From 957a711d248a86493fd6612980d042aff1b99b74 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Thu, 19 Dec 2019 00:00:31 +0800 Subject: [PATCH 001/705] v3.4.1, mask errors --- CHANGELOG.md | 15 +++++++++++++- bot.py | 32 +++++++++++++++++++++-------- cogs/modmail.py | 5 +++-- core/thread.py | 54 ++++++++++++++++++++++++++++--------------------- pyproject.toml | 2 +- 5 files changed, 73 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54e9d761f2..5d0929f316 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,21 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes does not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). -# v3.4.0 +# v3.4.1 + +### Fixed +- Masked a bunch of noise errors when deleting messages. +- Added more checks for deleting messages. + +### Breaking + +- `thread_initiate` is now dispatched at the beginning of the setup process. +- `thread_create` is dispatched when the thread is registered as a thread by Modmail (ie. when channel topic is edited). +- `thread_ready` is dispatched when a thread finishes its setup steps. + + +# v3.4.0 ### Added diff --git a/bot.py b/bot.py index b5ccdaccd5..694f860cf1 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.4.0" +__version__ = "3.4.1" import asyncio @@ -1069,19 +1069,32 @@ async def on_member_join(self, member): async def on_message_delete(self, message): """Support for deleting linked messages""" # TODO: use audit log to check if modmail deleted the message - if message.embeds and not isinstance(message.channel, discord.DMChannel): - thread = await self.threads.find(channel=message.channel) + if isinstance(message.channel, discord.DMChannel): + thread = await self.threads.find(recipient=message.author) + if not thread: + return try: - await thread.delete_message(message) + message = await thread.find_linked_message_from_dm(message) except ValueError as e: - if str(e) not in {"DM message not found.", " Malformed thread message."}: + if str(e) != "Thread channel message not found.": logger.warning("Failed to find linked message to delete: %s", e) - else: - thread = await self.threads.find(recipient=message.author) - message = await thread.find_linked_message_from_dm(message) + return embed = message.embeds[0] embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=embed.footer.icon_url) await message.edit(embed=embed) + return + + thread = await self.threads.find(channel=message.channel) + if not thread: + return + try: + await thread.delete_message(message, note=False) + except ValueError as e: + if str(e) not in {"DM message not found.", "Malformed thread message."}: + logger.warning("Failed to find linked message to delete: %s", e) + return + except discord.NotFound: + return async def on_bulk_message_delete(self, messages): await discord.utils.async_all(self.on_message_delete(msg) for msg in messages) @@ -1094,6 +1107,9 @@ async def on_message_edit(self, before, after): if isinstance(after.channel, discord.DMChannel): thread = await self.threads.find(recipient=before.author) + if not thread: + return + try: await thread.edit_dm_message(after, after.content) except ValueError: diff --git a/cogs/modmail.py b/cogs/modmail.py index 6531e61e70..7d36cecb62 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1150,8 +1150,9 @@ async def delete(self, ctx, message_id: int = None): thread = ctx.thread try: - await thread.delete_message(message_id) - except ValueError: + await thread.delete_message(message_id, note=True) + except ValueError as e: + logger.warning("Failed to delete message: %s.", e) return await ctx.send( embed=discord.Embed( title="Failed", diff --git a/core/thread.py b/core/thread.py index 0926a0acd0..960dafe0f7 100644 --- a/core/thread.py +++ b/core/thread.py @@ -72,15 +72,13 @@ def ready(self) -> bool: def ready(self, flag: bool): if flag: self._ready_event.set() - self.bot.dispatch("thread_ready", self) + self.bot.dispatch("thread_create", self) else: self._ready_event.clear() async def setup(self, *, creator=None, category=None): """Create the thread channel and other io related initialisation tasks""" - - self.bot.dispatch("thread_create", self) - + self.bot.dispatch("thread_initiate", self) recipient = self.recipient # in case it creates a channel outside of category @@ -175,6 +173,7 @@ async def send_recipient_genesis_message(): await self.bot.add_reaction(msg, close_emoji) await asyncio.gather(send_genesis_message(), send_recipient_genesis_message()) + self.bot.dispatch("thread_ready", self) def _format_info_embed(self, user, log_url, log_count, color): """Get information about a member of a server @@ -457,9 +456,14 @@ async def find_linked_messages( message_id: typing.Optional[int] = None, either_direction: bool = False, message1: discord.Message = None, + note: bool = True, ) -> typing.Tuple[discord.Message, typing.Optional[discord.Message]]: if message1 is not None: - if not message1.embeds or not message1.embeds[0].author.url: + if ( + not message1.embeds + or not message1.embeds[0].author.url + or message1.author != self.bot.user + ): raise ValueError("Malformed thread message.") elif message_id is not None: @@ -469,13 +473,18 @@ async def find_linked_messages( raise ValueError("Thread message not found.") if not ( - message1.embeds and message1.embeds[0].author.url and message1.embeds[0].color + message1.embeds + and message1.embeds[0].author.url + and message1.embeds[0].color + and message1.author == self.bot.user ): raise ValueError("Thread message not found.") if message1.embeds[0].color.value == self.bot.main_color and message1.embeds[ 0 ].author.name.startswith("Note"): + if not note: + raise ValueError("Thread message not found.") return message1, None if message1.embeds[0].color.value != self.bot.mod_color and not ( @@ -495,6 +504,8 @@ async def find_linked_messages( and message1.embeds[0].color.value == self.bot.recipient_color ) ) + and message1.embeds[0].author.url.split("#")[-1].isdigit() + and message1.author == self.bot.user ): break else: @@ -516,7 +527,7 @@ async def find_linked_messages( if int(msg.embeds[0].author.url.split("#")[-1]) == joint_id: return message1, msg except ValueError: - raise ValueError("DM message not found.") + continue raise ValueError("DM message not found.") async def edit_message(self, message_id: typing.Optional[int], message: str) -> None: @@ -537,16 +548,13 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> await asyncio.gather(*tasks) - async def delete_message(self, message: typing.Union[int, discord.Message] = None) -> None: - try: - if isinstance(message, discord.Message): - message1, message2 = await self.find_linked_messages(message1=message) - else: - message1, message2 = await self.find_linked_messages(message) - except ValueError as e: - logger.warning("Failed to delete message: %s.", e) - raise - + async def delete_message( + self, message: typing.Union[int, discord.Message] = None, note: bool = True + ) -> None: + if isinstance(message, discord.Message): + message1, message2 = await self.find_linked_messages(message1=message, note=note) + else: + message1, message2 = await self.find_linked_messages(message, note=note) tasks = [] if not isinstance(message, discord.Message): tasks += [message1.delete()] @@ -571,12 +579,12 @@ async def find_linked_message_from_dm(self, message, either_direction=False): return linked_message msg_id = url.split("#")[-1] - try: - if int(msg_id) == message.id: - return linked_message - except ValueError: - raise ValueError("Malformed dm channel message.") - raise ValueError("DM channel message not found.") + if not msg_id.isdigit(): + continue + msg_id = int(msg_id) + if int(msg_id) == message.id: + return linked_message + raise ValueError("Thread channel message not found.") async def edit_dm_message(self, message: discord.Message, content: str) -> None: try: diff --git a/pyproject.toml b/pyproject.toml index e9c402661d..f5af2276c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.4.0' +version = '3.4.1' description = 'Modmail is similar to Reddits Modmail both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way.' license = 'AGPL-3.0-only' authors = [ From be598f56193cd89c35311043a8ce2055d11d872e Mon Sep 17 00:00:00 2001 From: codeinteger6 <44692189+codeinteger6@users.noreply.github.com> Date: Mon, 6 Jan 2020 18:22:09 +0600 Subject: [PATCH 002/705] Bump to Python 3.7.6 --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index aefcfbece7..6919bf9ede 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.5 +python-3.7.6 From b0189fc0e0557c28b1df17be1f57c673b13deeb9 Mon Sep 17 00:00:00 2001 From: KarateWumpus <48181821+KarateWumpus@users.noreply.github.com> Date: Wed, 8 Jan 2020 19:04:11 +0100 Subject: [PATCH 003/705] New name, same me --- plugins/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 1c268d89be..3722b6d781 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -170,7 +170,7 @@ "thumbnail_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png" }, "stats": { - "repository": "MiTonder/modmail-plugins", + "repository": "KarateWumpus/modmail-plugins", "branch": "master", "description": "Get useful stats directly in an embed about either the Modmail bot, a user or the server.", "bot_version": "2.24.1", From 1f671ec54cdadab9f34c23ad97165f128e4d59bb Mon Sep 17 00:00:00 2001 From: DAzVise <52792999+DAzVise@users.noreply.github.com> Date: Thu, 9 Jan 2020 09:21:42 +0300 Subject: [PATCH 004/705] Edit plugin description --- plugins/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 3722b6d781..00518c1c65 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -190,7 +190,7 @@ "serverstats": { "repository": "dazvise/modmail-plugins", "branch": "master", - "description": "Interesting and accurate statistics about your server.", + "description": "Voice channels containing interesting and accurate statistics about your server such as Member Count.", "bot_version": "2.20.1", "title": "Server Stats", "icon_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png", From b2f4a40325a31a04940a8044bfbc44c8c790067f Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jan 2020 00:39:17 -0800 Subject: [PATCH 005/705] Update README.md --- README.md | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index d162f03bc3..ec28a420b7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
@@ -31,10 +31,6 @@ Made with Python 3.7 - - - - @@ -147,7 +143,7 @@ You can build your own Docker image: $ docker build . --tag=modmail ``` -or run directly from a pre-built version from https://hub.docker.com/. Currently there are two community release of Modmail: +or run directly from a pre-built version from https://hub.docker.com/. - Kyber's: @@ -155,21 +151,11 @@ or run directly from a pre-built version from https://hub.docker.com/. Currently $ docker pull kyb3rr/modmail ``` -- Taku's: - -```console -$ docker pull taaku18/modmail -# You can also choose one of the following: -$ docker pull taaku18/modmail:dev -$ docker pull taaku18/modmail: ( ex: 3.2.0, 3.2, etc.) -``` - And to run your docker image: ```console -$ docker run --env-file .env user/modmail +$ docker run --env-file .env kyb3rr/modmail ``` -- Replace `user/modmail` with `kyb3rr/modmail`, `taaku18/modmail`, `taaku18/modmail:3.2`, etc as above. - `.env` should be the path to your env file, you can also supply a path: `/path/to/.env`. ## Sponsors From e7771f02f4b825040367bd6603ddfd7a42e02459 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jan 2020 01:10:25 -0800 Subject: [PATCH 006/705] Update feature_request.md --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 48b986344d..7cd7a506cd 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: "[FEATURE-REQUEST] your title here" +title: "your title here" labels: feature-request assignees: '' From 00e92ae65a6dbc26ece1c42b245dd93ae2529830 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jan 2020 01:10:47 -0800 Subject: [PATCH 007/705] Update command-request.md --- .github/ISSUE_TEMPLATE/command-request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/command-request.md b/.github/ISSUE_TEMPLATE/command-request.md index 44902f2cf3..d3c1673a6b 100644 --- a/.github/ISSUE_TEMPLATE/command-request.md +++ b/.github/ISSUE_TEMPLATE/command-request.md @@ -1,7 +1,7 @@ --- name: Command request about: Request a new command -title: "[COMMAND-REQUEST] your title here" +title: "your title here" labels: command-request assignees: '' From cac233bee91f0675772138413c45ae1edc10e53d Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jan 2020 09:33:04 -0800 Subject: [PATCH 008/705] Spell check --- CHANGELOG.md | 252 ++++++++++++++++++++++++------------------------ CONTRIBUTING.md | 17 ++-- README.md | 28 +++--- pyproject.toml | 4 +- 4 files changed, 150 insertions(+), 151 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d0929f316..0dcb9acbcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); -however, insignificant breaking changes does not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). +however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. # v3.4.1 @@ -16,8 +16,8 @@ however, insignificant breaking changes does not guarantee a major version bump, ### Breaking -- `thread_initiate` is now dispatched at the beginning of the setup process. -- `thread_create` is dispatched when the thread is registered as a thread by Modmail (ie. when channel topic is edited). +- `thread_initiate` will be dispatched at the beginning of the setup process. +- `thread_create` is dispatched when the thread is registered as a thread by Modmail (i.e., when channel topic is edited). - `thread_ready` is dispatched when a thread finishes its setup steps. @@ -36,35 +36,35 @@ however, insignificant breaking changes does not guarantee a major version bump, - Multi-command alias is now more stable. With support for a single quote escape `\"`. - New command `?freply`, which behaves exactly like `?reply` with the addition that you can substitute `{channel}`, `{recipient}`, and `{author}` to be their respective values. - New command `?repair`, repair any broken Modmail thread (with help from @officialpiyush). -- Recipient get feedback when they edit message. +- Recipients get feedback when they edit their messages. - Chained delete for DMs now comes with a message. - poetry (in case someone needs it). ### Changed - The look of alias and snippet when previewing. -- Message ID of the thread embed is saved in DB, instead of the original message. +- The database now saves the message ID of the thread embed, instead of the original message. - Swapped the position of user and category for `?contact`. - The log file will no longer grow infinitely large. -- Hard limit of maximum 25 steps for alias. +- A hard limit of a maximum of 25 steps for aliases. - `?disable` is now `?disable new`. ### Fixed - Setting config vars using human time wasn't working. - Fixed some bugs with aliases. -- Fixed a lot of issues with `?edit` and `?delete` and recipient message edit. +- Fixed many issues with `?edit` and `?delete` and recipient message edit. - Masked the error: "AttributeError: 'int' object has no attribute 'name'" - Channel delete event will not be checked until discord.py fixes this issue. -- Chained reaction add / remove. +- Chained reaction add/remove. - Chained delete for thread channels. ### Internal -- Commit to black format line width max = 99, consistent with pylint. -- Alias parser is rewritten without shlex. +- Commit to black format line width max = 99, consistent with PyLint. +- No longer requires shlex for alias parsing. - New checks with thread create / find. -- No more flake8 and travis. +- No more flake8 and Travis. # v3.3.2 @@ -88,19 +88,19 @@ however, insignificant breaking changes does not guarantee a major version bump, - Three new config vars: - `enable_plugins` (yes/no default yes) - - When set to no, plugins will not be loaded into the bot. + - When set to no, Modmail will not load plugins. - `error_color` (color format, defaults discord red) - The color of error messages. - `anon_reply_without_command` (yes/no default no) (Thanks to papiersnipper PR#288) - When set, all non-command messages sent to thread channels are forwarded to the recipient anonymously without the need of `?anonreply`. - This config takes precedence over `reply_without_command`. -- `?logs responded [user]` command, it will show all logs that the user has sent an reply. (Thanks to papiersnipper PR#288) +- `?logs responded [user]` command. It will show all the logs that the user has sent a reply. (Thanks to papiersnipper PR#288) - `user` when not provided, defaults to the user who ran the command. -- Open threads in limbo now auto closes if the channel cannot be found. This check is done every time the bot restarts. +- Open threads in limbo now auto-close if Modmail cannot find the channel. Modmail does this check every time the bot restarts. - Ability to disable new threads from getting created. - - `?disable` + - `?disable`. - Ability to fully disable Modmail DM. - - `?disable all` + - `?disable all`. - To re-enable DM: `?enable`, and to see the current status: `?isenable`. - This disabled Modmail interface is customizable with the following config vars: - `disabled_new_thread_title` @@ -114,33 +114,33 @@ however, insignificant breaking changes does not guarantee a major version bump, ### Changed -- `?contact` no longer send the "thread created" message to where the command is ran, instead, it's now sent to the newly created thread channel. (Thanks to DAzVise) +- `?contact` no longer send the "thread created" message to where the command was run, instead, it's now sent to the newly created thread channel. (Thanks to DAzVise) - Automatically delete notes command `?note` when there're no attachments attached. - Embed author links used to be inaccessible in many cases, now: - `?anonreply`, `?reply`, and `?note` in the thread channel will link to the sender's profile. - - `?reply` and recipient's DM will also link the sender's profile. + - `?reply` and the recipient's DM will also link the sender's profile. - `?anonreply` in DM channel will link to the first channel of the main guild. - Plugins update (mostly internal). - - `git` is no longer used to install plugins, it now downloads through zip files. + - `git` is no longer used to install plugins; it now downloads through zip files. - `?plugins enabled` renamed to `?plugins loaded` while `enabled` is still an alias to that command. - Reorganized plugins folder structure. - Logging / plugin-related messages change. - - Updating one plugin will not update all other plugins (plugins are no longer separated by repos, but the plugin name itself). -- Help command is in alphabetical order grouped by permissions. -- Notes are no longer always blurple, it's set to `MAIN_COLOR` now. + - Updating one plugin will not update other plugins; repositories no longer separate plugins, but the plugin name itself. +- The help command is in alphabetical order grouped by permissions. +- Notes are no longer always blurple; it's set to `MAIN_COLOR` now. - Added `?plugins update` for updating all installed plugins. - Reintroduce flake8 and use bandit for security issues detection. -- Add travis checks for 3.6 in Linux and 3.7 for MacOS and Windows. -- Eval commands are logged in debug logs. +- Add Travis checks for 3.6 in Linux and 3.7 for macOS and Windows. +- Debug logs not logs eval commands. - Presence updates 30 minutes instead of 45 now. -- Fixed an assortment of problems to do with block. +- Fixed an assortment of problems to do with `?block`. - Existing aliases can be used when creating new aliases. (Thanks to papiersnipper PR#402) ### Internal - Reworked `config.get` and `config.set`, it feeds through the converters before setting/getting. - To get/set the raw value, access through `config[]`. -- Prerelease naming scheme is now `x.x.x-devN`. +- The prerelease naming scheme is now `x.x.x-devN`. - `trigger_typing` has been moved to `core.utils.trigger_typing`, the original location is deprecated. - Simpler status and activity logic. - New logging logic. @@ -153,9 +153,9 @@ Security update! - Supporter permission users used to be able to "hack" snippets to reveal all your config vars, including your token and MongoURI. - Implemented some changes to address this bug: - - All customizable variables used in snippets, close messages, etc, using the `{}` syntax, now forbids chaining 2 or more attributes and attributes that starts with `_`. -- It is advised to update to this version. -- If you felt your credentials have been leaked, consider changing your bot token / mongo uri. + - All customizable variables used in snippets, close messages, etc., using the `{}` syntax, now forbids chaining two or more attributes and attributes that start with `_`. +- We advise you to update to this version. +- If you felt your credentials had been leaked, consider changing your bot token / MongoURI. # v3.2.1 @@ -185,7 +185,7 @@ Security update! ### Internal -- Use regex to parse Changes, Added, Fixed, etc and description. +- Use regex to parse Changes, Added, Fixed, etc. and description. - Adds `PermissionLevel.INVALID` when commands don't have a permission level. # v3.1.1 @@ -205,33 +205,33 @@ Security update! ### Added - `?sfw`, mark a thread as "safe for work", undos `?nsfw`. -- New config variable, `thread_auto_close_silently`, when set to a truthy value, no message will be sent when thread is auto-closed. +- New config variable, `thread_auto_close_silently`, when set to a truthy value, no message will be sent when a thread is auto-closed. - New configuration variable `thread_self_closable_creation_footer` — the footer when `recipient_thread_close` is enabled. - Added a minimalistic version of requirements.txt (named requirements.min.txt) that contains only the absolute minimum of Modmail. - For users having trouble with pipenv or any other reason. -- Multi-step alias, see `?help alias add`. Public beta testing, might be unstable. +- Multi-step alias, see `?help alias add`. Public beta testing might be unstable. - Misc commands without cogs are now displayed in `?help`. - `?help` works for alias and snippets. - `?config help ` shows a help embed for the configuration. -- Support setting permissions for sub commands. -- Support numbers (1-5) as substitutes for Permission Level REGULAR - OWNER in `?perms` sub commands. +- Support setting permissions for subcommands. +- Support numbers (1-5) as substitutes for Permission Level REGULAR - OWNER in `?perms` subcommands. ### Changes - `thread_auto_close_response` has a configurable variable `{timeout}`. - `?snippet` is now the default command name instead of `?snippets` (`?snippets` is still usable). This is to make this consistent with `?alias`/`?aliases`. -- `colorama` is no longer a necessity, this is due to some unsupported OS. -- Changelog command can now take a version argument to jump straight to specified version. +- `colorama` is no longer a necessity; this is due to some unsupported OS. +- Changelog command can now take a version argument to jump straight to the specified version. - `?plugin enabled` results are now sorted alphabetically. -- `?plugin registry` results are now sorted alphabetically, helps user find plugins more easily. +- `?plugin registry` results are now sorted alphabetically, helps users find plugins more easily. - `?plugin registry page-number` plugin registry can specify a page number for quick access. - A reworked interface for `?snippet` and `?alias`. - Add an `?snippet raw ` command for viewing the raw content of a snippet (escaped markdown). - - Add an `?alias raw ` command for viewing the raw content of a alias (escaped markdown). + - Add an `?alias raw ` command for displaying the raw content of an alias (escaped markdown). - The placeholder channel for the streaming status changed to https://www.twitch.tv/discordmodmail/. - Removed unclear `rm` alias for some `remove` commands. - Paginate `?config options`. -- All users configured with a permission level greater than REGULAR has access to the main Modmail category. +- All users configured with a permission level higher than REGULAR has access to the main Modmail category. - Category overrides also changes when a level is removed or added to a user or role. - `@everyone` is now accepted for `?perms add`. @@ -239,12 +239,12 @@ Security update! - `?notify` no longer carries over to the next thread. - `discord.NotFound` errors for `on_raw_reaction_add`. -- `mod_typing` ~~and `user_typing`~~ (`user_typing` is now by-design to show) will no longer show when user is blocked. +- `mod_typing` ~~and `user_typing`~~ (`user_typing` is now by-design to show) will no longer show when the user is blocked. - Better `?block` usage message. -- Resolves errors when message was sent by mods after thread is closed somehow. +- Resolved errors when mods sent messages after a thread is closed somehow. - Recipient join/leave server messages are limited to only the guild set by `GUILD_ID`. -- When creating snippets and aliases, it now checks if another snippets/aliases with the same name exists. -- Was looking for `config.json` in the wrong directory. +- When creating snippets and aliases, it now checks if other snippets/aliases with the same name exist. +- Modmail looked for `config.json` in the wrong directory. ### Internal @@ -264,13 +264,13 @@ Security update! ### Added - New commands, `?alias edit ` and `?snippets edit `. - - They can be used to edit aliases and snippets respectively. + - They can be used to edit aliases and snippets, respectively. # v3.0.2 ### Added -- New command, `?blocked whitelist `, this command prevents users from getting blocked by any means. +- A new command, `?blocked whitelist `, this command prevents users from getting blocked by any means. ### Changed @@ -280,30 +280,30 @@ Security update! ### Fixed -- A lot of bugs with `thread_auto_close` 😅 +- Many bugs with `thread_auto_close`. # v3.0.0 ### Added -- Sponsors command that will list sponsors. -- An alert will now be sent to the log channel if a thread channel fails to create. This could be due to a variety of problems such as insufficient permissions or the category channel limit is met. +- `?sponsors` command will list sponsors. +- An alert will now be sent to the log channel if a thread channel fails to create. This could be due to a variety of problems such as insufficient permissions, or the category channel limit is met. - Threads will close automatically after some time when `thread_auto_close` is set. -- Custom closing message can be set with `thread_auto_close_response`. +- Custom closing messages can be configured with `thread_auto_close_response`. ### Breaking Changes -- Removed autoupdate functionality and the `?update` command in favour of the [Pull app](https://github.com/apps/pull). +- Removed auto-update functionality and the `?update` command in favor of the [Pull app](https://github.com/apps/pull). Read more about updating your bot [here](https://github.com/kyb3r/modmail/wiki/updating) ### Changed -- Channel names now can contain unicode characters. -- Debug logs are now located in a unique file for each bot. (Internal change) +- Channel names now can contain Unicode characters. +- Debug logs are now located in a different file for each bot. (Internal change) - Default cogs always appear first in the help command now. ### Fixed -- Editing notes now works, minor bug with edit command is fixed. +- Editing notes now work, minor bug with edit command is fixed. - Bug in the `?oauth` command where the response message fails to send when an ID is provided. - Plugin requirement installation now works in virtual environments @@ -318,7 +318,7 @@ Fixed a bug with branches and `?plugin update`. ### Added -Branch support for `?plugin add` and in registry. Typically for developers. +Branch support for `?plugin add` and in the registry. Typically for developers. # v2.23.0 @@ -326,11 +326,11 @@ Branch support for `?plugin add` and in registry. Typically for developers. Added a "Mutual servers" field to the genesis embed if: a) The user is not in the main guild. -b) The user shares more than 1 server with the bot. +b) The user shares more than one server with the bot. ### Changed -Notes taken with the `?note` command are now automatically pinned within the thread channel. +Notes with the `?note` command are now automatically pinned within the thread channel. # v2.22.0 @@ -372,14 +372,14 @@ Add your plugin in the `plugins/registry.json` file in the main repository. This update contains mostly internal changes. - Implemented support for the new discord.py v1.1.1. - Improved help text for most commands. - - Completely revamped help command, few user changes. - - Removed abc (internal). + - Completely revamped help command, few users changes. + - Removed ABC (internal). # v2.20.0 ### What's new? -New `oauth` whitelist command which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app check the logviewer [repo](https://github.com/kyb3r/logviewer). +New `?oauth whitelist` command, which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app, check the logviewer [repo](https://github.com/kyb3r/logviewer). # v2.19.1 @@ -387,7 +387,7 @@ New `oauth` whitelist command which allows you to whitelist users so they can lo - Ability to force an update despite having the same version number. Helpful to keep up-to-date with the latest GitHub commit. - `?update force`. -- Plugin developers now have a new event called `on_plugin_ready`, this is coroutine is awaited when all plugins are loaded. Use `on_plugin_ready` instead of `on_ready` since `on_ready` will not get called in plugins. +- Plugin developers now have a new event called `on_plugin_ready`; this is a coroutine and is awaited when all plugins are loaded. Use `on_plugin_ready` instead of `on_ready` since `on_ready` will not get called in plugins. # v2.19.0 @@ -408,17 +408,17 @@ Fix the teams permission bug. ### Changed -Commands now have better error messages, instead of just sending the help message for a command when an argument fails to be converted to its specified object, the bot now says things like "User 'bob' not found" instead. +Commands now have better error messages. Instead of sending the help message for a command when an argument fails to be converted, the bot now says like "User 'bob' not found" instead. # v2.18.1 -Un-deprecated the `OWNERS` config variable to support discord developer team accounts. +Un-deprecated the `OWNERS` config variable to support Discord developer team accounts. # v2.18.0 ### New Permissions System -- A brand new permission system! Replacing the old guild-based permissions (ie. manage channels, manage messages), the new system enables you to customize your desired permission level specific to a command or a group of commands for a role or user. +- A brand new permission system! Replaced the old guild-based permissions (i.e., manage channels, manage messages), with the new system enables you to customize your desired permission level specific to a command or a group of commands for a role or user. - There are five permission levels: - Owner [5] - Administrator [4] @@ -437,7 +437,7 @@ You may add a role or user to a permission group through any of the following me The same applies to individual commands permissions: - `?permissions add command command-name @member#1234` -- ... and the other methods listed above. +- and the other methods listed above. To revoke permission, use `remove` instead of `add`. @@ -450,11 +450,11 @@ By default, all newly set up Modmail will have `OWNER` set to the owner of the b ### Breaking When updating to this version, all prior permission settings with guild-based permissions will be invalidated. You will need to convert to the above system. -`OWNERS` will also get removed, you will need to set owners through `?permissions add level owner 212931293123129` or any way listed above. +`OWNERS` will also get removed; you will need to set owners through `?permissions add level owner 212931293123129` or any way listed above. ### New Command -- A `?delete` command, which is an alternative to manually deleting a message. This command is created to no longer requires manage messages permission to recall thread messages. +- A `?delete` command, which is an alternative to manually deleting a message. This command is created to no longer require "manage messages" permission to recall thread messages. ### Changed @@ -475,28 +475,28 @@ Stricter fallback genesis embed search. ### Changed -How modmail checks if a channel is a thread: +How Modmail checks if a channel is a thread: -1. The bot first checks if the channel topic is in the format `User ID: xxxx`, this means it is a thread. -2. If a channel topic is not found, the bot searches through the message history of a channel to find the thread creation embed. This step should never yield a thread for a normal user, but in the case of another bot messing up the channel topic (happened to a user before) this extra step was added. +1. The bot first checks if the channel topic is in the format `User ID: XXXX`, this means it is a thread. +2. If a channel topic is not found, the bot searches through the message history of a channel to find the thread creation embed. This step should never yield a thread for an average user. Still, in the case of another bot messing up the channel topic (happened to a user before), this extra step was added. # v2.17.0 ### What's new? -Added a config option `reply_without_command` which when present, enables the bot to forward any message sent in a thread channel to the recipient. (Replying without using a command) +Added a config option `reply_without_command`, which, when present, enables the bot to forward any message sent in a thread channel to the recipient. (Replying without using a command) To enable this functionality, do `?config set reply_without_command true` and to disable it, use `?config del reply_without_command`. ### Changed -The `move` command now only requires `manage_messages` perms instead of `manage_channels` +The `move` command now only requires `manage_messages` perms instead of `manage_channels`. # v2.16.1 ### Fixed -An issue where a scheduled close would not execute over a long period of time if the recipient no shares any servers with the bot. +An issue where a scheduled close would not execute over a long time if the recipient no shares any servers with the bot. # v2.16.0 @@ -526,8 +526,8 @@ Added the ability to change the default close message via the introduction of tw They will be provided by string variables that you can incorporate into them: - `closer` - the user object that closed the thread. -- `logkey` - the key for the thread logs e.g. (`5219ccc82ad4`) -- `loglink` - the full link to the thread logs e.g. (`https://logwebsite.com/logs/5219ccc82ad4`) +- `logkey` - the key for the thread logs, e.g. (`5219ccc82ad4`) +- `loglink` - the full link to the thread logs, e.g. (`https://logwebsite.com/logs/5219ccc82ad4`) Example usage would be: ``?config set thread_close_message {closer.mention} closed the thread, here is the link to your logs: [**`{logkey}`**]({loglink})`` @@ -556,9 +556,9 @@ You now have complete control of the look of the thread creation and close embed ### What's new? -Added the ability to disable the `sent_emoji` and `blocked_emoji` when a user messages modmail. +Added the ability to disable the `sent_emoji` and `blocked_emoji` when a user messages Modmail. -You can do this via `?config set sent_emoji disable` +You can do this via `?config set sent_emoji disable`. ### Fixed @@ -575,17 +575,17 @@ Added image link in title in case discord fails to embed an image. - Introduced a new configuration variable `account_age` for setting a minimum account creation age. - Users blocked by this reason will be stored in `blocked` along with other reasons for being blocked. - `account_age` needs to be an ISO-8601 Duration Format (examples: `P12DT3H` 12 days and 3 hours, `P3Y5M` 3 years and 5 months `PT4H14M999S` 4 hours 14 minutes and 999 seconds). https://en.wikipedia.org/wiki/ISO_8601#Durations. - - You can set `account_age` using `config set account_age time` where "time" can be a simple human readable time string or an ISO-8601 Duration Format string. + - You can set `account_age` using `config set account_age time` where "time" can be a simple human-readable time string or an ISO-8601 Duration Format string. ### Changed -- `block` reason cannot start with `System Message: ` as it is now reserved for internal user blocking. -- `block`, like `close`, now supports a block duration (temp blocking). +- `?block` reason cannot start with `System Message: ` as it is now reserved for internal user blocking. +- `?block`, like `?close`, now supports a block duration (temp blocking). # v2.13.10 ### Fixed - Fixed an issue where status and activity do not work if they were modified wrongly in the database. - - This was especially an issue for older Modmail users, as the old `status` configuration variable clashes with the new `status` variable. + - This was primarily an issue for older Modmail users, as the old `status` configuration variable clashes with the new `status` variable. # v2.13.9 @@ -604,7 +604,7 @@ Added image link in title in case discord fails to embed an image. ### What's new? - The ability to enable typing interactions. - - If you want the bot to type in the thread channel if the user is also typing, add the config variable `user_typing` and set it to "yes" or "true". use `config del` to disable the functionality. The same thing in reverse is also possible if you want the user to see the bot type when someone is typing in the thread channel add the `mod_typing` config variable. + - If you want the bot to type in the thread channel if the user is also typing, add the config variable `user_typing` and set it to "yes" or "true". Use `config del` to disable the functionality. The same thing in reverse is also possible if you want the user to see the bot type when someone is typing in the thread channel add the `mod_typing` config variable. - New `status` command, change the bot's status to `online`, `idle`, `dnd`, `invisible`, or `offline`. - To remove the status (change it back to default), use `status clear`. - This also introduces a new internal configuration variable: `status`. Possible values are `online`, `idle`, `dnd`, `invisible`, and `offline`. @@ -621,15 +621,15 @@ Added image link in title in case discord fails to embed an image. ### What's new? - You will no longer need to view your bot debug logs from Heroku. `debug` will show you the recent logs within 24h through a series of embeds. - - If you don't mind your data (may or may not be limited to: user ID, guild ID, bot name) be on the internet, `debug hastebin` will upload a formatted logs file to https://hasteb.in. + - If you don't mind your data (may or may not be limited to user ID, guild ID, bot name) be on the internet, `debug hastebin` will upload a formatted logs file to https://hasteb.in. - `debug clear` will clear the locally cached logs. - - Local logs are automatically cleared at least once every 27h for bots hosted on Heroku. + - Local logs are automatically erased at least once every 27h for bots hosted on Heroku. ### Fixed -- Will no longer show `Unclosed client session` and `Task was destroyed but it is pending!` when the bot terminates. +- Will no longer show `Unclosed client session` and `Task was destroyed, but it is pending!` when the bot terminates. - `thread.create` is now synchronous so that the first message sent can be queued to be sent as soon as a thread is created. - This fixes a problem where if multiple messages are sent in quick succession, the first message sent (which triggers the thread creation) is not sent in order. -- Trying to reply to someone who has DMs disabled or has blocked the bot is now handled and the bot will send a message saying so. +- Trying to reply to someone who has DMs disabled or has blocked the bot is now handled, and the bot will send a message saying so. ### Changed - `print` is replaced by logging. @@ -663,14 +663,14 @@ Added image link in title in case discord fails to embed an image. ### What's new? - Plugins: - - Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it. Add a welcome message to Modmail, or moderation commands? It's all up to your imagination! Have a niche feature request that you think only your server would benefit from? Plugins are your go-to! + - Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it. Add a welcome message to Modmail, or moderation commands? It's all up to your imagination! Have a niche feature request that you think only your server would benefit? Plugins are your go-to! - [Creating Plugins Documentation](https://github.com/kyb3r/modmail/wiki/Plugins). # v2.12.5 ### Fixed -- `config del` command will now work properly on self-hosted db bots. +- `config del` command will now work correctly on self-hosted DB bots. # v2.12.4 @@ -684,14 +684,14 @@ Added image link in title in case discord fails to embed an image. ### Fixed - Patched a bug where `logs` sub-commands were accessible by anyone. -- Patched a bug where an error was raised if there was an open thread where the recipient had left the server. +- Patched a bug where an error was raised when a thread is open where the recipient left the server. Huge thanks to Sasiko for reporting these issues. # v2.12.2 ### Fixed -- Fixed a bug in self-hosted `update` command. +- Fixed a bug in self-hosted `?update` command. # v2.12.1 @@ -702,12 +702,12 @@ Huge thanks to Sasiko for reporting these issues. # v2.12.0 ### Important -**In the future, the Modmail API (https://modmail.tk) will be deprecated. This is due to the fact that we are providing a free service without getting anything in return, and thus we do not have the resources to scale to accommodate for more users. +**In the future, the Modmail API (https://modmail.tk) will be deprecated. This is because we are providing free service without getting anything in return. Thus we do not have the resources to scale to accommodate more users. We recommend using your own database for logs. In the future you will soon get a `backup` command so you can download all your pre-existing data and migrate to your own database.** ### Changed - A lot of painful code cleanup, which is good for us (the developers), but shouldn't affect you. -- The appearance of the `logs` command. Should be clearer with better info now. +- The appearance of the `?logs` command. It should be clearer with better info now. - Bot owners get access to all commands regardless of server permissions. - Blocked users no longer receive a message, only the blocked emoji will be sent. @@ -715,10 +715,10 @@ We recommend using your own database for logs. In the future you will soon get a - **Note:** The following commands only work if you are self-hosting your logs. We recommend you to use your own database. - Log search queries, in the form of two new commands. - `logs search [query]` - this searches all log messages for a query string. -- `logs closed-by [user]` this returns all logs closed by a certain user +- `logs closed-by [user]` this returns all logs closed by a particular user ### Fixed -- `activity listening to music` no longer result in two "to"s ("listening to to music"). +- `activity listening to music` no longer results in two "to"s ("listening to to music"). - This may require you to change your activity message to accommodate this fix. - A problem where `main_category_id` and `log_channel_id` weren't updated when their corresponding channel or category get deleted. @@ -741,7 +741,7 @@ We recommend using your own database for logs. In the future you will soon get a ### What's new? - `anonreply` command to anonymously reply to the recipient. -The username of the anonymous user defaults to the `mod_tag` (the footer text of a mod reply message). The avatar defaults the guild icon URL. However you can change both of these via the `anon_username`, `anon_avatar_url` and `anon_tag` config variables. +The username of the anonymous user defaults to the `mod_tag` (the footer text of a mod reply message) — the avatar defaults to the guild icon URL. However, you can change both of these via the `anon_username`, `anon_avatar_url`, and `anon_tag` config variables. ### Changed - Your bot now logs all messages sent in a thread channel, including discussions that take place. You can now toggle to view them in the log viewer app. @@ -766,7 +766,7 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of - All commands are now blurple instead of green. ### Fixed -- Bug where the close command wouldn't work if you didnt configure a log channel. +- Bug where the close command wouldn't work if you didn't configure a log channel. ### What's new? - Ability to set your own custom `mod_color` and `recipient_color` for the thread message embeds. @@ -783,13 +783,13 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of # v2.9.0 ### What's new? -- New command `note` will add a system message to your thread logs. This is useful for noting the context of a conversation. +- New command `note` will add a system message to your thread logs. - - This is useful for noting the context of a conversation. # v2.8.1 ### Fixed - Fixed bug where thread logs were getting duplicated when using the `contact` command. -- Fixed bug where the wrong key was used for logs which caused some `log` command log links to point to an HTTP 404 Not Found. +- Fixed bug where the wrong key was used for logs, which caused some `log` command log links to point to an HTTP 404 Not Found. - A minor oversight from commit 1ba74d9. # v2.8.0 @@ -806,7 +806,7 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of ### Security Thread channels will now default to being private (`@everyone`'s read message perms set to `false`). - If the thread creation category could not be resolved. - - This will save you from some trouble if for whatever reason your configuration gets messed up. + - This will save you from some trouble if, for whatever reason, your configuration gets messed up. # v2.7.1 @@ -818,20 +818,20 @@ Thread channels will now default to being private (`@everyone`'s read message pe ### Note -- If your Modmail bot was set up a long time ago, you may experience an issue where messages were sent outside of the category. +- If your Modmail bot was set up a long time ago, you might experience an issue where messages were sent outside of the category. - To fix this, set `main_category_id` to the ID of the Modmail category. # v2.7.0 ### Changed -- `move` command now syncs thread channel permissions with the category that it was moved to. +- `move` command now syncs thread channel permissions with the destination category. - `contact` command now supports an optional category argument (where the thread channel will be created). # v2.6.3 ### Fixes -- Fixed small issue with finding thread. +- Fixed small issue with finding threads. # v2.6.2 @@ -851,8 +851,8 @@ Thread channels will now default to being private (`@everyone`'s read message pe ### Changed - Log URLs are moved to their own collection. - Log URLs are now `https://logs.modmail.tk/LOGKEY`, no more numbers before the log key. -- We still support the numbers so as to not break everyone's URLs so quickly but both work at the moment. -- This is a huge change to the backend logging and there might be migration errors. If so, please contact us in our [discord server](https://discord.gg/2fMbf2N). +- We still support the numbers to not break everyone's URLs so quickly, but both work at the moment. +- This is a huge change to the backend logging, and there might be migration errors. If so, please contact us in our [Discord server](https://discord.gg/2fMbf2N). # v2.5.2 @@ -862,13 +862,13 @@ Thread channels will now default to being private (`@everyone`'s read message pe # v2.5.1 ### Fixes -- Emergency patch to save config. +- Emergency patch to save configs. # v2.5.0 ### Background - Bots hosted by Heroku restart at least once every 27 hours. -- During this period, local caches are deleted, which results in the inability to set the scheduled close time to longer than 24 hours. This update resolves this issue. +- During this period, local caches will be deleted, which results in the inability to set the scheduled close time to longer than 24 hours. This update resolves this issue. - [PR #135](https://github.com/kyb3r/modmail/pull/135) ### Changed @@ -886,7 +886,7 @@ Fixed activity setting due to flawed logic in `config.get()` function. # v2.4.4 ### Fixed -Fixed a bug in activity command where it would fail to set the activity on bot restart if the activity type was `playing`. +Fixed a bug in the `?activity` command where it would fail to set the activity on bot restart if the activity type was `playing`. # v2.4.3 @@ -901,17 +901,17 @@ Fixed a bug in activity command where it would fail to set the activity on bot r # v2.4.1 ### Fixed -- Small bug in `activity` command. +- Small bug in `?activity` command. # v2.4.0 ### What's new? -- Added the `activity` command for setting the activity -- [PR #131](https://github.com/kyb3r/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening` and `streaming`). +- Added the `?activity` command for setting the activity +- [PR #131](https://github.com/kyb3r/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening`, and `streaming`). ### Removed - Removed the deprecated `status` command. -- This also means you will have to reset your bot status with the `activity` command, as `status` command is removed. +- This also means you will have to reset your bot status with the `?activity` command, as the `?status` command was removed. # v2.3.0 @@ -932,7 +932,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### What's new? - Notify command `notify [role]`. - Notify a given role or yourself to the next thread message received. - - Once a thread message is received you will be pinged once only. + - Once a thread message is received, you will be pinged once only. - Subscribe command `sub [role]` / `unsub [role]`. - Subscribes yourself or a given role to be notified when thread messages are received. @@ -949,15 +949,15 @@ Fixed a bug in activity command where it would fail to set the activity on bot r # v2.1.0 ### What's new? -- Ability to set a custom thread creation response message. +- Ability to set a custom thread-creation-response message. - Via `config set thread_creation_response [message]`. ### Changed -- Improve logs command format. -- Improve thread log channel message to have more relevant info. +- Improve `?logs` command format. +- Improve thread log channel messages to have more relevant info. - Improve close command. - - You now can close the thread after a delay and use a custom thread close message. - - You also now have the ability to close a thread silently. + - You can now close the thread after a delay and use a custom thread close message. + - You also now can close a thread silently. # v2.0.10 @@ -972,7 +972,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Fixes - Support multiple images and file attachments in one message. -- This is only possible on mobile so its good to handle it in code. +- This is only possible on mobile, so its good to handle it in code. # v2.0.8 @@ -983,7 +983,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r - You can do this via the `config set main_category_id ` command. ### Changed -- You now have the ability to supply a reason when blocking a user. +- You can now supply a reason when blocking a user. - Blocked users are now stored in the database instead of in the channel topic. - This means you can delete the top channel in the Modmail category now (after migrating the currently blocked users). @@ -994,8 +994,8 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Changed - `update` command now shows the latest changes directly from CHANGELOG.md. -- Auto update messages also show the latest changes from the GitHub repo. -- Removed "latest changes" section from the `about` command. +- Auto-update messages also show the latest changes from the GitHub repo. +- Removed the "latest changes" section from the `about` command. # v2.0.6 @@ -1008,20 +1008,20 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Changed - `alias` command now checks if you are adding a valid alias-command combo. -- Deleting a channel manually will now correctly close the thread and post logs. +- Manually deleting a channel will now correctly close the thread and post logs. # v2.0.4 ### Fixed -- Fixed a one-off bug where the channel topic disappears, but Modmail operations should still continue. +- Fixed a one-off bug where the channel topic disappears, but Modmail operations should continue. - Fixed `linked_message_id` issues. # v2.0.3 ### Fixed -- Thread creation embed now shows the correct number of past logs. +- The thread creation embed now shows the correct number of past logs. - If using a separate server setup, roles in the info embed now are shown as names instead of mentions. - - This is due to the fact that you can't mention roles across servers. + - This is because you can't mention roles across servers. # v2.0.2 @@ -1033,7 +1033,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Changed - Improved `block` / `unblock` commands. - - They now take a wider range of arguments: usernames, nicknames, mentions and user IDs. + - They now take a more comprehensive range of arguments: usernames, nicknames, mentions, and user IDs. ### Fixed - Setup command now configures permissions correctly so that the bot will always be able to see the main operations category. @@ -1041,7 +1041,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r # v2.0.0 This release introduces the use of our centralized [API service](https://github.com/kyb3r/webserver) to enable dynamic configuration, auto-updates, and thread logs. -To use this release you must acquire an API token from https://modmail.tk. +To use this release, you must acquire an API token from https://modmail.tk. Read the updated installation guide [here](https://github.com/kyb3r/modmail/wiki/installation). ### Changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a95e344610..568e5f2175 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,33 +15,32 @@ We use GitHub to host code, to track issues and feature requests, as well as acc ## We Use [Git Flow](https://atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) ![Simple Image Of A Git Flow Workflow](https://nvie.com/img/hotfix-branches@2x.png) -When contributing to this project please make sure you follow this and name your branches appropriately! +When contributing to this project, please make sure you follow this and name your branches appropriately! ## All Code Changes Happen Through Pull Requests Make sure you know how Git Flow works before contributing! Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests: 1. Fork the repo and create your branch from `master` or `development` according to Git Flow. -2. If you've added code that should be tested, add tests. -3. If you've changed APIs, update the documentation. -4. Ensure the test suite passes. -5. Make sure your code lints. -6. Issue that pull request! +2. Update the CHANGELOG. +3. If you've changed `core/*` or `bot.py`, mark changelog as "BREAKING" since plugins may break. +4. Make sure your code passes the lint checks. +5. Create Issues and pull requests! ## Any contributions you make will be under the GNU Affero General Public License v3.0 In short, when you submit code changes, your submissions are understood to be under the same [GNU Affero General Public License v3.0](https://www.gnu.org/licenses/agpl-3.0.en.html) that covers the project. Feel free to contact the maintainers if that's a concern. ## Report bugs using [Github Issues](https://github.com/kyb3r/modmail/issues) -We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! +We use GitHub issues to track public bugs. Report a bug by [opening a new Issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! ## Write bug reports with detail, background, and sample code **Great Bug Reports** tend to have: -- A quick summary and/or background +- A quick summary and background - Steps to reproduce - Be specific! - What you expected would happen -- What actually happens +- What *actually* happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) diff --git a/README.md b/README.md index ec28a420b7..961a664a21 100644 --- a/README.md +++ b/README.md @@ -46,25 +46,25 @@ ## What is Modmail? -Modmail is similar to Reddit's Modmail both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way. +Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way. This bot is free for everyone and always will be. If you like this project and would like to show your appreciation, you can support us on **[Patreon](https://www.patreon.com/kyber)**, cool benefits included! ## How does it work? -When a member sends a direct message to the bot, Modmail will create a channel or "thread" within an isolated category. All further DM messages will automatically relay to that channel, for any available staff can respond within the channel. +When a member sends a direct message to the bot, Modmail will create a channel or "thread" into a designated category. All further DM messages will automatically relay to that channel; any available staff can respond within the channel. -All threads are logged and you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.logviewer.tech/example). +Our Logviewer will save the threads so you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.logviewer.tech/example). ## Features * **Highly Customisable:** * Bot activity, prefix, category, log channel, etc. * Command permission system. - * Interface elements (color, responses, reactions, etc). + * Interface elements (color, responses, reactions, etc.). * Snippets and *command aliases*. * Minimum duration for accounts to be created before allowed to contact Modmail (`account_age`). - * Minimum duration for members to be in the guild before allowed to contact Modmail (`guild_age`). + * Minimum length for members to be in the guild before allowed to contact Modmail (`guild_age`). * **Advanced Logging Functionality:** * When you close a thread, Modmail will generate a [log link](https://logs.logviewer.tech/example) and post it to your log channel. @@ -86,11 +86,11 @@ This list is ever-growing thanks to active development and our exceptional contr Where can I find the Modmail bot invite link? -Unfortunately, due to how this bot functions, it cannot be invited. This is to ensure the individuality to your server and grant you full control over your bot and data. Nonetheless, you can easily obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time)... +Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time). ### Heroku -This bot can be hosted on Heroku. +You can host this bot on Heroku. Installation via Heroku is possible with your web browser alone. The [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) (which includes a video tutorial!) will guide you through the entire installation process. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. @@ -104,11 +104,11 @@ To configure automatic updates: ### Hosting for Patreons -If you don't want to go through the trouble of setting up your very own Modmail bot, and/or want to support this project, we offer the all inclusive installation, hosting and maintenance of your Modmail with [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! +If you don't want to go through the trouble of setting up your very own Modmail bot or wish to support this project, we got a solution for you! We offer the complete installation, hosting, and maintenance of your Modmail with [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! ### Locally -Local hosting of Modmail is also possible, first you will need [`Python 3.7`](https://www.python.org/downloads/). +Local hosting of Modmail is also possible. First, you will need [`Python 3.7`](https://www.python.org/downloads/). Follow the [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) and disregard deploying the Heroku bot application. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. @@ -143,7 +143,7 @@ You can build your own Docker image: $ docker build . --tag=modmail ``` -or run directly from a pre-built version from https://hub.docker.com/. +Or run directly from a pre-built version from https://hub.docker.com/. - Kyber's: @@ -156,7 +156,7 @@ And to run your docker image: ```console $ docker run --env-file .env kyb3rr/modmail ``` -- `.env` should be the path to your env file, you can also supply a path: `/path/to/.env`. +- `.env` should be the path to your env file; you can also supply a path: `/path/to/.env`. ## Sponsors @@ -175,9 +175,9 @@ Become a sponsor on [Patreon](https://patreon.com/kyber). ## Plugins Modmail supports the use of third-party plugins to extend or add functionalities to the bot. -This allows niche features as well as anything else outside of the scope of the core functionality of Modmail. +Plugins allow niche features as well as anything else outside of the scope of the core functionality of Modmail. -A list of third-party plugins can be found using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/kyb3r/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. +You can find a list of third-party plugins using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/kyb3r/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. To develop your own, check out the [plugins documentation](https://github.com/kyb3r/modmail/wiki/Plugins). @@ -185,6 +185,6 @@ Plugins requests and support is available in our [Modmail Plugins Server](https: ## Contributing -Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our contribution [guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. +Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. If you like this project and would like to show your appreciation, support us on **[Patreon](https://www.patreon.com/kyber)**! diff --git a/pyproject.toml b/pyproject.toml index f5af2276c9..3ea9cf9b8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 99 -target-version = ['py36'] +target-version = ['py37'] include = '\.pyi?$' exclude = ''' ( @@ -22,7 +22,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' version = '3.4.1' -description = 'Modmail is similar to Reddits Modmail both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way.' +description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ 'kyb3r ', From 5ff81d5b8a292dd2b06694c2493b58ba5cff27fb Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Thu, 6 Feb 2020 18:45:31 -0800 Subject: [PATCH 009/705] links to python 3.7 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 961a664a21..9873ba5f12 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ If you don't want to go through the trouble of setting up your very own Modmail ### Locally -Local hosting of Modmail is also possible. First, you will need [`Python 3.7`](https://www.python.org/downloads/). +Local hosting of Modmail is also possible. First, you will need [`Python 3.7`](https://www.python.org/downloads/release/python-376/). Follow the [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) and disregard deploying the Heroku bot application. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. From df91e75a075834c60013f56e5aeef4d0fbfbe5d6 Mon Sep 17 00:00:00 2001 From: "MiscDev.py" <60783846+mischievousdev@users.noreply.github.com> Date: Thu, 20 Feb 2020 18:10:39 +0530 Subject: [PATCH 010/705] Add my plugin --- plugins/registry.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 00518c1c65..0fe6428789 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -195,5 +195,13 @@ "title": "Server Stats", "icon_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png", "thumbnail_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png" + }, + "githubstats": { + "repository": "mischievousdev/modmail-plugins", + "branch": "master", + "description": "Github statistics in discord", + "bot_version": "2.20.1", + "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", + "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" } } From fae731e925ca76b534b10ce0472f014ddf816fde Mon Sep 17 00:00:00 2001 From: Piyush Bhangale Date: Fri, 21 Feb 2020 10:30:33 +0530 Subject: [PATCH 011/705] feat: add github_token in config --- core/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/config.py b/core/config.py index a0eda4a2dc..f9097e737e 100644 --- a/core/config.py +++ b/core/config.py @@ -110,6 +110,8 @@ class ConfigManager: "owners": None, # bot "token": None, + # github access token for private repositories + "github_token": None # Logging "log_level": "INFO", "enable_plugins": True, From 8b127b5e1fc43ad1a11036ae3ed5710de5fc2d34 Mon Sep 17 00:00:00 2001 From: Piyush Bhangale Date: Fri, 21 Feb 2020 10:36:02 +0530 Subject: [PATCH 012/705] feat: add authorization header if present --- cogs/plugins.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index e4543d2f1e..e8b7095c0c 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -154,7 +154,10 @@ async def download_plugin(self, plugin, force=False): logger.debug("Loading cached %s.", plugin.cache_path) else: - async with self.bot.session.get(plugin.url) as resp: + headers = {} + if self.bot.config.get("github_token") is not None: + headers["Authorization"] = f"token {self.bot.config.get('github_token')}" + async with self.bot.session.get(plugin.url, headers=headers) as resp: logger.debug("Downloading %s.", plugin.url) raw = await resp.read() plugin_io = io.BytesIO(raw) From 5aa1f007ddbcf7e0cb93fb9a0bc7e351cc903525 Mon Sep 17 00:00:00 2001 From: Piyush Bhangale Date: Fri, 21 Feb 2020 10:38:26 +0530 Subject: [PATCH 013/705] fix: add a missing comma --- core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config.py b/core/config.py index f9097e737e..9b2763aa55 100644 --- a/core/config.py +++ b/core/config.py @@ -111,7 +111,7 @@ class ConfigManager: # bot "token": None, # github access token for private repositories - "github_token": None + "github_token": None, # Logging "log_level": "INFO", "enable_plugins": True, From 98c691eade294e0eea7b7afe0af77e10f159131b Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Thu, 20 Feb 2020 21:27:45 -0800 Subject: [PATCH 014/705] Add my plugin, the suggestion plugin. --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 00518c1c65..0c887c88b7 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -196,4 +196,13 @@ "icon_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png", "thumbnail_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png" } + "suggest": { + "repository": "realcyguy/modmail-plugins", + "branch": "master", + "description": "Send suggestions to a selected server! It even has moderation...", + "bot_version": "3.4.1", + "title": "Suggest stuff.", + "icon_url": "https://i.imgur.com/qtE7AH8.png", + "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" + } } From 663caabcdca8ad15f8b27577f4f526cf687815bb Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Thu, 20 Feb 2020 22:36:16 -0800 Subject: [PATCH 015/705] added comma --- plugins/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 0c887c88b7..32210e50be 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -195,7 +195,7 @@ "title": "Server Stats", "icon_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png", "thumbnail_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png" - } + }, "suggest": { "repository": "realcyguy/modmail-plugins", "branch": "master", From dd3d5412433f41b15b88714bb3608d709764ec97 Mon Sep 17 00:00:00 2001 From: "MiscDev.py" <60783846+mischievousdev@users.noreply.github.com> Date: Tue, 10 Mar 2020 16:26:22 +0530 Subject: [PATCH 016/705] Added title in githubstats plugin --- plugins/registry.json | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/registry.json b/plugins/registry.json index c66b01b081..379245539b 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -210,6 +210,7 @@ "branch": "master", "description": "Github statistics in discord", "bot_version": "2.20.1", + "title": "Github Stats", "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" } From 4c235f1a30e2f983a34ec1ecb5e2c3dc1ed7f75d Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Thu, 12 Mar 2020 01:35:34 -0700 Subject: [PATCH 017/705] support newer venv and virtualenv since real_prefix is no longer set --- cogs/plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index e4543d2f1e..b602d6e78e 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -187,7 +187,7 @@ async def load_plugin(self, plugin): if req_txt.exists(): # Install PIP requirements - venv = hasattr(sys, "real_prefix") # in a virtual env + venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env user_install = " --user" if not venv else "" proc = await asyncio.create_subprocess_shell( f"{sys.executable} -m pip install --upgrade{user_install} -r {req_txt} -q -q", From 9dd6a268f440f5516d1e0f9cbf766118c114aab6 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 13 Mar 2020 23:40:36 +0100 Subject: [PATCH 018/705] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9873ba5f12..4b36c5a3d2 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ Special thanks to our sponsors for supporting the project. - + From fc2d0a2d6d77bb1453eeb6862b966b57b99cdef1 Mon Sep 17 00:00:00 2001 From: Taven Argus Date: Thu, 16 Apr 2020 04:21:56 +0000 Subject: [PATCH 019/705] Ensure optional dependencies in pyproject.toml can be installed by poetry. This adds an extras section so that the defined optionals can be installed with poetry. Source: https://stackoverflow.com/a/60990574/5586359 --- poetry.lock | 467 ++++++++++++++++++++++++++++++++++++++++++------- pyproject.toml | 2 + 2 files changed, 405 insertions(+), 64 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1841d893a1..f4b23956b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,6 +13,9 @@ chardet = ">=2.0,<4.0" multidict = ">=4.0,<5.0" yarl = ">=1.0,<2.0" +[package.extras] +speedups = ["aiodns", "brotlipy", "cchardet"] + [[package]] category = "dev" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." @@ -54,6 +57,12 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "19.3.0" +[package.extras] +azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] +dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] +docs = ["sphinx", "zope.interface"] +tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] + [[package]] category = "dev" description = "Security oriented static analyser for python code." @@ -83,6 +92,9 @@ attrs = ">=18.1.0" click = ">=6.5" toml = ">=0.9.4" +[package.extras] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + [[package]] category = "main" description = "Universal encoding detector for Python 2 and 3" @@ -96,8 +108,8 @@ category = "dev" description = "Composable command line interface toolkit" name = "click" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "7.0" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "7.1.1" [[package]] category = "main" @@ -119,6 +131,10 @@ version = "1.2.5" aiohttp = ">=3.3.0,<3.6.0" websockets = ">=6.0,<7.0" +[package.extras] +docs = ["sphinx (1.7.4)", "sphinxcontrib-asyncio", "sphinxcontrib-websupport"] +voice = ["PyNaCl (1.3.0)"] + [[package]] category = "main" description = "DNS toolkit" @@ -127,6 +143,10 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "1.16.0" +[package.extras] +DNSSEC = ["pycryptodome", "ecdsa (>=0.13)"] +IDNA = ["idna (>=2.1)"] + [[package]] category = "main" description = "Emoji for Python" @@ -135,6 +155,9 @@ optional = false python-versions = "*" version = "0.5.4" +[package.extras] +dev = ["nose", "coverage", "coveralls"] + [[package]] category = "main" description = "Backport of the concurrent.futures package from Python 3.2" @@ -146,24 +169,24 @@ version = "3.1.1" [[package]] category = "dev" description = "Git Object Database" -name = "gitdb2" +name = "gitdb" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.0.6" +python-versions = ">=3.4" +version = "4.0.4" [package.dependencies] -smmap2 = ">=2.0.0" +smmap = ">=3.0.1,<4" [[package]] category = "dev" description = "Python Git Library" name = "gitpython" optional = false -python-versions = ">=3.0, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.0.5" +python-versions = ">=3.4" +version = "3.1.1" [package.dependencies] -gitdb2 = ">=2.0.0" +gitdb = ">=4.0.1,<5" [[package]] category = "main" @@ -171,7 +194,7 @@ description = "Internationalized Domain Names in Applications (IDNA)" name = "idna" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.8" +version = "2.9" [[package]] category = "main" @@ -192,6 +215,12 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "4.3.21" +[package.extras] +pipfile = ["pipreqs", "requirementslib"] +pyproject = ["toml"] +requirements = ["pipreqs", "pip-api"] +xdg_home = ["appdirs (>=1.4.0)"] + [[package]] category = "dev" description = "A fast and thorough lazy object proxy." @@ -226,7 +255,7 @@ description = "multidict implementation" name = "multidict" optional = false python-versions = ">=3.5" -version = "4.7.1" +version = "4.7.5" [[package]] category = "main" @@ -253,7 +282,7 @@ description = "Python Build Reasonableness" name = "pbr" optional = false python-versions = "*" -version = "5.4.4" +version = "5.4.5" [[package]] category = "dev" @@ -275,7 +304,15 @@ description = "Python driver for MongoDB " name = "pymongo" optional = true python-versions = "*" -version = "3.10.0" +version = "3.10.1" + +[package.extras] +encryption = ["pymongocrypt (<2.0.0)"] +gssapi = ["pykerberos"] +snappy = ["python-snappy"] +srv = ["dnspython (>=1.16.0,<1.17.0)"] +tls = ["ipaddress"] +zstd = ["zstandard"] [[package]] category = "main" @@ -294,31 +331,34 @@ description = "Add .env support to your django/flask apps in development and dep name = "python-dotenv" optional = false python-versions = "*" -version = "0.10.3" +version = "0.10.5" + +[package.extras] +cli = ["click (>=5.0)"] [[package]] category = "dev" description = "YAML parser and emitter for Python" name = "pyyaml" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "5.2" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "5.3.1" [[package]] category = "main" description = "Python 2 and 3 compatibility utilities" name = "six" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "1.13.0" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.14.0" [[package]] category = "dev" description = "A pure Python implementation of a sliding window memory map manager" -name = "smmap2" +name = "smmap" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.0.5" +version = "3.0.2" [[package]] category = "dev" @@ -326,7 +366,7 @@ description = "Manage dynamic plugins for Python applications" name = "stevedore" optional = false python-versions = "*" -version = "1.31.0" +version = "1.32.0" [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" @@ -347,7 +387,7 @@ marker = "implementation_name == \"cpython\" and python_version < \"3.8\"" name = "typed-ast" optional = false python-versions = "*" -version = "1.4.0" +version = "1.4.1" [[package]] category = "main" @@ -385,48 +425,347 @@ version = "1.4.2" idna = ">=2.0" multidict = ">=4.0" +[extras] +mongodb = ["motor"] + [metadata] -content-hash = "fbe9e329f33e482854cff5bf05b006de9830c2d46bf3874e2ee4f8a8da0b1797" +content-hash = "793f86eb19d73f473f00883384ec965876c3930f41f94a171d2d1bc38f66903b" python-versions = "^3.7" -[metadata.hashes] -aiohttp = ["00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55", "0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed", "09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10", "199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5", "296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1", "368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939", "40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390", "629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa", "6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc", "87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5", "9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d", "9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf", "9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6", "a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72", "a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12", "a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366", "acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4", "b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300", "c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d", "cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303", "d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6", "e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889"] -appdirs = ["9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", "d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"] -astroid = ["71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", "840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"] -async-timeout = ["0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"] -attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] -bandit = ["336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952", "41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"] -black = ["09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", "68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"] -chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] -click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] -colorama = ["7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", "e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"] -"discord.py" = ["7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d"] -dnspython = ["36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", "f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"] -emoji = ["60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"] -futures = ["3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b", "51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd", "c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"] -gitdb2 = ["1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350", "96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b"] -gitpython = ["9c2398ffc3dcb3c40b27324b316f08a4f93ad646d5a6328cafbb871aa79f5e42", "c155c6a2653593ccb300462f6ef533583a913e17857cfef8fc617c246b6dc245"] -idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] -isodate = ["2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", "aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"] -isort = ["54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", "6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"] -lazy-object-proxy = ["0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", "194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", "1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", "4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", "48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", "5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", "59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", "8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", "9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", "9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", "97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", "9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", "a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", "a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", "ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", "cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", "d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", "d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", "eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", "efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"] -mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] -motor = ["599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", "756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", "97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"] -multidict = ["09c19f642e055550c9319d5123221b7e07fc79bda58122aa93910e52f2ab2f29", "0c1a5d5f7aa7189f7b83c4411c2af8f1d38d69c4360d5de3eea129c65d8d7ce2", "12f22980e7ed0972a969520fb1e55682c9fca89a68b21b49ec43132e680be812", "258660e9d6b52de1a75097944e12718d3aa59adc611b703361e3577d69167aaf", "3374a23e707848f27b3438500db0c69eca82929337656fce556bd70031fbda74", "503b7fce0054c73aa631cc910a470052df33d599f3401f3b77e54d31182525d5", "6ce55f2c45ffc90239aab625bb1b4864eef33f73ea88487ef968291fbf09fb3f", "725496dde5730f4ad0a627e1a58e2620c1bde0ad1c8080aae15d583eb23344ce", "a3721078beff247d0cd4fb19d915c2c25f90907cf8d6cd49d0413a24915577c6", "ba566518550f81daca649eded8b5c7dd09210a854637c82351410aa15c49324a", "c42362750a51a15dc905cb891658f822ee5021bfbea898c03aa1ed833e2248a5", "cf14aaf2ab067ca10bca0b14d5cbd751dd249e65d371734bc0e47ddd8fafc175", "cf24e15986762f0e75a622eb19cfe39a042e952b8afba3e7408835b9af2be4fb", "d7b6da08538302c5245cd3103f333655ba7f274915f1f5121c4f4b5fbdb3febe", "e27e13b9ff0a914a6b8fb7e4947d4ac6be8e4f61ede17edffabd088817df9e26", "e53b205f8afd76fc6c942ef39e8ee7c519c775d336291d32874082a87802c67c", "ec804fc5f68695d91c24d716020278fcffd50890492690a7e1fef2e741f7172c"] -natural = ["18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"] -parsedatetime = ["3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1", "d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667"] -pbr = ["139d2625547dbfa5fb0b81daebb39601c478c21956dc57e2e07b74450a8c506b", "61aa52a0f18b71c5cc58232d2cf8f8d09cd67fcad60b742a60124cb8d6951488"] -pylint = ["3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", "886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"] -pymongo = ["0369136c6e79c5edc16aa5de2b48a1b1c1fe5e6f7fc5915a2deaa98bd6e9dad5", "08364e1bea1507c516b18b826ec790cb90433aec2f235033ec5eecfd1011633b", "0af1d2bc8cc9503bf92ec3669a77ec3a6d7938193b583fb867b7e9696eed52e8", "0cfd1aeeb8c0a634646ab3ebeb4ce6828b94b2e33553a69ff7e6c07c250bf201", "15bbd2b5397f7d22498e2f2769fd698a8a247b9cc1a630ee8dabf647fb333480", "1b4a13dff15641e58620524db15d7a323d60572b2b187261c5cb58c36d74778d", "22fbdb908257f9aaaa372a7684f3e094a05ca52eb84f8f381c8b1827c49556fd", "264272fd1c95fc48002ad85d5e41270831777b4180f2500943e45e12b2a3ab43", "3372e98eebbfd05ebf020388003f8a4438bed41e0fef1ef696d2c13633c416c8", "339d24ecdc42745d2dc09b26fda8151988e806ca81134a7bd10513c4031d91e1", "38281855fc3961ba5510fbb503b8d16cc1fcb326e9f7ba0dd096ed4eb72a7084", "4acdd2e16392472bfd49ca49038845c95e5254b5af862b55f7f2cc79aa258886", "4e0c006bc6e98e861b678432e05bf64ba3eb889b6ab7e7bf1ebaecf9f1ba0e58", "4e4284bcbe4b7be1b37f9641509085b715c478e7fbf8f820358362b5dd359379", "4e5e94a5f9823f0bd0c56012a57650bc6772636c29d83d253260c26b908fcfd9", "4e61f30800a40f1770b2ec56bbf5dc0f0e3f7e9250eb05fa4feb9ccb7bbe39ca", "53577cf57ba9d93b58ab41d45250277828ff83c5286dde14f855e4b17ec19976", "681cb31e8631882804a6cc3c8cc8f54a74ff3a82261a78e50f20c5eec05ac855", "6dfc2710f43dd1d66991a0f160d196356732ccc8aa9dbc6875aeba78388fa142", "72218201b13d8169be5736417987e9a0a3b10d4349e40e4db7a6a5ac670c7ef2", "7247fbcdbf7ab574eb70743461b3cfc14d9cfae3f27a9afb6ce14d87f67dd0b5", "72651f4b4adf50201891580506c8cca465d94d38f26ed92abfc56440662c723c", "87b3aaf12ad6a9b5570b12d2a4b8802757cb3588a903aafd3c25f07f9caf07e3", "87c28b7b37617c5a01eb396487f7d3b61a453e1fa0475a175ab87712d6f5d52f", "88efe627b628f36ef53f09abb218d4630f83d8ebde7028689439559475c43dae", "89bfbca22266f12df7fb80092b7c876734751d02b93789580b68957ad4a8bf56", "908a3caf348a672b28b8a06fe7b4a27c2fdcf7f873df671e4027d48bcd7f971f", "9128e7bea85f3a3041306fa14a7aa82a24b47881918500e1b8396dd1c933b5a6", "9737d6d688a15b8d5c0bfa909638b79261e195be817b9f1be79c722bbb23cd76", "98a8305da158f46e99e7e51db49a2f8b5fcdd7683ea7083988ccb9c4450507a6", "99285cd44c756f0900cbdb5fe75f567c0a76a273b7e0467f23cb76f47e60aac0", "9ed568f8026ffeb00ce31e5351e0d09d704cc19a29549ba4da0ac145d2a26fdf", "a006162035032021dfd00a879643dc06863dac275f9210d843278566c719eebc", "a03cb336bc8d25a11ff33b94967478a9775b0d2b23b39e952d9cc6cb93b75d69", "a863ceb67be163060d1099b7e89b6dd83d6dd50077c7ceae31ac844c4c2baff9", "b82628eaf0a16c1f50e1c205fd1dd406d7874037dd84643da89e91b5043b5e82", "bc6446a41fb7eeaf2c808bab961b9bac81db0f5de69eab74eebe1b8b072399f7", "c42d290ed54096355838421cf9d2a56e150cb533304d2439ef1adf612a986eaf", "c43879fe427ea6aa6e84dae9fbdc5aa14428a4cfe613fe0fee2cc004bf3f307c", "c566cbdd1863ba3ccf838656a1403c3c81fdb57cbe3fdd3515be7c9616763d33", "c5b7a0d7e6ca986de32b269b6dbbd5162c1a776ece72936f55decb4d1b197ee9", "ca109fe9f74da4930590bb589eb8fdf80e5d19f5cd9f337815cac9309bbd0a76", "d0260ba68f9bafd8775b2988b5aeace6e69a37593ec256e23e150c808160c05c", "d12d86e771fc3072a0e6bdbf4e417c63fec85ee47cb052ba7ad239403bf5e154", "d2ce33501149b373118fcfec88a292a87ef0b333fb30c7c6aac72fe64700bdf6", "d582ea8496e2a0e124e927a67dca55c8833f0dbfbc2c84aaf0e5949a2dd30c51", "d68b9ab0a900582a345fb279675b0ad4fac07d6a8c2678f12910d55083b7240d", "dbf1fa571db6006907aeaf6473580aaa76041f4f3cd1ff8a0039fd0f40b83f6d", "e032437a7d2b89dab880c79379d88059cee8019da0ff475d924c4ccab52db88f", "e0f5798f3ad60695465a093e3d002f609c41fef3dcb97fcefae355d24d3274cf", "e756355704a2cf91a7f4a649aa0bbf3bbd263018b9ed08f60198c262f4ee24b6", "e824b4b87bd88cbeb25c8babeadbbaaaf06f02bbb95a93462b7c6193a064974e", "ea1171470b52487152ed8bf27713cc2480dc8b0cd58e282a1bff742541efbfb8", "fa19aef44d5ed8f798a8136ff981aedfa508edac3b1bed481eca5dde5f14fd3d", "faf83d20c041637cb277e5fdb59abc217c40ab3202dd87cc95d6fbd9ce5ffd9b", "fceb6ae5a149a42766efb8344b0df6cfb21b55c55f360170abaddb11d43af0f1"] -python-dateutil = ["73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"] -python-dotenv = ["debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", "f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544"] -pyyaml = ["0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc", "2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803", "35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc", "38a4f0d114101c58c0f3a88aeaa44d63efd588845c5a2df5290b73db8f246d15", "483eb6a33b671408c8529106df3707270bfacb2447bf8ad856a4b4f57f6e3075", "4b6be5edb9f6bb73680f5bf4ee08ff25416d1400fbd4535fe0069b2994da07cd", "7f38e35c00e160db592091751d385cd7b3046d6d51f578b29943225178257b31", "8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f", "c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c", "e4c015484ff0ff197564917b4b4246ca03f411b9bd7f16e02a2f586eb48b6d04", "ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4"] -six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] -smmap2 = ["0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde", "29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a"] -stevedore = ["01d9f4beecf0fbd070ddb18e5efb10567801ba7ef3ddab0074f54e3cd4e91730", "e0739f9739a681c7a1fda76a102b65295e96a144ccdb552f2ae03c5f0abe8a14"] -toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"] -typed-ast = ["1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", "48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", "7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", "838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", "fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"] -uvloop = ["08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", "123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", "4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", "4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", "afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", "b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", "bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", "e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"] -websockets = ["0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136", "2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6", "5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1", "5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538", "669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4", "695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908", "6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0", "79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d", "7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c", "82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d", "8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c", "91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb", "952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf", "99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e", "9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96", "a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584", "cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484", "e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d", "e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559", "ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff", "f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"] -wrapt = ["565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"] -yarl = ["0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", "0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", "2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", "25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", "26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", "308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", "3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", "58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", "5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", "6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", "944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", "a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", "a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", "c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", "c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", "d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", "e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"] +[metadata.files] +aiohttp = [ + {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_10_x86_64.whl", hash = "sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5"}, + {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed"}, + {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303"}, + {file = "aiohttp-3.5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10"}, + {file = "aiohttp-3.5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa"}, + {file = "aiohttp-3.5.4-cp35-cp35m-win32.whl", hash = "sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4"}, + {file = "aiohttp-3.5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72"}, + {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5"}, + {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12"}, + {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6"}, + {file = "aiohttp-3.5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6"}, + {file = "aiohttp-3.5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d"}, + {file = "aiohttp-3.5.4-cp36-cp36m-win32.whl", hash = "sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1"}, + {file = "aiohttp-3.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d"}, + {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300"}, + {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390"}, + {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366"}, + {file = "aiohttp-3.5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889"}, + {file = "aiohttp-3.5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55"}, + {file = "aiohttp-3.5.4-cp37-cp37m-win32.whl", hash = "sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc"}, + {file = "aiohttp-3.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939"}, + {file = "aiohttp-3.5.4.tar.gz", hash = "sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf"}, +] +appdirs = [ + {file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"}, + {file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"}, +] +astroid = [ + {file = "astroid-2.3.3-py3-none-any.whl", hash = "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"}, + {file = "astroid-2.3.3.tar.gz", hash = "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a"}, +] +async-timeout = [ + {file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"}, + {file = "async_timeout-3.0.1-py3-none-any.whl", hash = "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"}, +] +attrs = [ + {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, + {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, +] +bandit = [ + {file = "bandit-1.6.2-py2.py3-none-any.whl", hash = "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952"}, + {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"}, +] +black = [ + {file = "black-19.3b0-py36-none-any.whl", hash = "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf"}, + {file = "black-19.3b0.tar.gz", hash = "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] +click = [ + {file = "click-7.1.1-py2.py3-none-any.whl", hash = "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"}, + {file = "click-7.1.1.tar.gz", hash = "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc"}, +] +colorama = [ + {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, + {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, +] +"discord.py" = [ + {file = "discord.py-1.2.5-py3-none-any.whl", hash = "sha256:7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d"}, +] +dnspython = [ + {file = "dnspython-1.16.0-py2.py3-none-any.whl", hash = "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"}, + {file = "dnspython-1.16.0.zip", hash = "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01"}, +] +emoji = [ + {file = "emoji-0.5.4.tar.gz", hash = "sha256:60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"}, +] +futures = [ + {file = "futures-3.1.1-py2-none-any.whl", hash = "sha256:c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"}, + {file = "futures-3.1.1-py3-none-any.whl", hash = "sha256:3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b"}, + {file = "futures-3.1.1.tar.gz", hash = "sha256:51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd"}, +] +gitdb = [ + {file = "gitdb-4.0.4-py3-none-any.whl", hash = "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a"}, + {file = "gitdb-4.0.4.tar.gz", hash = "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5"}, +] +gitpython = [ + {file = "GitPython-3.1.1-py3-none-any.whl", hash = "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d"}, + {file = "GitPython-3.1.1.tar.gz", hash = "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74"}, +] +idna = [ + {file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"}, + {file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"}, +] +isodate = [ + {file = "isodate-0.6.0-py2.py3-none-any.whl", hash = "sha256:aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"}, + {file = "isodate-0.6.0.tar.gz", hash = "sha256:2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8"}, +] +isort = [ + {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"}, + {file = "isort-4.3.21.tar.gz", hash = "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1"}, +] +lazy-object-proxy = [ + {file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"}, + {file = "lazy_object_proxy-1.4.3-cp27-cp27m-macosx_10_13_x86_64.whl", hash = "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442"}, + {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win32.whl", hash = "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4"}, + {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a"}, + {file = "lazy_object_proxy-1.4.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d"}, + {file = "lazy_object_proxy-1.4.3-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a"}, + {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win32.whl", hash = "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e"}, + {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win_amd64.whl", hash = "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357"}, + {file = "lazy_object_proxy-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50"}, + {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db"}, + {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449"}, + {file = "lazy_object_proxy-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156"}, + {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531"}, + {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb"}, + {file = "lazy_object_proxy-1.4.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08"}, + {file = "lazy_object_proxy-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383"}, + {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142"}, + {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea"}, + {file = "lazy_object_proxy-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62"}, + {file = "lazy_object_proxy-1.4.3-cp38-cp38-win32.whl", hash = "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd"}, + {file = "lazy_object_proxy-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +motor = [ + {file = "motor-2.1.0-py2-none-any.whl", hash = "sha256:599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909"}, + {file = "motor-2.1.0-py3-none-any.whl", hash = "sha256:97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"}, + {file = "motor-2.1.0.tar.gz", hash = "sha256:756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4"}, +] +multidict = [ + {file = "multidict-4.7.5-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:fc3b4adc2ee8474cb3cd2a155305d5f8eda0a9c91320f83e55748e1fcb68f8e3"}, + {file = "multidict-4.7.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:42f56542166040b4474c0c608ed051732033cd821126493cf25b6c276df7dd35"}, + {file = "multidict-4.7.5-cp35-cp35m-win32.whl", hash = "sha256:7774e9f6c9af3f12f296131453f7b81dabb7ebdb948483362f5afcaac8a826f1"}, + {file = "multidict-4.7.5-cp35-cp35m-win_amd64.whl", hash = "sha256:c2c37185fb0af79d5c117b8d2764f4321eeb12ba8c141a95d0aa8c2c1d0a11dd"}, + {file = "multidict-4.7.5-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:e439c9a10a95cb32abd708bb8be83b2134fa93790a4fb0535ca36db3dda94d20"}, + {file = "multidict-4.7.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:85cb26c38c96f76b7ff38b86c9d560dea10cf3459bb5f4caf72fc1bb932c7136"}, + {file = "multidict-4.7.5-cp36-cp36m-win32.whl", hash = "sha256:620b37c3fea181dab09267cd5a84b0f23fa043beb8bc50d8474dd9694de1fa6e"}, + {file = "multidict-4.7.5-cp36-cp36m-win_amd64.whl", hash = "sha256:6e6fef114741c4d7ca46da8449038ec8b1e880bbe68674c01ceeb1ac8a648e78"}, + {file = "multidict-4.7.5-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a326f4240123a2ac66bb163eeba99578e9d63a8654a59f4688a79198f9aa10f8"}, + {file = "multidict-4.7.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dc561313279f9d05a3d0ffa89cd15ae477528ea37aa9795c4654588a3287a9ab"}, + {file = "multidict-4.7.5-cp37-cp37m-win32.whl", hash = "sha256:4b7df040fb5fe826d689204f9b544af469593fb3ff3a069a6ad3409f742f5928"}, + {file = "multidict-4.7.5-cp37-cp37m-win_amd64.whl", hash = "sha256:317f96bc0950d249e96d8d29ab556d01dd38888fbe68324f46fd834b430169f1"}, + {file = "multidict-4.7.5-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:b51249fdd2923739cd3efc95a3d6c363b67bbf779208e9f37fd5e68540d1a4d4"}, + {file = "multidict-4.7.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ae402f43604e3b2bc41e8ea8b8526c7fa7139ed76b0d64fc48e28125925275b2"}, + {file = "multidict-4.7.5-cp38-cp38-win32.whl", hash = "sha256:bb519becc46275c594410c6c28a8a0adc66fe24fef154a9addea54c1adb006f5"}, + {file = "multidict-4.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:544fae9261232a97102e27a926019100a9db75bec7b37feedd74b3aa82f29969"}, + {file = "multidict-4.7.5.tar.gz", hash = "sha256:aee283c49601fa4c13adc64c09c978838a7e812f85377ae130a24d7198c0331e"}, +] +natural = [ + {file = "natural-0.2.0.tar.gz", hash = "sha256:18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"}, +] +parsedatetime = [ + {file = "parsedatetime-2.5-py2-none-any.whl", hash = "sha256:3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1"}, + {file = "parsedatetime-2.5.tar.gz", hash = "sha256:d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667"}, +] +pbr = [ + {file = "pbr-5.4.5-py2.py3-none-any.whl", hash = "sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"}, + {file = "pbr-5.4.5.tar.gz", hash = "sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c"}, +] +pylint = [ + {file = "pylint-2.4.4-py3-none-any.whl", hash = "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"}, + {file = "pylint-2.4.4.tar.gz", hash = "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd"}, +] +pymongo = [ + {file = "pymongo-3.10.1-cp27-cp27m-macosx_10_14_intel.whl", hash = "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee"}, + {file = "pymongo-3.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed"}, + {file = "pymongo-3.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6"}, + {file = "pymongo-3.10.1-cp27-cp27m-win32.whl", hash = "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5"}, + {file = "pymongo-3.10.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe"}, + {file = "pymongo-3.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc"}, + {file = "pymongo-3.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764"}, + {file = "pymongo-3.10.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372"}, + {file = "pymongo-3.10.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32"}, + {file = "pymongo-3.10.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc"}, + {file = "pymongo-3.10.1-cp34-cp34m-win32.whl", hash = "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a"}, + {file = "pymongo-3.10.1-cp34-cp34m-win_amd64.whl", hash = "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae"}, + {file = "pymongo-3.10.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35"}, + {file = "pymongo-3.10.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b"}, + {file = "pymongo-3.10.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80"}, + {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409"}, + {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113"}, + {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_ppc64le.whl", hash = "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f"}, + {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_s390x.whl", hash = "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf"}, + {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d"}, + {file = "pymongo-3.10.1-cp35-cp35m-win32.whl", hash = "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57"}, + {file = "pymongo-3.10.1-cp35-cp35m-win_amd64.whl", hash = "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70"}, + {file = "pymongo-3.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8"}, + {file = "pymongo-3.10.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4"}, + {file = "pymongo-3.10.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606"}, + {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e"}, + {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151"}, + {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54"}, + {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464"}, + {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73"}, + {file = "pymongo-3.10.1-cp36-cp36m-win32.whl", hash = "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33"}, + {file = "pymongo-3.10.1-cp36-cp36m-win_amd64.whl", hash = "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6"}, + {file = "pymongo-3.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f"}, + {file = "pymongo-3.10.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d"}, + {file = "pymongo-3.10.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d"}, + {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794"}, + {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7"}, + {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2"}, + {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11"}, + {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951"}, + {file = "pymongo-3.10.1-cp37-cp37m-win32.whl", hash = "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39"}, + {file = "pymongo-3.10.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b"}, + {file = "pymongo-3.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03"}, + {file = "pymongo-3.10.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c"}, + {file = "pymongo-3.10.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892"}, + {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103"}, + {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7"}, + {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d"}, + {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82"}, + {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be"}, + {file = "pymongo-3.10.1-cp38-cp38-win32.whl", hash = "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f"}, + {file = "pymongo-3.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac"}, + {file = "pymongo-3.10.1-py2.7-macosx-10.14-intel.egg", hash = "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a"}, + {file = "pymongo-3.10.1-py2.7-win-amd64.egg", hash = "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012"}, + {file = "pymongo-3.10.1-py2.7-win32.egg", hash = "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a"}, + {file = "pymongo-3.10.1.tar.gz", hash = "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, + {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, +] +python-dotenv = [ + {file = "python-dotenv-0.10.5.tar.gz", hash = "sha256:f254bfd0c970d64ccbb6c9ebef3667ab301a71473569c991253a481f1c98dddc"}, + {file = "python_dotenv-0.10.5-py2.py3-none-any.whl", hash = "sha256:440c7c23d53b7d352f9c94d6f70860242c2f071cf5c029dd661ccb22d64ae42b"}, +] +pyyaml = [ + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, +] +six = [ + {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, + {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, +] +smmap = [ + {file = "smmap-3.0.2-py2.py3-none-any.whl", hash = "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1"}, + {file = "smmap-3.0.2.tar.gz", hash = "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911"}, +] +stevedore = [ + {file = "stevedore-1.32.0-py2.py3-none-any.whl", hash = "sha256:a4e7dc759fb0f2e3e2f7d8ffe2358c19d45b9b8297f393ef1256858d82f69c9b"}, + {file = "stevedore-1.32.0.tar.gz", hash = "sha256:18afaf1d623af5950cc0f7e75e70f917784c73b652a34a12d90b309451b5500b"}, +] +toml = [ + {file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"}, + {file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"}, + {file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] +uvloop = [ + {file = "uvloop-0.14.0-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd"}, + {file = "uvloop-0.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726"}, + {file = "uvloop-0.14.0-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7"}, + {file = "uvloop-0.14.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"}, + {file = "uvloop-0.14.0-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891"}, + {file = "uvloop-0.14.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95"}, + {file = "uvloop-0.14.0-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5"}, + {file = "uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09"}, + {file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"}, +] +websockets = [ + {file = "websockets-6.0-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d"}, + {file = "websockets-6.0-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484"}, + {file = "websockets-6.0-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e"}, + {file = "websockets-6.0-cp34-cp34m-win32.whl", hash = "sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"}, + {file = "websockets-6.0-cp34-cp34m-win_amd64.whl", hash = "sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96"}, + {file = "websockets-6.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538"}, + {file = "websockets-6.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0"}, + {file = "websockets-6.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1"}, + {file = "websockets-6.0-cp35-cp35m-win32.whl", hash = "sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d"}, + {file = "websockets-6.0-cp35-cp35m-win_amd64.whl", hash = "sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6"}, + {file = "websockets-6.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf"}, + {file = "websockets-6.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d"}, + {file = "websockets-6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb"}, + {file = "websockets-6.0-cp36-cp36m-win32.whl", hash = "sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c"}, + {file = "websockets-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff"}, + {file = "websockets-6.0-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908"}, + {file = "websockets-6.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559"}, + {file = "websockets-6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4"}, + {file = "websockets-6.0-cp37-cp37m-win32.whl", hash = "sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136"}, + {file = "websockets-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584"}, + {file = "websockets-6.0.tar.gz", hash = "sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c"}, +] +wrapt = [ + {file = "wrapt-1.11.2.tar.gz", hash = "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"}, +] +yarl = [ + {file = "yarl-1.4.2-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b"}, + {file = "yarl-1.4.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1"}, + {file = "yarl-1.4.2-cp35-cp35m-win32.whl", hash = "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080"}, + {file = "yarl-1.4.2-cp35-cp35m-win_amd64.whl", hash = "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a"}, + {file = "yarl-1.4.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f"}, + {file = "yarl-1.4.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea"}, + {file = "yarl-1.4.2-cp36-cp36m-win32.whl", hash = "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb"}, + {file = "yarl-1.4.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70"}, + {file = "yarl-1.4.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d"}, + {file = "yarl-1.4.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce"}, + {file = "yarl-1.4.2-cp37-cp37m-win32.whl", hash = "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"}, + {file = "yarl-1.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce"}, + {file = "yarl-1.4.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b"}, + {file = "yarl-1.4.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae"}, + {file = "yarl-1.4.2-cp38-cp38-win32.whl", hash = "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462"}, + {file = "yarl-1.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6"}, + {file = "yarl-1.4.2.tar.gz", hash = "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b"}, +] diff --git a/pyproject.toml b/pyproject.toml index 3ea9cf9b8e..a114573201 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,3 +54,5 @@ black = {version = "=19.3b0", allows-prereleases = true} pylint = "^2.4" bandit = "^1.6" +[tool.poetry.extras] +mongodb = ["motor"] From f8931cc9816dc6603423b5c05f0dc5d3903954ac Mon Sep 17 00:00:00 2001 From: Mark David <44349634+markd69@users.noreply.github.com> Date: Thu, 16 Apr 2020 14:05:36 -0400 Subject: [PATCH 020/705] Changed Typo on !unsubscribe (tag) When a user is tagged in the !unsubscribe command it shows as they are already subscribed but they are not. --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 7d36cecb62..3b9c591294 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -502,7 +502,7 @@ async def subscribe( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=f"{mention} is already subscribed to this thread.", + description=f"{mention} is not subscribed to this thread.", ) else: mentions.append(mention) From ec831a302e8f42e78618b34ee138ec9f33267986 Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Sun, 19 Apr 2020 17:54:33 -0700 Subject: [PATCH 021/705] make approved issues not stale --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index b3003ccf92..c204febe99 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,4 +14,4 @@ jobs: stale-issue-message: 'This issue is stale because it has been open for 100 days with no activity. Remove stale label or comment or this will be closed in 5 days. Please do not un-stale this issue unless it carries significant contribution.' days-before-stale: 100 days-before-close: 5 - exempt-issue-label: 'high priority' + exempt-issue-label: 'high priority,approved' From 9d391ea002e0c1f03b541c7e9ae9a6bc7ce2f117 Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Sun, 19 Apr 2020 18:00:00 -0700 Subject: [PATCH 022/705] change high priority to actual name --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index c204febe99..e4408c1388 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,4 +14,4 @@ jobs: stale-issue-message: 'This issue is stale because it has been open for 100 days with no activity. Remove stale label or comment or this will be closed in 5 days. Please do not un-stale this issue unless it carries significant contribution.' days-before-stale: 100 days-before-close: 5 - exempt-issue-label: 'high priority,approved' + exempt-issue-label: 'priority: high,approved' From fd09373270da732d879ed13442ba6e25c252ba68 Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Sun, 19 Apr 2020 18:00:32 -0700 Subject: [PATCH 023/705] security is also not stale --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index e4408c1388..f5f4eb1976 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,4 +14,4 @@ jobs: stale-issue-message: 'This issue is stale because it has been open for 100 days with no activity. Remove stale label or comment or this will be closed in 5 days. Please do not un-stale this issue unless it carries significant contribution.' days-before-stale: 100 days-before-close: 5 - exempt-issue-label: 'priority: high,approved' + exempt-issue-label: 'priority: high,approved,security' From 6febccf05395988607b7f663ef9a542a2aff674c Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Mon, 20 Apr 2020 08:38:51 -0700 Subject: [PATCH 024/705] added bug --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index f5f4eb1976..d0811bfd30 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,4 +14,4 @@ jobs: stale-issue-message: 'This issue is stale because it has been open for 100 days with no activity. Remove stale label or comment or this will be closed in 5 days. Please do not un-stale this issue unless it carries significant contribution.' days-before-stale: 100 days-before-close: 5 - exempt-issue-label: 'priority: high,approved,security' + exempt-issue-label: 'priority: high,approved,security,bug' From 0ea0a907d2bb93257c9cd0c3143fea65cc93d37f Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Tue, 26 May 2020 22:43:46 -0700 Subject: [PATCH 025/705] Update bot.py --- bot.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bot.py b/bot.py index 694f860cf1..9b8bdd1141 100644 --- a/bot.py +++ b/bot.py @@ -46,6 +46,9 @@ if not os.path.exists(temp_dir): os.mkdir(temp_dir) +if sys.platform == 'win32': + asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) + class ModmailBot(commands.Bot): def __init__(self): From 6af5ff1113f0e2323439039186c0e446ffb56329 Mon Sep 17 00:00:00 2001 From: xTeen <62380638+Teen1@users.noreply.github.com> Date: Mon, 1 Jun 2020 18:28:58 +0300 Subject: [PATCH 026/705] Added new plugin added slowmode plugin to registry --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 379245539b..1a5872225d 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -214,4 +214,13 @@ "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" } + "slowmode": { + "repository": "teen1/modmail-plugins", + "branch": "master", + "description": "Configure slow mode for your channels with Modmail!", + "bot_version": "2.20.1", + "title": "Slow Mode", + "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", + "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" + } } From 46be01e97c57b03eca48b190a216168f8dc1b318 Mon Sep 17 00:00:00 2001 From: xTeen <62380638+Teen1@users.noreply.github.com> Date: Mon, 1 Jun 2020 18:41:46 +0300 Subject: [PATCH 027/705] Update registry.json --- plugins/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 1a5872225d..b15bb374dc 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -213,7 +213,7 @@ "title": "Github Stats", "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" - } + }, "slowmode": { "repository": "teen1/modmail-plugins", "branch": "master", From 0d4c8e22a5d34c51ba7b60adb75f2d80218f6f33 Mon Sep 17 00:00:00 2001 From: Ralph Date: Fri, 5 Jun 2020 01:47:48 -0400 Subject: [PATCH 028/705] Reformat plugins.py to pass black check --- cogs/plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index b602d6e78e..d14035286d 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -187,7 +187,7 @@ async def load_plugin(self, plugin): if req_txt.exists(): # Install PIP requirements - venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env + venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env user_install = " --user" if not venv else "" proc = await asyncio.create_subprocess_shell( f"{sys.executable} -m pip install --upgrade{user_install} -r {req_txt} -q -q", From e0387a4fed625f2aecf2caa4773896aa4cab49a1 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sat, 6 Jun 2020 23:15:48 -0700 Subject: [PATCH 029/705] Bumped versions in requirements, unstable --- Pipfile | 8 +- Pipfile.lock | 504 ++++++++++++++++++++++++------------------- poetry.lock | 496 ++++++++---------------------------------- pyproject.toml | 10 +- requirements.min.txt | 28 +-- runtime.txt | 2 +- 6 files changed, 396 insertions(+), 652 deletions(-) diff --git a/Pipfile b/Pipfile index 9173c3a5fe..16bbac8e49 100644 --- a/Pipfile +++ b/Pipfile @@ -4,7 +4,7 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -black = "==19.3b0" +black = "==19.10b0" pylint = "*" bandit = "==1.6.2" @@ -17,11 +17,11 @@ motor = ">=2.0.0" natural = "==0.2.0" isodate = ">=0.6.0" dnspython = "~=1.16.0" -parsedatetime = "==2.5" -aiohttp = "<3.6.0,>=3.3.0" +parsedatetime = "==2.6" +aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -"discord.py" = "==1.2.5" +"discord.py" = "==1.3.3" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 06d263645b..14f91762aa 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c2eb0898f236534a02cb1c198d74c82fed052b4445e39f99c1af3e58d22aa435" + "sha256": "bfb85b7c7862e17e905d739f0fb63248d3bf446035f32e3afac619f6d2c5a0ba" }, "pipfile-spec": 6, "requires": { @@ -18,31 +18,28 @@ "default": { "aiohttp": { "hashes": [ - "sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55", - "sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed", - "sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10", - "sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5", - "sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1", - "sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939", - "sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390", - "sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa", - "sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc", - "sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5", - "sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d", - "sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf", - "sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6", - "sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72", - "sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12", - "sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366", - "sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4", - "sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300", - "sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d", - "sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303", - "sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6", - "sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889" + "sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", + "sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", + "sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", + "sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", + "sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", + "sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", + "sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", + "sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", + "sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", + "sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", + "sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", + "sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965" ], "index": "pypi", - "version": "==3.5.4" + "version": "==3.6.2" + }, + "appdirs": { + "hashes": [ + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" + ], + "version": "==1.4.4" }, "async-timeout": { "hashes": [ @@ -60,10 +57,10 @@ }, "certifi": { "hashes": [ - "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", - "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" + "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304", + "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519" ], - "version": "==2019.11.28" + "version": "==2020.4.5.1" }, "chardet": { "hashes": [ @@ -82,10 +79,17 @@ }, "discord.py": { "hashes": [ - "sha256:7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d" + "sha256:406871b06d86c3dc49fba63238519f28628dac946fef8a0e22988ff58ec05580", + "sha256:ad00e34c72d2faa8db2157b651d05f3c415d7d05078e7e41dc9e8dc240051beb" ], "index": "pypi", - "version": "==1.2.5" + "version": "==1.3.3" + }, + "distlib": { + "hashes": [ + "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21" + ], + "version": "==0.3.0" }, "dnspython": { "hashes": [ @@ -102,12 +106,27 @@ "index": "pypi", "version": "==0.5.4" }, + "filelock": { + "hashes": [ + "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", + "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" + ], + "version": "==3.0.12" + }, "idna": { "hashes": [ - "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", - "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", + "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa" ], - "version": "==2.8" + "version": "==2.9" + }, + "importlib-metadata": { + "hashes": [ + "sha256:0505dd08068cfec00f53a74a0ad927676d7757da81b7436a6eefe4c7cf75c545", + "sha256:15ec6c0fd909e893e3a08b3a7c76ecb149122fb14b7efe1199ddd4c7c57ea958" + ], + "markers": "python_version < '3.8'", + "version": "==1.6.1" }, "isodate": { "hashes": [ @@ -128,25 +147,25 @@ }, "multidict": { "hashes": [ - "sha256:09c19f642e055550c9319d5123221b7e07fc79bda58122aa93910e52f2ab2f29", - "sha256:0c1a5d5f7aa7189f7b83c4411c2af8f1d38d69c4360d5de3eea129c65d8d7ce2", - "sha256:12f22980e7ed0972a969520fb1e55682c9fca89a68b21b49ec43132e680be812", - "sha256:258660e9d6b52de1a75097944e12718d3aa59adc611b703361e3577d69167aaf", - "sha256:3374a23e707848f27b3438500db0c69eca82929337656fce556bd70031fbda74", - "sha256:503b7fce0054c73aa631cc910a470052df33d599f3401f3b77e54d31182525d5", - "sha256:6ce55f2c45ffc90239aab625bb1b4864eef33f73ea88487ef968291fbf09fb3f", - "sha256:725496dde5730f4ad0a627e1a58e2620c1bde0ad1c8080aae15d583eb23344ce", - "sha256:a3721078beff247d0cd4fb19d915c2c25f90907cf8d6cd49d0413a24915577c6", - "sha256:ba566518550f81daca649eded8b5c7dd09210a854637c82351410aa15c49324a", - "sha256:c42362750a51a15dc905cb891658f822ee5021bfbea898c03aa1ed833e2248a5", - "sha256:cf14aaf2ab067ca10bca0b14d5cbd751dd249e65d371734bc0e47ddd8fafc175", - "sha256:cf24e15986762f0e75a622eb19cfe39a042e952b8afba3e7408835b9af2be4fb", - "sha256:d7b6da08538302c5245cd3103f333655ba7f274915f1f5121c4f4b5fbdb3febe", - "sha256:e27e13b9ff0a914a6b8fb7e4947d4ac6be8e4f61ede17edffabd088817df9e26", - "sha256:e53b205f8afd76fc6c942ef39e8ee7c519c775d336291d32874082a87802c67c", - "sha256:ec804fc5f68695d91c24d716020278fcffd50890492690a7e1fef2e741f7172c" - ], - "version": "==4.7.1" + "sha256:1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", + "sha256:275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", + "sha256:3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", + "sha256:4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", + "sha256:5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", + "sha256:51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", + "sha256:5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", + "sha256:6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", + "sha256:7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", + "sha256:9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", + "sha256:c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", + "sha256:d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", + "sha256:e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", + "sha256:f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", + "sha256:fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", + "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", + "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" + ], + "version": "==4.7.6" }, "natural": { "hashes": [ @@ -157,78 +176,77 @@ }, "parsedatetime": { "hashes": [ - "sha256:3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1", - "sha256:d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667" + "sha256:4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455", + "sha256:cb96edd7016872f58479e35879294258c71437195760746faffedb692aef000b" ], "index": "pypi", - "version": "==2.5" + "version": "==2.6" }, "pipenv": { "hashes": [ - "sha256:56ad5f5cb48f1e58878e14525a6e3129d4306049cb76d2f6a3e95df0d5fc6330", - "sha256:7df8e33a2387de6f537836f48ac6fcd94eda6ed9ba3d5e3fd52e35b5bc7ff49e", - "sha256:a673e606e8452185e9817a987572b55360f4d28b50831ef3b42ac3cab3fee846" + "sha256:7dd49a7345fa5da7843907bab42a996dece474e45dd309dbd7619739dc60478b", + "sha256:cc289dc78feaa14def4e1723b0b4d85ff628c8e5f740eeeb68197b90dafa8dff" ], "index": "pypi", - "version": "==2018.11.26" + "version": "==2020.6.2" }, "pymongo": { "hashes": [ - "sha256:0369136c6e79c5edc16aa5de2b48a1b1c1fe5e6f7fc5915a2deaa98bd6e9dad5", - "sha256:08364e1bea1507c516b18b826ec790cb90433aec2f235033ec5eecfd1011633b", - "sha256:0af1d2bc8cc9503bf92ec3669a77ec3a6d7938193b583fb867b7e9696eed52e8", - "sha256:0cfd1aeeb8c0a634646ab3ebeb4ce6828b94b2e33553a69ff7e6c07c250bf201", - "sha256:1b4a13dff15641e58620524db15d7a323d60572b2b187261c5cb58c36d74778d", - "sha256:22fbdb908257f9aaaa372a7684f3e094a05ca52eb84f8f381c8b1827c49556fd", - "sha256:264272fd1c95fc48002ad85d5e41270831777b4180f2500943e45e12b2a3ab43", - "sha256:3372e98eebbfd05ebf020388003f8a4438bed41e0fef1ef696d2c13633c416c8", - "sha256:339d24ecdc42745d2dc09b26fda8151988e806ca81134a7bd10513c4031d91e1", - "sha256:38281855fc3961ba5510fbb503b8d16cc1fcb326e9f7ba0dd096ed4eb72a7084", - "sha256:4acdd2e16392472bfd49ca49038845c95e5254b5af862b55f7f2cc79aa258886", - "sha256:4e0c006bc6e98e861b678432e05bf64ba3eb889b6ab7e7bf1ebaecf9f1ba0e58", - "sha256:4e4284bcbe4b7be1b37f9641509085b715c478e7fbf8f820358362b5dd359379", - "sha256:4e5e94a5f9823f0bd0c56012a57650bc6772636c29d83d253260c26b908fcfd9", - "sha256:4e61f30800a40f1770b2ec56bbf5dc0f0e3f7e9250eb05fa4feb9ccb7bbe39ca", - "sha256:53577cf57ba9d93b58ab41d45250277828ff83c5286dde14f855e4b17ec19976", - "sha256:681cb31e8631882804a6cc3c8cc8f54a74ff3a82261a78e50f20c5eec05ac855", - "sha256:6dfc2710f43dd1d66991a0f160d196356732ccc8aa9dbc6875aeba78388fa142", - "sha256:72218201b13d8169be5736417987e9a0a3b10d4349e40e4db7a6a5ac670c7ef2", - "sha256:7247fbcdbf7ab574eb70743461b3cfc14d9cfae3f27a9afb6ce14d87f67dd0b5", - "sha256:72651f4b4adf50201891580506c8cca465d94d38f26ed92abfc56440662c723c", - "sha256:87b3aaf12ad6a9b5570b12d2a4b8802757cb3588a903aafd3c25f07f9caf07e3", - "sha256:87c28b7b37617c5a01eb396487f7d3b61a453e1fa0475a175ab87712d6f5d52f", - "sha256:88efe627b628f36ef53f09abb218d4630f83d8ebde7028689439559475c43dae", - "sha256:89bfbca22266f12df7fb80092b7c876734751d02b93789580b68957ad4a8bf56", - "sha256:908a3caf348a672b28b8a06fe7b4a27c2fdcf7f873df671e4027d48bcd7f971f", - "sha256:9128e7bea85f3a3041306fa14a7aa82a24b47881918500e1b8396dd1c933b5a6", - "sha256:9737d6d688a15b8d5c0bfa909638b79261e195be817b9f1be79c722bbb23cd76", - "sha256:98a8305da158f46e99e7e51db49a2f8b5fcdd7683ea7083988ccb9c4450507a6", - "sha256:99285cd44c756f0900cbdb5fe75f567c0a76a273b7e0467f23cb76f47e60aac0", - "sha256:9ed568f8026ffeb00ce31e5351e0d09d704cc19a29549ba4da0ac145d2a26fdf", - "sha256:a006162035032021dfd00a879643dc06863dac275f9210d843278566c719eebc", - "sha256:a03cb336bc8d25a11ff33b94967478a9775b0d2b23b39e952d9cc6cb93b75d69", - "sha256:a863ceb67be163060d1099b7e89b6dd83d6dd50077c7ceae31ac844c4c2baff9", - "sha256:b82628eaf0a16c1f50e1c205fd1dd406d7874037dd84643da89e91b5043b5e82", - "sha256:bc6446a41fb7eeaf2c808bab961b9bac81db0f5de69eab74eebe1b8b072399f7", - "sha256:c42d290ed54096355838421cf9d2a56e150cb533304d2439ef1adf612a986eaf", - "sha256:c43879fe427ea6aa6e84dae9fbdc5aa14428a4cfe613fe0fee2cc004bf3f307c", - "sha256:c566cbdd1863ba3ccf838656a1403c3c81fdb57cbe3fdd3515be7c9616763d33", - "sha256:c5b7a0d7e6ca986de32b269b6dbbd5162c1a776ece72936f55decb4d1b197ee9", - "sha256:ca109fe9f74da4930590bb589eb8fdf80e5d19f5cd9f337815cac9309bbd0a76", - "sha256:d0260ba68f9bafd8775b2988b5aeace6e69a37593ec256e23e150c808160c05c", - "sha256:d2ce33501149b373118fcfec88a292a87ef0b333fb30c7c6aac72fe64700bdf6", - "sha256:d582ea8496e2a0e124e927a67dca55c8833f0dbfbc2c84aaf0e5949a2dd30c51", - "sha256:d68b9ab0a900582a345fb279675b0ad4fac07d6a8c2678f12910d55083b7240d", - "sha256:dbf1fa571db6006907aeaf6473580aaa76041f4f3cd1ff8a0039fd0f40b83f6d", - "sha256:e032437a7d2b89dab880c79379d88059cee8019da0ff475d924c4ccab52db88f", - "sha256:e0f5798f3ad60695465a093e3d002f609c41fef3dcb97fcefae355d24d3274cf", - "sha256:e756355704a2cf91a7f4a649aa0bbf3bbd263018b9ed08f60198c262f4ee24b6", - "sha256:e824b4b87bd88cbeb25c8babeadbbaaaf06f02bbb95a93462b7c6193a064974e", - "sha256:ea1171470b52487152ed8bf27713cc2480dc8b0cd58e282a1bff742541efbfb8", - "sha256:fa19aef44d5ed8f798a8136ff981aedfa508edac3b1bed481eca5dde5f14fd3d", - "sha256:fceb6ae5a149a42766efb8344b0df6cfb21b55c55f360170abaddb11d43af0f1" - ], - "version": "==3.10.0" + "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", + "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", + "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", + "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", + "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", + "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", + "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", + "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", + "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", + "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", + "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", + "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", + "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", + "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", + "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", + "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", + "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", + "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", + "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", + "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", + "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", + "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", + "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", + "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", + "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", + "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", + "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", + "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", + "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", + "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", + "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", + "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", + "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", + "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", + "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", + "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", + "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", + "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", + "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", + "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", + "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", + "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", + "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", + "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", + "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", + "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", + "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", + "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", + "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", + "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", + "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", + "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", + "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606" + ], + "version": "==3.10.1" }, "python-dateutil": { "hashes": [ @@ -240,18 +258,18 @@ }, "python-dotenv": { "hashes": [ - "sha256:debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", - "sha256:f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544" + "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", + "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" ], "index": "pypi", - "version": "==0.10.3" + "version": "==0.13.0" }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.13.0" + "version": "==1.15.0" }, "uvloop": { "hashes": [ @@ -271,43 +289,44 @@ }, "virtualenv": { "hashes": [ - "sha256:116655188441670978117d0ebb6451eb6a7526f9ae0796cc0dee6bd7356909b0", - "sha256:b57776b44f91511866594e477dd10e76a6eb44439cdd7f06dcd30ba4c5bd854f" + "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf", + "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70" ], - "version": "==16.7.8" + "version": "==20.0.21" }, "virtualenv-clone": { "hashes": [ - "sha256:532f789a5c88adf339506e3ca03326f20ee82fd08ee5586b44dc859b5b4468c5", - "sha256:c88ae171a11b087ea2513f260cdac9232461d8e9369bcd1dc143fc399d220557" + "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", + "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" ], - "version": "==0.5.3" + "version": "==0.5.4" }, "websockets": { "hashes": [ - "sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136", - "sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6", - "sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1", - "sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538", - "sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4", - "sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908", - "sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0", - "sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d", - "sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c", - "sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d", - "sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c", - "sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb", - "sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf", - "sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e", - "sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96", - "sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584", - "sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484", - "sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d", - "sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559", - "sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff", - "sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454" - ], - "version": "==6.0" + "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", + "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", + "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", + "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", + "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", + "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", + "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", + "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", + "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", + "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", + "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", + "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", + "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", + "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", + "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", + "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", + "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", + "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", + "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", + "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", + "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", + "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" + ], + "version": "==8.1" }, "yarl": { "hashes": [ @@ -330,22 +349,29 @@ "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2" ], "version": "==1.4.2" + }, + "zipp": { + "hashes": [ + "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", + "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" + ], + "version": "==3.1.0" } }, "develop": { "appdirs": { "hashes": [ - "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", - "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" ], - "version": "==1.4.3" + "version": "==1.4.4" }, "astroid": { "hashes": [ - "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", - "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42" + "sha256:4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1", + "sha256:d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38" ], - "version": "==2.3.3" + "version": "==2.4.1" }, "attrs": { "hashes": [ @@ -364,32 +390,32 @@ }, "black": { "hashes": [ - "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", - "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c" + "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", + "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539" ], "index": "pypi", - "version": "==19.3b0" + "version": "==19.10b0" }, "click": { "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "version": "==7.0" + "version": "==7.1.2" }, - "gitdb2": { + "gitdb": { "hashes": [ - "sha256:1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350", - "sha256:96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b" + "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", + "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], - "version": "==2.0.6" + "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:9c2398ffc3dcb3c40b27324b316f08a4f93ad646d5a6328cafbb871aa79f5e42", - "sha256:c155c6a2653593ccb300462f6ef533583a913e17857cfef8fc617c246b6dc245" + "sha256:e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a", + "sha256:ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac" ], - "version": "==3.0.5" + "version": "==3.1.3" }, "isort": { "hashes": [ @@ -431,96 +457,130 @@ ], "version": "==0.6.1" }, + "pathspec": { + "hashes": [ + "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", + "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061" + ], + "version": "==0.8.0" + }, "pbr": { "hashes": [ - "sha256:139d2625547dbfa5fb0b81daebb39601c478c21956dc57e2e07b74450a8c506b", - "sha256:61aa52a0f18b71c5cc58232d2cf8f8d09cd67fcad60b742a60124cb8d6951488" + "sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c", + "sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8" ], - "version": "==5.4.4" + "version": "==5.4.5" }, "pylint": { "hashes": [ - "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", - "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4" + "sha256:b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c", + "sha256:dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b" ], "index": "pypi", - "version": "==2.4.4" + "version": "==2.5.2" }, "pyyaml": { "hashes": [ - "sha256:0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc", - "sha256:2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803", - "sha256:35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc", - "sha256:38a4f0d114101c58c0f3a88aeaa44d63efd588845c5a2df5290b73db8f246d15", - "sha256:483eb6a33b671408c8529106df3707270bfacb2447bf8ad856a4b4f57f6e3075", - "sha256:4b6be5edb9f6bb73680f5bf4ee08ff25416d1400fbd4535fe0069b2994da07cd", - "sha256:7f38e35c00e160db592091751d385cd7b3046d6d51f578b29943225178257b31", - "sha256:8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f", - "sha256:c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c", - "sha256:e4c015484ff0ff197564917b4b4246ca03f411b9bd7f16e02a2f586eb48b6d04", - "sha256:ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4" - ], - "version": "==5.2" + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", + "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", + "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", + "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" + ], + "version": "==5.3.1" + }, + "regex": { + "hashes": [ + "sha256:150125da109fccdcc8fec3b0b386b2a5d6ca7cff076f8b622486d1ca868b0c10", + "sha256:163bc0805e46acfa098dfc8c0b07f371577d505f603e48afc425ff475cdac3a5", + "sha256:20c513893ff80bdbe4b4ce11ea2e93d49481f05b270595d82af69ffc402010a6", + "sha256:21fc17cb868c4264f0813f992f46f9ae6fc8c309d4741091de4153bd1f6a6176", + "sha256:2c928bc8e0c453d73dffa3193a6e37ee752ea36df0dd4601e21024d98274dfad", + "sha256:2d9beca70e36f9c60d679e108c5fe49f3d4da79d13a13f91e5e759443bd954f9", + "sha256:5735f26cacdb50b3d6d35ebf8fdeb504bd8b381e2d079d2d9f12ce534fc14ecd", + "sha256:6edc5c190248d3b612f2cca45448cf8ebc3621d41afcd1c5708853cbb1dbb3b3", + "sha256:7606dba82435429641efe4fbc580574942f89cf2b9c5c1f8bc1eab2bacbf7e8b", + "sha256:8d1ee3796795e609ef7a3a5a35eaf4728038d986aa12c06b3fd1b92ee81911f4", + "sha256:8d9bb2d90e23c51aacbc58c1a11320f49b335cd67a91986cdbebcc3e843e4de8", + "sha256:97d414c41f19fd2362e493810caa8445c05e0a2d63a14081c972aad66284a8d2", + "sha256:9e37502817225ee99d91d8418f5119e98c380b00e772d06915690c05290f32ee", + "sha256:af7209b2fcc79ee2b0ad4ea080d70bb748450ec4f282cc9e864861e469b1072e", + "sha256:c0849b0864ff451f04c8afb5fc28e9ed592262e03debdd227cf0f53e04a55dcd", + "sha256:c4ac9215650688e78dea29b46adbdafb7b85058eebe92ef6ea848e14466c915f", + "sha256:dcda6d4e1bbfc939b177c237aee41c9678eaaf71df482688f8986e8251e12345", + "sha256:dd8501b8d9ea1aba53c4bc7d47bc72933f9b4213d534cf400f16c1431f51c8ba", + "sha256:ec0e509ed1877ff1cbc6f0864689bb60384a303502c4d72d9a635f8a4676fd3f", + "sha256:f6c8c3f56fef719180464855346e6e80971b86dfd9e5a0e356664b5baca53072", + "sha256:ffd4f80602490a309064cf2b203e220d581c51660e01055c64bf5da450485ee6" + ], + "version": "==2020.6.7" }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.13.0" + "version": "==1.15.0" }, - "smmap2": { + "smmap": { "hashes": [ - "sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde", - "sha256:29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a" + "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", + "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], - "version": "==2.0.5" + "version": "==3.0.4" }, "stevedore": { "hashes": [ - "sha256:01d9f4beecf0fbd070ddb18e5efb10567801ba7ef3ddab0074f54e3cd4e91730", - "sha256:e0739f9739a681c7a1fda76a102b65295e96a144ccdb552f2ae03c5f0abe8a14" + "sha256:001e90cd704be6470d46cc9076434e2d0d566c1379187e7013eb296d3a6032d9", + "sha256:471c920412265cc809540ae6fb01f3f02aba89c79bbc7091372f4745a50f9691" ], - "version": "==1.31.0" + "version": "==2.0.0" }, "toml": { "hashes": [ - "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", - "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", + "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" ], - "version": "==0.10.0" + "version": "==0.10.1" }, "typed-ast": { "hashes": [ - "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", - "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", - "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", - "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", - "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", - "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", - "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", - "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", - "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", - "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", - "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", - "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", - "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", - "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", - "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", - "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", - "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", - "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", - "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", - "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", + "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", + "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", + "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", + "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", + "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", + "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", + "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", + "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", + "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", + "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", + "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", + "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", + "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", + "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", + "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", + "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", + "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", + "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", + "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", + "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" ], "markers": "implementation_name == 'cpython' and python_version < '3.8'", - "version": "==1.4.0" + "version": "==1.4.1" }, "wrapt": { "hashes": [ - "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" + "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" ], - "version": "==1.11.2" + "version": "==1.12.1" } } } diff --git a/poetry.lock b/poetry.lock index f4b23956b8..4aa8248546 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4,38 +4,35 @@ description = "Async http client/server framework (asyncio)" name = "aiohttp" optional = false python-versions = ">=3.5.3" -version = "3.5.4" +version = "3.6.2" [package.dependencies] async-timeout = ">=3.0,<4.0" attrs = ">=17.3.0" chardet = ">=2.0,<4.0" -multidict = ">=4.0,<5.0" +multidict = ">=4.5,<5.0" yarl = ">=1.0,<2.0" -[package.extras] -speedups = ["aiodns", "brotlipy", "cchardet"] - [[package]] category = "dev" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." name = "appdirs" optional = false python-versions = "*" -version = "1.4.3" +version = "1.4.4" [[package]] category = "dev" description = "An abstract syntax tree for Python with inference support." name = "astroid" optional = false -python-versions = ">=3.5.*" -version = "2.3.3" +python-versions = ">=3.5" +version = "2.4.1" [package.dependencies] lazy-object-proxy = ">=1.4.0,<1.5.0" six = ">=1.12,<2.0" -wrapt = ">=1.11.0,<1.12.0" +wrapt = ">=1.11,<2.0" [package.dependencies.typed-ast] python = "<3.8" @@ -57,12 +54,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "19.3.0" -[package.extras] -azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] -dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] -docs = ["sphinx", "zope.interface"] -tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] - [[package]] category = "dev" description = "Security oriented static analyser for python code." @@ -84,16 +75,16 @@ description = "The uncompromising code formatter." name = "black" optional = false python-versions = ">=3.6" -version = "19.3b0" +version = "19.10b0" [package.dependencies] appdirs = "*" attrs = ">=18.1.0" click = ">=6.5" +pathspec = ">=0.6,<1" +regex = "*" toml = ">=0.9.4" - -[package.extras] -d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +typed-ast = ">=1.4.0" [[package]] category = "main" @@ -109,7 +100,7 @@ description = "Composable command line interface toolkit" name = "click" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "7.1.1" +version = "7.1.2" [[package]] category = "main" @@ -121,19 +112,15 @@ version = "0.4.3" [[package]] category = "main" -description = "A python wrapper for the Discord API" +description = "A Python wrapper for the Discord API" name = "discord.py" optional = false python-versions = ">=3.5.3" -version = "1.2.5" +version = "1.3.3" [package.dependencies] -aiohttp = ">=3.3.0,<3.6.0" -websockets = ">=6.0,<7.0" - -[package.extras] -docs = ["sphinx (1.7.4)", "sphinxcontrib-asyncio", "sphinxcontrib-websupport"] -voice = ["PyNaCl (1.3.0)"] +aiohttp = ">=3.6.0,<3.7.0" +websockets = ">=6.0,<7.0 || >7.0,<8.0 || >8.0,<8.0.1 || >8.0.1,<9.0" [[package]] category = "main" @@ -143,10 +130,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "1.16.0" -[package.extras] -DNSSEC = ["pycryptodome", "ecdsa (>=0.13)"] -IDNA = ["idna (>=2.1)"] - [[package]] category = "main" description = "Emoji for Python" @@ -155,9 +138,6 @@ optional = false python-versions = "*" version = "0.5.4" -[package.extras] -dev = ["nose", "coverage", "coveralls"] - [[package]] category = "main" description = "Backport of the concurrent.futures package from Python 3.2" @@ -172,7 +152,7 @@ description = "Git Object Database" name = "gitdb" optional = false python-versions = ">=3.4" -version = "4.0.4" +version = "4.0.5" [package.dependencies] smmap = ">=3.0.1,<4" @@ -183,7 +163,7 @@ description = "Python Git Library" name = "gitpython" optional = false python-versions = ">=3.4" -version = "3.1.1" +version = "3.1.3" [package.dependencies] gitdb = ">=4.0.1,<5" @@ -215,12 +195,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "4.3.21" -[package.extras] -pipfile = ["pipreqs", "requirementslib"] -pyproject = ["toml"] -requirements = ["pipreqs", "pip-api"] -xdg_home = ["appdirs (>=1.4.0)"] - [[package]] category = "dev" description = "A fast and thorough lazy object proxy." @@ -255,7 +229,7 @@ description = "multidict implementation" name = "multidict" optional = false python-versions = ">=3.5" -version = "4.7.5" +version = "4.7.6" [[package]] category = "main" @@ -274,7 +248,15 @@ description = "Parse human-readable date/time text." name = "parsedatetime" optional = false python-versions = "*" -version = "2.5" +version = "2.6" + +[[package]] +category = "dev" +description = "Utility library for gitignore style pattern matching of file paths." +name = "pathspec" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.8.0" [[package]] category = "dev" @@ -290,13 +272,14 @@ description = "python code static checker" name = "pylint" optional = false python-versions = ">=3.5.*" -version = "2.4.4" +version = "2.5.2" [package.dependencies] -astroid = ">=2.3.0,<2.4" +astroid = ">=2.4.0,<=2.5" colorama = "*" isort = ">=4.2.5,<5" mccabe = ">=0.6,<0.7" +toml = ">=0.7.1" [[package]] category = "main" @@ -306,14 +289,6 @@ optional = true python-versions = "*" version = "3.10.1" -[package.extras] -encryption = ["pymongocrypt (<2.0.0)"] -gssapi = ["pykerberos"] -snappy = ["python-snappy"] -srv = ["dnspython (>=1.16.0,<1.17.0)"] -tls = ["ipaddress"] -zstd = ["zstandard"] - [[package]] category = "main" description = "Extensions to the standard Python datetime module" @@ -333,9 +308,6 @@ optional = false python-versions = "*" version = "0.10.5" -[package.extras] -cli = ["click (>=5.0)"] - [[package]] category = "dev" description = "YAML parser and emitter for Python" @@ -344,13 +316,21 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "5.3.1" +[[package]] +category = "dev" +description = "Alternative regular expression module, to replace re." +name = "regex" +optional = false +python-versions = "*" +version = "2020.6.7" + [[package]] category = "main" description = "Python 2 and 3 compatibility utilities" name = "six" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.14.0" +version = "1.15.0" [[package]] category = "dev" @@ -358,19 +338,18 @@ description = "A pure Python implementation of a sliding window memory map manag name = "smmap" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.0.2" +version = "3.0.4" [[package]] category = "dev" description = "Manage dynamic plugins for Python applications" name = "stevedore" optional = false -python-versions = "*" -version = "1.32.0" +python-versions = ">=3.6" +version = "2.0.0" [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" -six = ">=1.10.0" [[package]] category = "dev" @@ -378,12 +357,11 @@ description = "Python Library for Tom's Obvious, Minimal Language" name = "toml" optional = false python-versions = "*" -version = "0.10.0" +version = "0.10.1" [[package]] category = "dev" description = "a fork of Python 2 and 3 ast modules with type comment support" -marker = "implementation_name == \"cpython\" and python_version < \"3.8\"" name = "typed-ast" optional = false python-versions = "*" @@ -402,8 +380,8 @@ category = "main" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" name = "websockets" optional = false -python-versions = ">=3.4" -version = "6.0" +python-versions = ">=3.6.1" +version = "8.1" [[package]] category = "dev" @@ -411,7 +389,7 @@ description = "Module for decorators, wrappers and monkey patching." name = "wrapt" optional = false python-versions = "*" -version = "1.11.2" +version = "1.12.1" [[package]] category = "main" @@ -429,343 +407,49 @@ multidict = ">=4.0" mongodb = ["motor"] [metadata] -content-hash = "793f86eb19d73f473f00883384ec965876c3930f41f94a171d2d1bc38f66903b" +content-hash = "68d5c15e62c4bf5f65fd3b0a9a2586b15557f724c3de5b756534bacd52cbfe40" python-versions = "^3.7" -[metadata.files] -aiohttp = [ - {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_10_x86_64.whl", hash = "sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5"}, - {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed"}, - {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303"}, - {file = "aiohttp-3.5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10"}, - {file = "aiohttp-3.5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa"}, - {file = "aiohttp-3.5.4-cp35-cp35m-win32.whl", hash = "sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4"}, - {file = "aiohttp-3.5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72"}, - {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5"}, - {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12"}, - {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6"}, - {file = "aiohttp-3.5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6"}, - {file = "aiohttp-3.5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d"}, - {file = "aiohttp-3.5.4-cp36-cp36m-win32.whl", hash = "sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1"}, - {file = "aiohttp-3.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d"}, - {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300"}, - {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390"}, - {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366"}, - {file = "aiohttp-3.5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889"}, - {file = "aiohttp-3.5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55"}, - {file = "aiohttp-3.5.4-cp37-cp37m-win32.whl", hash = "sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc"}, - {file = "aiohttp-3.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939"}, - {file = "aiohttp-3.5.4.tar.gz", hash = "sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf"}, -] -appdirs = [ - {file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"}, - {file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"}, -] -astroid = [ - {file = "astroid-2.3.3-py3-none-any.whl", hash = "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"}, - {file = "astroid-2.3.3.tar.gz", hash = "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a"}, -] -async-timeout = [ - {file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"}, - {file = "async_timeout-3.0.1-py3-none-any.whl", hash = "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"}, -] -attrs = [ - {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, - {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, -] -bandit = [ - {file = "bandit-1.6.2-py2.py3-none-any.whl", hash = "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952"}, - {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"}, -] -black = [ - {file = "black-19.3b0-py36-none-any.whl", hash = "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf"}, - {file = "black-19.3b0.tar.gz", hash = "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"}, -] -chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, -] -click = [ - {file = "click-7.1.1-py2.py3-none-any.whl", hash = "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"}, - {file = "click-7.1.1.tar.gz", hash = "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc"}, -] -colorama = [ - {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, - {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, -] -"discord.py" = [ - {file = "discord.py-1.2.5-py3-none-any.whl", hash = "sha256:7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d"}, -] -dnspython = [ - {file = "dnspython-1.16.0-py2.py3-none-any.whl", hash = "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"}, - {file = "dnspython-1.16.0.zip", hash = "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01"}, -] -emoji = [ - {file = "emoji-0.5.4.tar.gz", hash = "sha256:60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"}, -] -futures = [ - {file = "futures-3.1.1-py2-none-any.whl", hash = "sha256:c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"}, - {file = "futures-3.1.1-py3-none-any.whl", hash = "sha256:3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b"}, - {file = "futures-3.1.1.tar.gz", hash = "sha256:51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd"}, -] -gitdb = [ - {file = "gitdb-4.0.4-py3-none-any.whl", hash = "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a"}, - {file = "gitdb-4.0.4.tar.gz", hash = "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5"}, -] -gitpython = [ - {file = "GitPython-3.1.1-py3-none-any.whl", hash = "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d"}, - {file = "GitPython-3.1.1.tar.gz", hash = "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74"}, -] -idna = [ - {file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"}, - {file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"}, -] -isodate = [ - {file = "isodate-0.6.0-py2.py3-none-any.whl", hash = "sha256:aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"}, - {file = "isodate-0.6.0.tar.gz", hash = "sha256:2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8"}, -] -isort = [ - {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"}, - {file = "isort-4.3.21.tar.gz", hash = "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1"}, -] -lazy-object-proxy = [ - {file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27m-macosx_10_13_x86_64.whl", hash = "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win32.whl", hash = "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d"}, - {file = "lazy_object_proxy-1.4.3-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a"}, - {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win32.whl", hash = "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e"}, - {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win_amd64.whl", hash = "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357"}, - {file = "lazy_object_proxy-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50"}, - {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db"}, - {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449"}, - {file = "lazy_object_proxy-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156"}, - {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531"}, - {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea"}, - {file = "lazy_object_proxy-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62"}, - {file = "lazy_object_proxy-1.4.3-cp38-cp38-win32.whl", hash = "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd"}, - {file = "lazy_object_proxy-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239"}, -] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] -motor = [ - {file = "motor-2.1.0-py2-none-any.whl", hash = "sha256:599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909"}, - {file = "motor-2.1.0-py3-none-any.whl", hash = "sha256:97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"}, - {file = "motor-2.1.0.tar.gz", hash = "sha256:756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4"}, -] -multidict = [ - {file = "multidict-4.7.5-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:fc3b4adc2ee8474cb3cd2a155305d5f8eda0a9c91320f83e55748e1fcb68f8e3"}, - {file = "multidict-4.7.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:42f56542166040b4474c0c608ed051732033cd821126493cf25b6c276df7dd35"}, - {file = "multidict-4.7.5-cp35-cp35m-win32.whl", hash = "sha256:7774e9f6c9af3f12f296131453f7b81dabb7ebdb948483362f5afcaac8a826f1"}, - {file = "multidict-4.7.5-cp35-cp35m-win_amd64.whl", hash = "sha256:c2c37185fb0af79d5c117b8d2764f4321eeb12ba8c141a95d0aa8c2c1d0a11dd"}, - {file = "multidict-4.7.5-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:e439c9a10a95cb32abd708bb8be83b2134fa93790a4fb0535ca36db3dda94d20"}, - {file = "multidict-4.7.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:85cb26c38c96f76b7ff38b86c9d560dea10cf3459bb5f4caf72fc1bb932c7136"}, - {file = "multidict-4.7.5-cp36-cp36m-win32.whl", hash = "sha256:620b37c3fea181dab09267cd5a84b0f23fa043beb8bc50d8474dd9694de1fa6e"}, - {file = "multidict-4.7.5-cp36-cp36m-win_amd64.whl", hash = "sha256:6e6fef114741c4d7ca46da8449038ec8b1e880bbe68674c01ceeb1ac8a648e78"}, - {file = "multidict-4.7.5-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a326f4240123a2ac66bb163eeba99578e9d63a8654a59f4688a79198f9aa10f8"}, - {file = "multidict-4.7.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dc561313279f9d05a3d0ffa89cd15ae477528ea37aa9795c4654588a3287a9ab"}, - {file = "multidict-4.7.5-cp37-cp37m-win32.whl", hash = "sha256:4b7df040fb5fe826d689204f9b544af469593fb3ff3a069a6ad3409f742f5928"}, - {file = "multidict-4.7.5-cp37-cp37m-win_amd64.whl", hash = "sha256:317f96bc0950d249e96d8d29ab556d01dd38888fbe68324f46fd834b430169f1"}, - {file = "multidict-4.7.5-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:b51249fdd2923739cd3efc95a3d6c363b67bbf779208e9f37fd5e68540d1a4d4"}, - {file = "multidict-4.7.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ae402f43604e3b2bc41e8ea8b8526c7fa7139ed76b0d64fc48e28125925275b2"}, - {file = "multidict-4.7.5-cp38-cp38-win32.whl", hash = "sha256:bb519becc46275c594410c6c28a8a0adc66fe24fef154a9addea54c1adb006f5"}, - {file = "multidict-4.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:544fae9261232a97102e27a926019100a9db75bec7b37feedd74b3aa82f29969"}, - {file = "multidict-4.7.5.tar.gz", hash = "sha256:aee283c49601fa4c13adc64c09c978838a7e812f85377ae130a24d7198c0331e"}, -] -natural = [ - {file = "natural-0.2.0.tar.gz", hash = "sha256:18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"}, -] -parsedatetime = [ - {file = "parsedatetime-2.5-py2-none-any.whl", hash = "sha256:3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1"}, - {file = "parsedatetime-2.5.tar.gz", hash = "sha256:d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667"}, -] -pbr = [ - {file = "pbr-5.4.5-py2.py3-none-any.whl", hash = "sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"}, - {file = "pbr-5.4.5.tar.gz", hash = "sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c"}, -] -pylint = [ - {file = "pylint-2.4.4-py3-none-any.whl", hash = "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"}, - {file = "pylint-2.4.4.tar.gz", hash = "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd"}, -] -pymongo = [ - {file = "pymongo-3.10.1-cp27-cp27m-macosx_10_14_intel.whl", hash = "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee"}, - {file = "pymongo-3.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed"}, - {file = "pymongo-3.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6"}, - {file = "pymongo-3.10.1-cp27-cp27m-win32.whl", hash = "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5"}, - {file = "pymongo-3.10.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe"}, - {file = "pymongo-3.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc"}, - {file = "pymongo-3.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764"}, - {file = "pymongo-3.10.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372"}, - {file = "pymongo-3.10.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32"}, - {file = "pymongo-3.10.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc"}, - {file = "pymongo-3.10.1-cp34-cp34m-win32.whl", hash = "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a"}, - {file = "pymongo-3.10.1-cp34-cp34m-win_amd64.whl", hash = "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae"}, - {file = "pymongo-3.10.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_ppc64le.whl", hash = "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_s390x.whl", hash = "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d"}, - {file = "pymongo-3.10.1-cp35-cp35m-win32.whl", hash = "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57"}, - {file = "pymongo-3.10.1-cp35-cp35m-win_amd64.whl", hash = "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70"}, - {file = "pymongo-3.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73"}, - {file = "pymongo-3.10.1-cp36-cp36m-win32.whl", hash = "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33"}, - {file = "pymongo-3.10.1-cp36-cp36m-win_amd64.whl", hash = "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6"}, - {file = "pymongo-3.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951"}, - {file = "pymongo-3.10.1-cp37-cp37m-win32.whl", hash = "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39"}, - {file = "pymongo-3.10.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b"}, - {file = "pymongo-3.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be"}, - {file = "pymongo-3.10.1-cp38-cp38-win32.whl", hash = "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f"}, - {file = "pymongo-3.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac"}, - {file = "pymongo-3.10.1-py2.7-macosx-10.14-intel.egg", hash = "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a"}, - {file = "pymongo-3.10.1-py2.7-win-amd64.egg", hash = "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012"}, - {file = "pymongo-3.10.1-py2.7-win32.egg", hash = "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a"}, - {file = "pymongo-3.10.1.tar.gz", hash = "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa"}, -] -python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, -] -python-dotenv = [ - {file = "python-dotenv-0.10.5.tar.gz", hash = "sha256:f254bfd0c970d64ccbb6c9ebef3667ab301a71473569c991253a481f1c98dddc"}, - {file = "python_dotenv-0.10.5-py2.py3-none-any.whl", hash = "sha256:440c7c23d53b7d352f9c94d6f70860242c2f071cf5c029dd661ccb22d64ae42b"}, -] -pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, -] -six = [ - {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, - {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, -] -smmap = [ - {file = "smmap-3.0.2-py2.py3-none-any.whl", hash = "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1"}, - {file = "smmap-3.0.2.tar.gz", hash = "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911"}, -] -stevedore = [ - {file = "stevedore-1.32.0-py2.py3-none-any.whl", hash = "sha256:a4e7dc759fb0f2e3e2f7d8ffe2358c19d45b9b8297f393ef1256858d82f69c9b"}, - {file = "stevedore-1.32.0.tar.gz", hash = "sha256:18afaf1d623af5950cc0f7e75e70f917784c73b652a34a12d90b309451b5500b"}, -] -toml = [ - {file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"}, - {file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"}, - {file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"}, -] -typed-ast = [ - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, - {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, - {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, - {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, - {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, - {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, - {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, -] -uvloop = [ - {file = "uvloop-0.14.0-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd"}, - {file = "uvloop-0.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726"}, - {file = "uvloop-0.14.0-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7"}, - {file = "uvloop-0.14.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"}, - {file = "uvloop-0.14.0-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891"}, - {file = "uvloop-0.14.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95"}, - {file = "uvloop-0.14.0-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5"}, - {file = "uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09"}, - {file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"}, -] -websockets = [ - {file = "websockets-6.0-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d"}, - {file = "websockets-6.0-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484"}, - {file = "websockets-6.0-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e"}, - {file = "websockets-6.0-cp34-cp34m-win32.whl", hash = "sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"}, - {file = "websockets-6.0-cp34-cp34m-win_amd64.whl", hash = "sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96"}, - {file = "websockets-6.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538"}, - {file = "websockets-6.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0"}, - {file = "websockets-6.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1"}, - {file = "websockets-6.0-cp35-cp35m-win32.whl", hash = "sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d"}, - {file = "websockets-6.0-cp35-cp35m-win_amd64.whl", hash = "sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6"}, - {file = "websockets-6.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf"}, - {file = "websockets-6.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d"}, - {file = "websockets-6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb"}, - {file = "websockets-6.0-cp36-cp36m-win32.whl", hash = "sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c"}, - {file = "websockets-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff"}, - {file = "websockets-6.0-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908"}, - {file = "websockets-6.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559"}, - {file = "websockets-6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4"}, - {file = "websockets-6.0-cp37-cp37m-win32.whl", hash = "sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136"}, - {file = "websockets-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584"}, - {file = "websockets-6.0.tar.gz", hash = "sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c"}, -] -wrapt = [ - {file = "wrapt-1.11.2.tar.gz", hash = "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"}, -] -yarl = [ - {file = "yarl-1.4.2-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b"}, - {file = "yarl-1.4.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1"}, - {file = "yarl-1.4.2-cp35-cp35m-win32.whl", hash = "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080"}, - {file = "yarl-1.4.2-cp35-cp35m-win_amd64.whl", hash = "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a"}, - {file = "yarl-1.4.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f"}, - {file = "yarl-1.4.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea"}, - {file = "yarl-1.4.2-cp36-cp36m-win32.whl", hash = "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb"}, - {file = "yarl-1.4.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70"}, - {file = "yarl-1.4.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d"}, - {file = "yarl-1.4.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce"}, - {file = "yarl-1.4.2-cp37-cp37m-win32.whl", hash = "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"}, - {file = "yarl-1.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce"}, - {file = "yarl-1.4.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b"}, - {file = "yarl-1.4.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae"}, - {file = "yarl-1.4.2-cp38-cp38-win32.whl", hash = "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462"}, - {file = "yarl-1.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6"}, - {file = "yarl-1.4.2.tar.gz", hash = "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b"}, -] +[metadata.hashes] +aiohttp = ["1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", "259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", "2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", "32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", "344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", "460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", "4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", "50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", "6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", "65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", "ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", "b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965"] +appdirs = ["7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", "a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"] +astroid = ["4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1", "d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38"] +async-timeout = ["0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"] +attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] +bandit = ["336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952", "41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"] +black = ["1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", "c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"] +chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] +click = ["d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"] +colorama = ["7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", "e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"] +"discord.py" = ["406871b06d86c3dc49fba63238519f28628dac946fef8a0e22988ff58ec05580", "ad00e34c72d2faa8db2157b651d05f3c415d7d05078e7e41dc9e8dc240051beb"] +dnspython = ["36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", "f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"] +emoji = ["60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"] +futures = ["3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b", "51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd", "c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"] +gitdb = ["91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"] +gitpython = ["e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a", "ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac"] +idna = ["7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", "a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"] +isodate = ["2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", "aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"] +isort = ["54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", "6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"] +lazy-object-proxy = ["0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", "194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", "1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", "4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", "48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", "5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", "59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", "8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", "9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", "9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", "97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", "9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", "a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", "a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", "ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", "cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", "d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", "d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", "eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", "efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"] +mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] +motor = ["599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", "756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", "97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"] +multidict = ["1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", "275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", "3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", "4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", "5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", "51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", "5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", "6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", "7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", "9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", "c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", "d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", "e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", "f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", "fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", "fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d"] +natural = ["18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"] +parsedatetime = ["4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455", "cb96edd7016872f58479e35879294258c71437195760746faffedb692aef000b"] +pathspec = ["7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", "da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"] +pbr = ["07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c", "579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"] +pylint = ["b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c", "dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b"] +pymongo = ["01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", "0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", "1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", "18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", "19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", "20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", "26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", "26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", "2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", "2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", "316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", "31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", "334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", "358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", "3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", "444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", "47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", "4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", "4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", "53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", "568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", "56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", "5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", "61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", "619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", "6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", "63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", "6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", "7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", "7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", "80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", "95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", "993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", "9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", "a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", "a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", "a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", "a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", "a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", "ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", "ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", "b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", "b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", "bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", "bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", "c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", "c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", "c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", "c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", "da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", "dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", "e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", "e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", "e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", "f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", "f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606"] +python-dateutil = ["73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"] +python-dotenv = ["440c7c23d53b7d352f9c94d6f70860242c2f071cf5c029dd661ccb22d64ae42b", "f254bfd0c970d64ccbb6c9ebef3667ab301a71473569c991253a481f1c98dddc"] +pyyaml = ["06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", "240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", "4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", "69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", "73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", "74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", "7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", "95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", "b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", "cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", "d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"] +regex = ["150125da109fccdcc8fec3b0b386b2a5d6ca7cff076f8b622486d1ca868b0c10", "163bc0805e46acfa098dfc8c0b07f371577d505f603e48afc425ff475cdac3a5", "20c513893ff80bdbe4b4ce11ea2e93d49481f05b270595d82af69ffc402010a6", "21fc17cb868c4264f0813f992f46f9ae6fc8c309d4741091de4153bd1f6a6176", "2c928bc8e0c453d73dffa3193a6e37ee752ea36df0dd4601e21024d98274dfad", "2d9beca70e36f9c60d679e108c5fe49f3d4da79d13a13f91e5e759443bd954f9", "5735f26cacdb50b3d6d35ebf8fdeb504bd8b381e2d079d2d9f12ce534fc14ecd", "6edc5c190248d3b612f2cca45448cf8ebc3621d41afcd1c5708853cbb1dbb3b3", "7606dba82435429641efe4fbc580574942f89cf2b9c5c1f8bc1eab2bacbf7e8b", "8d1ee3796795e609ef7a3a5a35eaf4728038d986aa12c06b3fd1b92ee81911f4", "8d9bb2d90e23c51aacbc58c1a11320f49b335cd67a91986cdbebcc3e843e4de8", "97d414c41f19fd2362e493810caa8445c05e0a2d63a14081c972aad66284a8d2", "9e37502817225ee99d91d8418f5119e98c380b00e772d06915690c05290f32ee", "af7209b2fcc79ee2b0ad4ea080d70bb748450ec4f282cc9e864861e469b1072e", "c0849b0864ff451f04c8afb5fc28e9ed592262e03debdd227cf0f53e04a55dcd", "c4ac9215650688e78dea29b46adbdafb7b85058eebe92ef6ea848e14466c915f", "dcda6d4e1bbfc939b177c237aee41c9678eaaf71df482688f8986e8251e12345", "dd8501b8d9ea1aba53c4bc7d47bc72933f9b4213d534cf400f16c1431f51c8ba", "ec0e509ed1877ff1cbc6f0864689bb60384a303502c4d72d9a635f8a4676fd3f", "f6c8c3f56fef719180464855346e6e80971b86dfd9e5a0e356664b5baca53072", "ffd4f80602490a309064cf2b203e220d581c51660e01055c64bf5da450485ee6"] +six = ["30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"] +smmap = ["54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"] +stevedore = ["001e90cd704be6470d46cc9076434e2d0d566c1379187e7013eb296d3a6032d9", "471c920412265cc809540ae6fb01f3f02aba89c79bbc7091372f4745a50f9691"] +toml = ["926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", "bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"] +typed-ast = ["0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", "0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", "249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", "24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", "269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", "4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", "498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", "4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", "6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", "715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", "73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", "8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", "8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", "aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", "bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", "c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", "d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", "d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", "d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", "fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", "fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"] +uvloop = ["08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", "123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", "4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", "4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", "afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", "b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", "bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", "e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"] +websockets = ["0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", "1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", "20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", "295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", "2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", "3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", "3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", "3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", "4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", "5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", "5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", "751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", "7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", "965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", "9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", "9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", "c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", "c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", "ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", "d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", "e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", "f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"] +wrapt = ["b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"] +yarl = ["0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", "0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", "2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", "25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", "26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", "308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", "3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", "58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", "5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", "6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", "944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", "a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", "a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", "c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", "c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", "d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", "e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"] diff --git a/pyproject.toml b/pyproject.toml index a114573201..6cedd6065c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,10 +36,10 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "=1.2.5" -uvloop = "^0.14.0" +"discord.py" = "=1.3.3" +uvloop = {version=">=0.12.0", sys_platform = "!= 'win32'"} python-dotenv = "^0.10.3" -parsedatetime = "^2.5" +parsedatetime = "^2.6" dnspython = "^1.16" isodate = "^0.6.0" natural = "^0.2.0" @@ -47,10 +47,10 @@ motor = {version = "^2.1", optional = true} emoji = "^0.5.4" python-dateutil = "^2.8" colorama = "^0.4.3" -aiohttp = "<3.6.0,>=3.3.0" +aiohttp = ">=3.6.0,<3.7.0" [tool.poetry.dev-dependencies] -black = {version = "=19.3b0", allows-prereleases = true} +black = {version = "=19.10b0", allows-prereleases = true} pylint = "^2.4" bandit = "^1.6" diff --git a/requirements.min.txt b/requirements.min.txt index dded194188..e3ba980fc1 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -1,24 +1,24 @@ -# Generated as of October, 2019 +# Generated as of June, 2020 # This is the bare minimum requirements.txt for running Modmail. # To install requirements.txt run: pip install -r requirements.min.txt -aiohttp==3.5.4 +aiohttp==3.6.2 async-timeout==3.0.1 attrs==19.3.0 chardet==3.0.4 -discord.py==1.2.5 +discord.py==1.3.3 dnspython==1.16.0 emoji==0.5.4 -future==0.18.1 -idna==2.8 +future==0.18.2 +idna==2.9 isodate==0.6.0 -motor==2.0.0 -multidict==4.5.2 +motor==2.1.0 +multidict==4.7.6 natural==0.2.0 -parsedatetime==2.4 -pymongo==3.9.0 -python-dateutil==2.8.0 -python-dotenv==0.10.3 -six==1.12.0 -websockets==6.0 -yarl==1.3.0 +parsedatetime==2.6 +pymongo==3.10.1 +python-dateutil==2.8.1 +python-dotenv==0.13.0 +six==1.15.0 +websockets==8.1 +yarl==1.4.2 diff --git a/runtime.txt b/runtime.txt index 6919bf9ede..05802392e0 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.6 +python-3.7.7 \ No newline at end of file From fd61637a92ad556db121768def88a0654e3943e8 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Jun 2020 00:22:36 -0700 Subject: [PATCH 030/705] Implement teams in metadata --- bot.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index 694f860cf1..8016a65ec6 100644 --- a/bot.py +++ b/bot.py @@ -1196,10 +1196,9 @@ async def validate_database_connection(self): logger.line("debug") async def post_metadata(self): - owner = (await self.application_info()).owner + info = await self.application_info() + data = { - "owner_name": str(owner), - "owner_id": owner.id, "bot_id": self.user.id, "bot_name": str(self.user), "avatar_url": str(self.user.avatar_url), @@ -1213,6 +1212,19 @@ async def post_metadata(self): "last_updated": str(datetime.utcnow()), } + if discord.AppInfo.team is not None: + data.update( + { + "owner_name": info.team.owner.name + if info.team.owner is not None + else "No Owner", + "owner_id": info.team.owner_id, + "team": True, + } + ) + else: + data.update({"owner_name": info.owner.name, "owner_id": info.owner.id, "team": False}) + async with self.session.post("https://api.logviewer.tech/metadata", json=data): logger.debug("Uploading metadata to Modmail server.") From 67ef0a34d701bae662a5ef02d1b9f40f652cb18e Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Jun 2020 05:16:01 -0700 Subject: [PATCH 031/705] Use event_type for raw reaction update, rename owner_ids -> bot_owner_ids to prevent overriding new owner_ids attribute for teams --- bot.py | 17 +++++++++-------- cogs/modmail.py | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index 8016a65ec6..88b28ec61e 100644 --- a/bot.py +++ b/bot.py @@ -180,7 +180,7 @@ def run(self, *args, **kwargs): logger.error(" - Shutting down bot - ") @property - def owner_ids(self): + def bot_owner_ids(self): owner_ids = self.config["owners"] if owner_ids is not None: owner_ids = set(map(int, str(owner_ids).split(","))) @@ -192,7 +192,7 @@ def owner_ids(self): return owner_ids async def is_owner(self, user: discord.User) -> bool: - if user.id in self.owner_ids: + if user.id in self.bot_owner_ids: return True return await super().is_owner(user) @@ -416,7 +416,8 @@ async def on_ready(self): logger.info("Logged in as: %s", self.user) logger.info("Bot ID: %s", self.user.id) owners = ", ".join( - getattr(self.get_user(owner_id), "name", str(owner_id)) for owner_id in self.owner_ids + getattr(self.get_user(owner_id), "name", str(owner_id)) + for owner_id in self.bot_owner_ids ) logger.info("Owners: %s", owners) logger.info("Prefix: %s", self.prefix) @@ -935,7 +936,7 @@ async def on_typing(self, channel, user, _): return await thread.recipient.trigger_typing() - async def handle_reaction_events(self, payload, *, add): + async def handle_reaction_events(self, payload): user = self.get_user(payload.user_id) if user.bot: return @@ -961,7 +962,7 @@ async def handle_reaction_events(self, payload, *, add): if not thread: return if ( - add + payload.event_type == "REACTION_ADD" and message.embeds and str(reaction) == str(close_emoji) and self.config.get("recipient_thread_close") @@ -992,7 +993,7 @@ async def handle_reaction_events(self, payload, *, add): logger.warning("Failed to find linked message for reactions: %s", e) return - if add: + if payload.event_type == "REACTION_ADD": if await self.add_reaction(linked_message, reaction): await self.add_reaction(message, reaction) else: @@ -1003,10 +1004,10 @@ async def handle_reaction_events(self, payload, *, add): logger.warning("Failed to remove reaction: %s", e) async def on_raw_reaction_add(self, payload): - await self.handle_reaction_events(payload, add=True) + await self.handle_reaction_events(payload) async def on_raw_reaction_remove(self, payload): - await self.handle_reaction_events(payload, add=False) + await self.handle_reaction_events(payload) async def on_guild_channel_delete(self, channel): if channel.guild != self.modmail_guild: diff --git a/cogs/modmail.py b/cogs/modmail.py index 3b9c591294..acbcd74722 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -120,8 +120,8 @@ async def setup(self, ctx): if not self.bot.config["command_permissions"] and not self.bot.config["level_permissions"]: await self.bot.update_perms(PermissionLevel.REGULAR, -1) - for owner_ids in self.bot.owner_ids: - await self.bot.update_perms(PermissionLevel.OWNER, owner_ids) + for owner_id in self.bot.bot_owner_ids: + await self.bot.update_perms(PermissionLevel.OWNER, owner_id) @commands.group(aliases=["snippets"], invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) From 48314e16185701444d5a9616497760fe000cdcba Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Jun 2020 05:30:32 -0700 Subject: [PATCH 032/705] Channel delete no longer show warnings and threads get closed properly now --- bot.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/bot.py b/bot.py index 88b28ec61e..57938637dd 100644 --- a/bot.py +++ b/bot.py @@ -1013,19 +1013,6 @@ async def on_guild_channel_delete(self, channel): if channel.guild != self.modmail_guild: return - try: - audit_logs = self.modmail_guild.audit_logs() - entry = await audit_logs.find(lambda a: a.target == channel) - mod = entry.user - except AttributeError as e: - # discord.py broken implementation with discord API - # TODO: waiting for dpy - logger.warning("Failed to retrieve audit log: %s.", e) - return - - if mod == self.user: - return - if isinstance(channel, discord.CategoryChannel): if self.main_category == channel: logger.debug("Main category was deleted.") @@ -1042,6 +1029,19 @@ async def on_guild_channel_delete(self, channel): await self.config.update() return + audit_logs = self.modmail_guild.audit_logs() + entry = await audit_logs.find( + lambda a: a.target == channel and a.action == discord.AuditLogAction.channel_delete + ) + + if entry is None: + logger.debug("Cannot find the audit log entry for channel delete of %d.", channel.id) + return + + mod = entry.user + if mod == self.user: + return + thread = await self.threads.find(channel=channel) if thread and thread.channel == channel: logger.debug("Manually closed channel %s.", channel.name) From 04e15ef2fe041cbad72a80464414a285e158f1aa Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Jun 2020 05:49:33 -0700 Subject: [PATCH 033/705] Use auditlog for message delete event to decrease error rate --- bot.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/bot.py b/bot.py index 57938637dd..a615554b4e 100644 --- a/bot.py +++ b/bot.py @@ -1069,8 +1069,10 @@ async def on_member_join(self, member): async def on_message_delete(self, message): """Support for deleting linked messages""" - # TODO: use audit log to check if modmail deleted the message + if isinstance(message.channel, discord.DMChannel): + if message.author == self.user: + return thread = await self.threads.find(recipient=message.author) if not thread: return @@ -1078,7 +1080,7 @@ async def on_message_delete(self, message): message = await thread.find_linked_message_from_dm(message) except ValueError as e: if str(e) != "Thread channel message not found.": - logger.warning("Failed to find linked message to delete: %s", e) + logger.debug("Failed to find linked message to delete: %s", e) return embed = message.embeds[0] embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=embed.footer.icon_url) @@ -1088,14 +1090,34 @@ async def on_message_delete(self, message): thread = await self.threads.find(channel=message.channel) if not thread: return + + audit_logs = self.modmail_guild.audit_logs() + entry = await audit_logs.find( + lambda a: a.target == message and a.action == discord.AuditLogAction.message_delete + ) + + if entry is None: + logger.debug("Cannot find the audit log entry for message delete of %d.", message.id) + elif entry.user == self.user: + return + try: await thread.delete_message(message, note=False) + embed = discord.Embed( + description="Successfully deleted message.", color=self.main_color + ) except ValueError as e: if str(e) not in {"DM message not found.", "Malformed thread message."}: - logger.warning("Failed to find linked message to delete: %s", e) - return + logger.debug("Failed to find linked message to delete: %s", e) + embed = discord.Embed( + description="Failed to delete message.", color=self.error_color + ) + else: + return except discord.NotFound: return + embed.set_footer(text=f"Message ID: {message.id} from {message.author}.") + return await message.channel.send(embed=embed) async def on_bulk_message_delete(self, messages): await discord.utils.async_all(self.on_message_delete(msg) for msg in messages) From f98354ca3075a2bfd7b4d25fba81f08abc4af297 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Jun 2020 06:34:00 -0700 Subject: [PATCH 034/705] Slight error fix --- bot.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/bot.py b/bot.py index a615554b4e..4b6033c40a 100644 --- a/bot.py +++ b/bot.py @@ -499,6 +499,17 @@ async def on_ready(self): self.metadata_loop.before_loop(self.before_post_metadata) self.metadata_loop.start() + other_guilds = [ + guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild} + ] + if any(other_guilds): + logger.warning( + "The bot is in more servers other than the main and staff server." + "This may cause data compromise (%s).", + ", ".join(guild.name for guild in other_guilds), + ) + logger.warning("If the external servers are valid, you may ignore this message.") + async def convert_emoji(self, name: str) -> str: ctx = SimpleNamespace(bot=self, guild=self.modmail_guild) converter = commands.EmojiConverter() @@ -1029,10 +1040,10 @@ async def on_guild_channel_delete(self, channel): await self.config.update() return - audit_logs = self.modmail_guild.audit_logs() - entry = await audit_logs.find( - lambda a: a.target == channel and a.action == discord.AuditLogAction.channel_delete + audit_logs = self.modmail_guild.audit_logs( + limit=10, action=discord.AuditLogAction.channel_delete ) + entry = await audit_logs.find(lambda a: int(a.target.id) == channel.id) if entry is None: logger.debug("Cannot find the audit log entry for channel delete of %d.", channel.id) @@ -1070,6 +1081,9 @@ async def on_member_join(self, member): async def on_message_delete(self, message): """Support for deleting linked messages""" + if message.is_system(): + return + if isinstance(message.channel, discord.DMChannel): if message.author == self.user: return @@ -1087,18 +1101,20 @@ async def on_message_delete(self, message): await message.edit(embed=embed) return + if message.author != self.user: + return + thread = await self.threads.find(channel=message.channel) if not thread: return - audit_logs = self.modmail_guild.audit_logs() - entry = await audit_logs.find( - lambda a: a.target == message and a.action == discord.AuditLogAction.message_delete + audit_logs = self.modmail_guild.audit_logs( + limit=10, action=discord.AuditLogAction.message_delete ) + entry = await audit_logs.find(lambda a: a.target == self.user) + if entry is None: - logger.debug("Cannot find the audit log entry for message delete of %d.", message.id) - elif entry.user == self.user: return try: @@ -1235,7 +1251,7 @@ async def post_metadata(self): "last_updated": str(datetime.utcnow()), } - if discord.AppInfo.team is not None: + if info.team is not None: data.update( { "owner_name": info.team.owner.name From 9a92a7418f619deebceb96a9a62055fb0ecd2c38 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Jun 2020 06:39:40 -0700 Subject: [PATCH 035/705] Add skeleton for dpy dump update --- CHANGELOG.md | 9 +++++++++ bot.py | 2 +- pyproject.toml | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dcb9acbcd..3b5fcb7515 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +# v3.5.0dev1 + +### Changed + +- Bump discord.py version to v1.3.3. +- Renamed `bot.owner_ids` to `bot.bot_owner_ids` as the attribute is now defined interally for team support. +- Deleting channel manually will now close the thread. +- Deleting messages will no longer cause the bot to produce warnings. + # v3.4.1 ### Fixed diff --git a/bot.py b/bot.py index 4b6033c40a..9b575bbdce 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.4.1" +__version__ = "3.5.0-dev1" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 6cedd6065c..eb11a19cb7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.4.1' +version = '3.5.0-dev1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 6bf3064c169c3aa7c5db9352d163fe40c0dbc476 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Jun 2020 16:40:06 -0700 Subject: [PATCH 036/705] disable eval config --- CHANGELOG.md | 7 ++++++- bot.py | 6 +++++- cogs/utility.py | 3 +++ core/config.py | 6 ++++-- pyproject.toml | 2 +- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b5fcb7515..191ed404a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,12 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.5.0dev1 +# v3.5.0dev2 + +### Added + +- A confirmation when you manually delete a thread message embed. +- Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. (GH #2803) ### Changed diff --git a/bot.py b/bot.py index 9b575bbdce..d84e3e1cc9 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.5.0-dev1" +__version__ = "3.5.0-dev2" import asyncio @@ -1200,6 +1200,10 @@ async def on_command_error(self, context, exception): corrected_permission_level.name, ) logger.warning("CheckFailure: %s", exception) + elif isinstance(exception, commands.DisabledCommand): + logger.info( + "DisabledCommand: %s is trying to run eval but it's disabled", context.author.name + ) else: logger.error("Unexpected exception:", exc_info=exception) diff --git a/cogs/utility.py b/cogs/utility.py index f8460c7d52..bd04bd6a09 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -239,6 +239,9 @@ def __init__(self, bot): ) self.bot.help_command.cog = self self.loop_presence.start() # pylint: disable=no-member + if not self.bot.config.get("enable_eval"): + self.eval_.enabled = False + logger.info("Eval disabled. enable_eval=False") def cog_unload(self): self.bot.help_command = self._original_help_command diff --git a/core/config.py b/core/config.py index a0eda4a2dc..a34c5a8e73 100644 --- a/core/config.py +++ b/core/config.py @@ -81,7 +81,7 @@ class ConfigManager: "activity_type": None, "status": None, # dm_disabled 0 = none, 1 = new threads, 2 = all threads - # TODO: use emum + # TODO: use enum "dm_disabled": 0, "oauth_whitelist": [], # moderation @@ -110,9 +110,10 @@ class ConfigManager: "owners": None, # bot "token": None, + "enable_plugins": True, + "enable_eval": False, # Logging "log_level": "INFO", - "enable_plugins": True, } colors = {"mod_color", "recipient_color", "main_color", "error_color"} @@ -128,6 +129,7 @@ class ConfigManager: "thread_auto_close_silently", "thread_move_notify", "enable_plugins", + "enable_eval", } special_types = {"status", "activity_type"} diff --git a/pyproject.toml b/pyproject.toml index eb11a19cb7..54f4efb4e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.5.0-dev1' +version = '3.5.0' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From a7b155b1d0e12fb536d78836d62bd55eb5af4290 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Mon, 8 Jun 2020 16:30:47 -0700 Subject: [PATCH 037/705] Plugins change --- CHANGELOG.md | 4 +++- bot.py | 2 +- cogs/plugins.py | 64 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 191ed404a1..f82dcdc294 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,13 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.5.0dev2 +# v3.5.0dev3 ### Added - A confirmation when you manually delete a thread message embed. - Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. (GH #2803) +- Added `?plugins reset` command to completely reset everything related to plugins. This will fix some problems caused by broken plugins in the file system. ### Changed @@ -20,6 +21,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Renamed `bot.owner_ids` to `bot.bot_owner_ids` as the attribute is now defined interally for team support. - Deleting channel manually will now close the thread. - Deleting messages will no longer cause the bot to produce warnings. +- Plugins will automatically be removed when it fails to load. # v3.4.1 diff --git a/bot.py b/bot.py index d84e3e1cc9..2d0d66f047 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.5.0-dev2" +__version__ = "3.5.0-dev3" import asyncio diff --git a/cogs/plugins.py b/cogs/plugins.py index d14035286d..09dde2b392 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -136,7 +136,12 @@ async def initial_load_plugins(self): await self.download_plugin(plugin) await self.load_plugin(plugin) except Exception: - logger.error("Error when loading plugin %s.", plugin, exc_info=True) + self.bot.config["plugins"].remove(plugin_name) + logger.error( + "Error when loading plugin %s. Plugin removed from config.", + plugin, + exc_info=True, + ) continue logger.debug("Finished loading all plugins.") @@ -415,17 +420,28 @@ async def update_plugin(self, ctx, plugin_name): return await ctx.send(embed=embed) async with ctx.typing(): + embed = discord.Embed( + description=f"Successfully updated {plugin.name}.", color=self.bot.main_color + ) await self.download_plugin(plugin, force=True) if self.bot.config.get("enable_plugins"): try: self.bot.unload_extension(plugin.ext_string) except commands.ExtensionError: logger.warning("Plugin unload fail.", exc_info=True) - await self.load_plugin(plugin) - logger.debug("Updated %s.", plugin_name) - embed = discord.Embed( - description=f"Successfully updated {plugin.name}.", color=self.bot.main_color - ) + try: + await self.load_plugin(plugin) + except Exception: + embed = discord.Embed( + description=f"Failed to update {plugin.name}. This plugin will now be removed from your bot.", + color=self.bot.error_color, + ) + self.bot.config["plugins"].remove(plugin_name) + logger.debug("Failed to update %s. Removed plugin from config.", plugin_name) + else: + logger.debug("Updated %s.", plugin_name) + else: + logger.debug("Updated %s.", plugin_name) return await ctx.send(embed=embed) @plugins.command(name="update") @@ -442,11 +458,45 @@ async def plugins_update(self, ctx, *, plugin_name: str = None): if plugin_name is None: # pylint: disable=redefined-argument-from-local - for plugin_name in self.bot.config["plugins"]: + for plugin_name in list(self.bot.config["plugins"]): await self.update_plugin(ctx, plugin_name) else: await self.update_plugin(ctx, plugin_name) + @plugins.command(name="reset") + @checks.has_permissions(PermissionLevel.OWNER) + async def plugins_reset(self, ctx): + """ + Reset all plugins for the bot. + + Deletes all cache and plugins from config and unloads from the bot. + """ + logger.warning("Purging plugins.") + for ext in list(self.bot.extensions): + if not ext.startswith("plugins."): + continue + try: + logger.error("Unloading plugin: %s.", ext) + self.bot.unload_extension(ext) + except Exception: + logger.error("Failed to unload plugin: %s.", ext) + self.bot.config["plugins"].clear() + + cache_path = Path(__file__).absolute().parent.parent / "temp" / "plugins-cache" + if cache_path.exists(): + logger.warning("Removing cache path.") + shutil.rmtree(cache_path) + + for entry in os.scandir(Path(__file__).absolute().parent.parent / "plugins"): + if entry.is_dir(): + shutil.rmtree(entry.path) + logger.warning("Removing %s.", entry.name) + + embed = discord.Embed( + description=f"Successfully purged all plugins from the bot.", color=self.bot.main_color + ) + return await ctx.send(embed=embed) + @plugins.command(name="loaded", aliases=["enabled", "installed"]) @checks.has_permissions(PermissionLevel.OWNER) async def plugins_loaded(self, ctx): From fcacfb6071f3d18c4a1a3265ea42bd48e75ceaa7 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 02:40:04 -0700 Subject: [PATCH 038/705] Add to changelog and bump version --- CHANGELOG.md | 3 ++- bot.py | 2 +- cogs/plugins.py | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f82dcdc294..baa39edb39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,14 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.5.0dev3 +# v3.5.0dev4 ### Added - A confirmation when you manually delete a thread message embed. - Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. (GH #2803) - Added `?plugins reset` command to completely reset everything related to plugins. This will fix some problems caused by broken plugins in the file system. +- Support private GitHub repos for plugins (thanks to @officialpiyush pr#2767) ### Changed diff --git a/bot.py b/bot.py index 2d0d66f047..28d786b3a9 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.5.0-dev3" +__version__ = "3.5.0-dev4" import asyncio diff --git a/cogs/plugins.py b/cogs/plugins.py index 74881f81f8..8ea358bcb3 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -157,11 +157,12 @@ async def download_plugin(self, plugin, force=False): if plugin.cache_path.exists() and not force: plugin_io = plugin.cache_path.open("rb") logger.debug("Loading cached %s.", plugin.cache_path) - else: headers = {} - if self.bot.config.get("github_token") is not None: - headers["Authorization"] = f"token {self.bot.config.get('github_token')}" + github_token = self.bot.config.get("github_token") + if github_token is not None: + headers["Authorization"] = f"token {github_token}" + async with self.bot.session.get(plugin.url, headers=headers) as resp: logger.debug("Downloading %s.", plugin.url) raw = await resp.read() From 691f916fb9ed22c3c00a97fae3b261b45e0f43d3 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 02:47:19 -0700 Subject: [PATCH 039/705] Bump version for windows plugins support --- CHANGELOG.md | 7 ++++++- bot.py | 7 +++++-- cogs/plugins.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index baa39edb39..eda457f786 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.5.0dev4 +# v3.5.0dev5 ### Added @@ -24,6 +24,11 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Deleting messages will no longer cause the bot to produce warnings. - Plugins will automatically be removed when it fails to load. +### Fixed + +- Plugins not loading in Windows OS. Now uses proactor event loop for asyncio which should fix this. + + # v3.4.1 ### Fixed diff --git a/bot.py b/bot.py index 854a81e0b4..a1a2f38717 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.5.0-dev4" +__version__ = "3.5.0-dev5" import asyncio @@ -47,7 +47,10 @@ os.mkdir(temp_dir) if sys.platform == 'win32': - asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) + try: + asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) + except AttributeError: + logger.error('Failed to use WindowsProactorEventLoopPolicy.', exc_info=True) class ModmailBot(commands.Bot): diff --git a/cogs/plugins.py b/cogs/plugins.py index 8ea358bcb3..df8259736c 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -159,7 +159,7 @@ async def download_plugin(self, plugin, force=False): logger.debug("Loading cached %s.", plugin.cache_path) else: headers = {} - github_token = self.bot.config.get("github_token") + github_token = self.bot.config["github_token"] if github_token is not None: headers["Authorization"] = f"token {github_token}" From ac4437737935936596e48be923b7812c27ffe8b4 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 02:47:49 -0700 Subject: [PATCH 040/705] Black format --- bot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index a1a2f38717..5090402d72 100644 --- a/bot.py +++ b/bot.py @@ -46,11 +46,11 @@ if not os.path.exists(temp_dir): os.mkdir(temp_dir) -if sys.platform == 'win32': +if sys.platform == "win32": try: asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) except AttributeError: - logger.error('Failed to use WindowsProactorEventLoopPolicy.', exc_info=True) + logger.error("Failed to use WindowsProactorEventLoopPolicy.", exc_info=True) class ModmailBot(commands.Bot): From 15372988d3479afc6d43e082c34e85af6fc208ec Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 05:33:50 -0700 Subject: [PATCH 041/705] Add additional database support potentials --- CHANGELOG.md | 4 +- bot.py | 83 +++------------------- cogs/modmail.py | 17 +---- core/clients.py | 180 +++++++++++++++++++++++++++++++++++++++++++++--- core/config.py | 2 + 5 files changed, 186 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eda457f786..248a55d603 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,10 +19,12 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Changed - Bump discord.py version to v1.3.3. -- Renamed `bot.owner_ids` to `bot.bot_owner_ids` as the attribute is now defined interally for team support. +- Renamed `bot.owner_ids` to `bot.bot_owner_ids` as the attribute is now defined internally for team support. - Deleting channel manually will now close the thread. - Deleting messages will no longer cause the bot to produce warnings. - Plugins will automatically be removed when it fails to load. +- Moved all database-related activities to clients.py under MongoDBClient, with possible future hook for additional database support. +- Deprecated `bot.plugin_db.get_partition` in favour of `bot.api.get_plugin_partition` (not final). ### Fixed diff --git a/bot.py b/bot.py index 5090402d72..bba04ff50d 100644 --- a/bot.py +++ b/bot.py @@ -18,8 +18,6 @@ from aiohttp import ClientSession from emoji import UNICODE_EMOJI -from motor.motor_asyncio import AsyncIOMotorClient -from pymongo.errors import ConfigurationError from pkg_resources import parse_version @@ -32,7 +30,7 @@ pass from core import checks -from core.clients import ApiClient, PluginDatabaseClient +from core.clients import ApiClient, PluginDatabaseClient, MongoDBClient from core.config import ConfigManager from core.utils import human_join, normalize_alias from core.models import PermissionLevel, SafeFormatter, getLogger, configure_logging @@ -72,22 +70,7 @@ def __init__(self): self.log_file_name = os.path.join(temp_dir, f"{self.token.split('.')[0]}.log") self._configure_logging() - mongo_uri = self.config["mongo_uri"] - if mongo_uri is None: - logger.critical("A Mongo URI is necessary for the bot to function.") - raise RuntimeError - - try: - self.db = AsyncIOMotorClient(mongo_uri).modmail_bot - except ConfigurationError as e: - logger.critical( - "Your MONGO_URI might be copied wrong, try re-copying from the source again. " - "Otherwise noted in the following message:" - ) - logger.critical(e) - sys.exit(0) - - self.plugin_db = PluginDatabaseClient(self) + self.plugin_db = PluginDatabaseClient(self) # Deprecated self.startup() @property @@ -158,7 +141,11 @@ def session(self) -> ClientSession: @property def api(self) -> ApiClient: if self._api is None: - self._api = ApiClient(self) + if self.config["database_type"].lower() == "mongodb": + self._api = MongoDBClient(self) + else: + logger.critical("Invalid database type.") + raise RuntimeError return self._api async def get_prefix(self, message=None): @@ -376,37 +363,16 @@ def command_perm(self, command_name: str) -> PermissionLevel: async def on_connect(self): try: - await self.validate_database_connection() + await self.api.validate_database_connection() except Exception: logger.debug("Logging out due to failed database connection.") return await self.logout() logger.debug("Connected to gateway.") await self.config.refresh() - await self.setup_indexes() + await self.api.setup_indexes() self._connected.set() - async def setup_indexes(self): - """Setup text indexes so we can use the $search operator""" - coll = self.db.logs - index_name = "messages.content_text_messages.author.name_text_key_text" - - index_info = await coll.index_information() - - # Backwards compatibility - old_index = "messages.content_text_messages.author.name_text" - if old_index in index_info: - logger.info("Dropping old index: %s", old_index) - await coll.drop_index(old_index) - - if index_name not in index_info: - logger.info('Creating "text" index for logs collection.') - logger.info("Name: %s", index_name) - await coll.create_index( - [("messages.content", "text"), ("messages.author.name", "text"), ("key", "text")] - ) - logger.debug("Successfully configured and verified database indexes.") - async def on_ready(self): """Bot startup, sets uptime.""" @@ -1213,37 +1179,6 @@ async def on_command_error(self, context, exception): else: logger.error("Unexpected exception:", exc_info=exception) - async def validate_database_connection(self): - try: - await self.db.command("buildinfo") - except Exception as exc: - logger.critical("Something went wrong while connecting to the database.") - message = f"{type(exc).__name__}: {str(exc)}" - logger.critical(message) - - if "ServerSelectionTimeoutError" in message: - logger.critical( - "This may have been caused by not whitelisting " - "IPs correctly. Make sure to whitelist all " - "IPs (0.0.0.0/0) https://i.imgur.com/mILuQ5U.png" - ) - - if "OperationFailure" in message: - logger.critical( - "This is due to having invalid credentials in your MONGO_URI. " - "Remember you need to substitute `` with your actual password." - ) - logger.critical( - "Be sure to URL encode your username and password (not the entire URL!!), " - "https://www.urlencoder.io/, if this issue persists, try changing your username and password " - "to only include alphanumeric characters, no symbols." - "" - ) - raise - else: - logger.debug("Successfully connected to the database.") - logger.line("debug") - async def post_metadata(self): info = await self.application_info() diff --git a/cogs/modmail.py b/cogs/modmail.py index acbcd74722..5c4de73e26 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -669,12 +669,7 @@ async def logs_closed_by(self, ctx, *, user: User = None): """ user = user if user is not None else ctx.author - query = {"guild_id": str(self.bot.guild_id), "open": False, "closer.id": str(user.id)} - - projection = {"messages": {"$slice": 5}} - - entries = await self.bot.db.logs.find(query, projection).to_list(None) - + entries = await self.bot.api.search_closed_by(user.id) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: @@ -748,15 +743,7 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): await ctx.trigger_typing() - query = { - "guild_id": str(self.bot.guild_id), - "open": False, - "$text": {"$search": f'"{query}"'}, - } - - projection = {"messages": {"$slice": 5}} - - entries = await self.bot.db.logs.find(query, projection).to_list(limit) + entries = await self.bot.api.search_by_text(query, limit) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) diff --git a/core/clients.py b/core/clients.py index 54cc28c9be..1e6008e042 100644 --- a/core/clients.py +++ b/core/clients.py @@ -1,18 +1,21 @@ import secrets +import sys from datetime import datetime from json import JSONDecodeError -from typing import Union +from typing import Union, Optional from discord import Member, DMChannel, TextChannel, Message from aiohttp import ClientResponseError, ClientResponse +from motor.motor_asyncio import AsyncIOMotorClient +from pymongo.errors import ConfigurationError from core.models import getLogger logger = getLogger(__name__) -class RequestClient: +class ApiClient: """ This class represents the general request class for all type of clients. @@ -29,8 +32,9 @@ class RequestClient: The bot's current running `ClientSession`. """ - def __init__(self, bot): + def __init__(self, bot, db): self.bot = bot + self.db = db self.session = bot.session async def request( @@ -74,16 +78,152 @@ async def request( except (JSONDecodeError, ClientResponseError): return await resp.text() - -class ApiClient(RequestClient): - @property - def db(self): - return self.bot.db - @property def logs(self): return self.db.logs + async def setup_indexes(self): + return NotImplemented + + async def validate_database_connection(self): + return NotImplemented + + async def get_user_logs(self, user_id: Union[str, int]) -> list: + return NotImplemented + + async def get_latest_user_logs(self, user_id: Union[str, int]): + return NotImplemented + + async def get_responded_logs(self, user_id: Union[str, int]) -> list: + return NotImplemented + + async def get_open_logs(self) -> list: + return NotImplemented + + async def get_log(self, channel_id: Union[str, int]) -> dict: + return NotImplemented + + async def get_log_link(self, channel_id: Union[str, int]) -> str: + return NotImplemented + + async def create_log_entry( + self, recipient: Member, channel: TextChannel, creator: Member + ) -> str: + return NotImplemented + + async def delete_log_entry(self, key: str) -> bool: + return NotImplemented + + async def get_config(self) -> dict: + return NotImplemented + + async def update_config(self, data: dict): + return NotImplemented + + async def edit_message(self, message_id: Union[int, str], new_content: str) -> None: + return NotImplemented + + async def append_log( + self, + message: Message, + *, + message_id: str = "", + channel_id: str = "", + type_: str = "thread_message", + ) -> dict: + return NotImplemented + + async def post_log(self, channel_id: Union[int, str], data: dict) -> dict: + return NotImplemented + + async def search_closed_by(self, user_id: Union[int, str]): + return NotImplemented + + async def search_by_text(self, text: str, limit: Optional[int]): + return NotImplemented + + def get_plugin_partition(self, cog): + return NotImplemented + + +class MongoDBClient(ApiClient): + def __init__(self, bot): + mongo_uri = bot.config["connection_uri"] + if mongo_uri is None: + mongo_uri = bot.config["mongo_uri"] + if mongo_uri is not None: + logger.warning( + "You're using the old config MONGO_URI, " + "consider switching to the new CONNECTION_URI config." + ) + else: + logger.critical("A Mongo URI is necessary for the bot to function.") + raise RuntimeError + + try: + db = AsyncIOMotorClient(mongo_uri).modmail_bot + except ConfigurationError as e: + logger.critical( + "Your MONGO_URI might be copied wrong, try re-copying from the source again. " + "Otherwise noted in the following message:" + ) + logger.critical(e) + sys.exit(0) + + super().__init__(bot, db) + + async def setup_indexes(self): + """Setup text indexes so we can use the $search operator""" + coll = self.db.logs + index_name = "messages.content_text_messages.author.name_text_key_text" + + index_info = await coll.index_information() + + # Backwards compatibility + old_index = "messages.content_text_messages.author.name_text" + if old_index in index_info: + logger.info("Dropping old index: %s", old_index) + await coll.drop_index(old_index) + + if index_name not in index_info: + logger.info('Creating "text" index for logs collection.') + logger.info("Name: %s", index_name) + await coll.create_index( + [("messages.content", "text"), ("messages.author.name", "text"), ("key", "text")] + ) + logger.debug("Successfully configured and verified database indexes.") + + async def validate_database_connection(self): + try: + await self.db.command("buildinfo") + except Exception as exc: + logger.critical("Something went wrong while connecting to the database.") + message = f"{type(exc).__name__}: {str(exc)}" + logger.critical(message) + + if "ServerSelectionTimeoutError" in message: + logger.critical( + "This may have been caused by not whitelisting " + "IPs correctly. Make sure to whitelist all " + "IPs (0.0.0.0/0) https://i.imgur.com/mILuQ5U.png" + ) + + if "OperationFailure" in message: + logger.critical( + "This is due to having invalid credentials in your MONGO_URI. " + "Remember you need to substitute `` with your actual password." + ) + logger.critical( + "Be sure to URL encode your username and password (not the entire URL!!), " + "https://www.urlencoder.io/, if this issue persists, try changing your username and password " + "to only include alphanumeric characters, no symbols." + "" + ) + raise + else: + logger.debug("Successfully connected to the database.") + logger.line("debug") + async def get_user_logs(self, user_id: Union[str, int]) -> list: query = {"recipient.id": str(user_id), "guild_id": str(self.bot.guild_id)} projection = {"messages": {"$slice": 5}} @@ -245,6 +385,26 @@ async def post_log(self, channel_id: Union[int, str], data: dict) -> dict: {"channel_id": str(channel_id)}, {"$set": data}, return_document=True ) + async def search_closed_by(self, user_id: Union[int, str]): + return await self.logs.find( + {"guild_id": str(self.bot.guild_id), "open": False, "closer.id": str(user_id)}, + {"messages": {"$slice": 5}}, + ).to_list(None) + + async def search_by_text(self, text: str, limit: Optional[int]): + return await self.bot.db.logs.find( + { + "guild_id": str(self.bot.guild_id), + "open": False, + "$text": {"$search": f'"{text}"'}, + }, + {"messages": {"$slice": 5}}, + ).to_list(limit) + + def get_plugin_partition(self, cog): + cls_name = cog.__class__.__name__ + return self.db.plugins[cls_name] + class PluginDatabaseClient: def __init__(self, bot): @@ -252,4 +412,4 @@ def __init__(self, bot): def get_partition(self, cog): cls_name = cog.__class__.__name__ - return self.bot.db.plugins[cls_name] + return self.bot.api.db.plugins[cls_name] diff --git a/core/config.py b/core/config.py index 786729fc75..f945557718 100644 --- a/core/config.py +++ b/core/config.py @@ -107,6 +107,8 @@ class ConfigManager: "log_url": "https://example.com/", "log_url_prefix": "/logs", "mongo_uri": None, + "database_type": "mongodb", + "connection_uri": None, # replace mongo uri in the future "owners": None, # bot "token": None, From 491d07a60eedfb7d38c821939a81bee3f8cc2fc3 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 05:44:50 -0700 Subject: [PATCH 042/705] Update app.json --- CHANGELOG.md | 1 + app.json | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 248a55d603..0956794786 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Plugins will automatically be removed when it fails to load. - Moved all database-related activities to clients.py under MongoDBClient, with possible future hook for additional database support. - Deprecated `bot.plugin_db.get_partition` in favour of `bot.api.get_plugin_partition` (not final). +- Deprecated `MONGO_URI` config var (but will keep support in the future) in favour of `CONNECTION_URI` and `DATABASE_TYPE`. Right now there is one supported database - "mongodb", which is the default. ### Fixed diff --git a/app.json b/app.json index 76fe320a30..b6a833b1ef 100644 --- a/app.json +++ b/app.json @@ -15,10 +15,14 @@ "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", "required": true }, - "MONGO_URI": { - "description": "Mongo DB connection URI for self-hosting your data.", + "CONNECTION_URI": { + "description": "The connection URI for your database.", "required": true }, + "DATABASE_TYPE": { + "description": "The type of your database. There is only one supported database at the moment - MongoDB (default).", + "required": false + }, "LOG_URL": { "description": "The url of the log viewer app for viewing self-hosted logs.", "required": true From f6957c415b25e0852231b54bc22f2a5953e8dc7b Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 17:58:19 -0700 Subject: [PATCH 043/705] Update Pipfile --- Pipfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Pipfile b/Pipfile index 16bbac8e49..e506daf6dd 100644 --- a/Pipfile +++ b/Pipfile @@ -21,6 +21,7 @@ parsedatetime = "==2.6" aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" +pip = ">=18.0" "discord.py" = "==1.3.3" [requires] From c12a16e0647d181c09c4ec47f86381d33539ba78 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 18:01:05 -0700 Subject: [PATCH 044/705] Add pip to pipfile, apparently theres a dependency problem? --- Pipfile.lock | 177 +++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 77 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 14f91762aa..d8c22e241e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "bfb85b7c7862e17e905d739f0fb63248d3bf446035f32e3afac619f6d2c5a0ba" + "sha256": "cd8e330d55a4f896b01872d9fd56534288882d1ab6c68f0fc0841a13d8df9f00" }, "pipfile-spec": 6, "requires": { @@ -46,6 +46,7 @@ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], + "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { @@ -53,14 +54,15 @@ "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==19.3.0" }, "certifi": { "hashes": [ - "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304", - "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519" + "sha256:5ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1", + "sha256:9cd41137dc19af6a5e03b630eefe7d1f458d964d406342dd3edf625839b944cc" ], - "version": "==2020.4.5.1" + "version": "==2020.4.5.2" }, "chardet": { "hashes": [ @@ -118,6 +120,7 @@ "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.9" }, "importlib-metadata": { @@ -165,6 +168,7 @@ "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" ], + "markers": "python_version >= '3.5'", "version": "==4.7.6" }, "natural": { @@ -192,59 +196,62 @@ }, "pymongo": { "hashes": [ - "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", - "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", - "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", - "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", - "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", - "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", - "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", - "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", - "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", - "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", - "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", - "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", - "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", - "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", - "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", - "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", - "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", - "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", - "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", - "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", - "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", - "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", - "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", + "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", + "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606", + "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", + "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", + "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", - "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", + "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", + "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", + "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", + "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", + "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", + "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", - "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", - "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", - "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", - "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", - "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", - "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", - "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", - "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", - "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", - "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", - "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", - "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", - "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", - "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", - "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", - "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", + "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", + "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", + "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", + "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", - "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", - "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", + "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", + "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", + "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", + "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", + "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", + "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", + "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", + "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", + "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", + "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", + "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", + "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", + "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", + "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", + "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", + "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", + "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", + "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", + "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", + "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", + "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", + "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", - "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606" + "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", + "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", + "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", + "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", + "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", + "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", + "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", + "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", + "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103" ], "version": "==3.10.1" }, @@ -269,6 +276,7 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "uvloop": { @@ -292,6 +300,7 @@ "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf", "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.0.21" }, "virtualenv-clone": { @@ -299,6 +308,7 @@ "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.5.4" }, "websockets": { @@ -326,6 +336,7 @@ "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" ], + "markers": "python_full_version >= '3.6.1'", "version": "==8.1" }, "yarl": { @@ -348,6 +359,7 @@ "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2" ], + "markers": "python_version >= '3.5'", "version": "==1.4.2" }, "zipp": { @@ -355,6 +367,7 @@ "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" ], + "markers": "python_version >= '3.6'", "version": "==3.1.0" } }, @@ -368,16 +381,18 @@ }, "astroid": { "hashes": [ - "sha256:4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1", - "sha256:d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38" + "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", + "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" ], - "version": "==2.4.1" + "markers": "python_version >= '3.5'", + "version": "==2.4.2" }, "attrs": { "hashes": [ "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==19.3.0" }, "bandit": { @@ -401,6 +416,7 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "gitdb": { @@ -408,6 +424,7 @@ "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], + "markers": "python_version >= '3.4'", "version": "==4.0.5" }, "gitpython": { @@ -415,6 +432,7 @@ "sha256:e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a", "sha256:ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac" ], + "markers": "python_version >= '3.4'", "version": "==3.1.3" }, "isort": { @@ -422,6 +440,7 @@ "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==4.3.21" }, "lazy-object-proxy": { @@ -448,6 +467,7 @@ "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.3" }, "mccabe": { @@ -473,11 +493,11 @@ }, "pylint": { "hashes": [ - "sha256:b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c", - "sha256:dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b" + "sha256:7dd78437f2d8d019717dbf287772d0b2dbdfd13fc016aa7faa08d67bccc46adc", + "sha256:d0ece7d223fe422088b0e8f13fa0a1e8eb745ebffcb8ed53d3e95394b6101a1c" ], "index": "pypi", - "version": "==2.5.2" + "version": "==2.5.3" }, "pyyaml": { "hashes": [ @@ -497,35 +517,36 @@ }, "regex": { "hashes": [ - "sha256:150125da109fccdcc8fec3b0b386b2a5d6ca7cff076f8b622486d1ca868b0c10", - "sha256:163bc0805e46acfa098dfc8c0b07f371577d505f603e48afc425ff475cdac3a5", - "sha256:20c513893ff80bdbe4b4ce11ea2e93d49481f05b270595d82af69ffc402010a6", - "sha256:21fc17cb868c4264f0813f992f46f9ae6fc8c309d4741091de4153bd1f6a6176", - "sha256:2c928bc8e0c453d73dffa3193a6e37ee752ea36df0dd4601e21024d98274dfad", - "sha256:2d9beca70e36f9c60d679e108c5fe49f3d4da79d13a13f91e5e759443bd954f9", - "sha256:5735f26cacdb50b3d6d35ebf8fdeb504bd8b381e2d079d2d9f12ce534fc14ecd", - "sha256:6edc5c190248d3b612f2cca45448cf8ebc3621d41afcd1c5708853cbb1dbb3b3", - "sha256:7606dba82435429641efe4fbc580574942f89cf2b9c5c1f8bc1eab2bacbf7e8b", - "sha256:8d1ee3796795e609ef7a3a5a35eaf4728038d986aa12c06b3fd1b92ee81911f4", - "sha256:8d9bb2d90e23c51aacbc58c1a11320f49b335cd67a91986cdbebcc3e843e4de8", - "sha256:97d414c41f19fd2362e493810caa8445c05e0a2d63a14081c972aad66284a8d2", - "sha256:9e37502817225ee99d91d8418f5119e98c380b00e772d06915690c05290f32ee", - "sha256:af7209b2fcc79ee2b0ad4ea080d70bb748450ec4f282cc9e864861e469b1072e", - "sha256:c0849b0864ff451f04c8afb5fc28e9ed592262e03debdd227cf0f53e04a55dcd", - "sha256:c4ac9215650688e78dea29b46adbdafb7b85058eebe92ef6ea848e14466c915f", - "sha256:dcda6d4e1bbfc939b177c237aee41c9678eaaf71df482688f8986e8251e12345", - "sha256:dd8501b8d9ea1aba53c4bc7d47bc72933f9b4213d534cf400f16c1431f51c8ba", - "sha256:ec0e509ed1877ff1cbc6f0864689bb60384a303502c4d72d9a635f8a4676fd3f", - "sha256:f6c8c3f56fef719180464855346e6e80971b86dfd9e5a0e356664b5baca53072", - "sha256:ffd4f80602490a309064cf2b203e220d581c51660e01055c64bf5da450485ee6" - ], - "version": "==2020.6.7" + "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a", + "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938", + "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29", + "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae", + "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387", + "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a", + "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf", + "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610", + "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9", + "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5", + "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3", + "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89", + "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded", + "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754", + "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f", + "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868", + "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd", + "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910", + "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3", + "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac", + "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c" + ], + "version": "==2020.6.8" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "smmap": { @@ -533,6 +554,7 @@ "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.0.4" }, "stevedore": { @@ -540,6 +562,7 @@ "sha256:001e90cd704be6470d46cc9076434e2d0d566c1379187e7013eb296d3a6032d9", "sha256:471c920412265cc809540ae6fb01f3f02aba89c79bbc7091372f4745a50f9691" ], + "markers": "python_version >= '3.6'", "version": "==2.0.0" }, "toml": { @@ -573,7 +596,7 @@ "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" ], - "markers": "implementation_name == 'cpython' and python_version < '3.8'", + "markers": "python_version < '3.8' and implementation_name == 'cpython'", "version": "==1.4.1" }, "wrapt": { From f51a7fb54c50f3d22b5018a08fecec27cbea61b1 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Tue, 9 Jun 2020 18:08:49 -0700 Subject: [PATCH 045/705] Rollback py version for heroku --- Pipfile | 1 - Pipfile.lock | 94 ++++++++++++++++++++++++++-------------------------- runtime.txt | 2 +- 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/Pipfile b/Pipfile index e506daf6dd..16bbac8e49 100644 --- a/Pipfile +++ b/Pipfile @@ -21,7 +21,6 @@ parsedatetime = "==2.6" aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -pip = ">=18.0" "discord.py" = "==1.3.3" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index d8c22e241e..9a650f4af4 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "cd8e330d55a4f896b01872d9fd56534288882d1ab6c68f0fc0841a13d8df9f00" + "sha256": "bfb85b7c7862e17e905d739f0fb63248d3bf446035f32e3afac619f6d2c5a0ba" }, "pipfile-spec": 6, "requires": { @@ -196,62 +196,62 @@ }, "pymongo": { "hashes": [ - "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", - "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", - "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606", - "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", - "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", - "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", - "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", - "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", - "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", - "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", - "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", + "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", + "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", + "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", + "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", + "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", + "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", + "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", + "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", + "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", + "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", + "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", + "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", + "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", + "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", + "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", + "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", + "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", + "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", + "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", + "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", + "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", + "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", + "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", + "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", + "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", + "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", - "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", - "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", - "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", - "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", + "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", + "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", - "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", - "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", - "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", - "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", - "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", - "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", - "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", + "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", - "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", - "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", - "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", - "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", - "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", - "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", - "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", - "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", - "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", - "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", - "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", - "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", - "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", - "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", - "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", - "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", - "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", + "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", + "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", + "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", + "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", + "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", + "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", + "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", + "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", + "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", - "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", - "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", - "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", - "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", + "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", + "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", - "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", - "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", - "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103" + "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", + "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", + "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", + "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", + "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", + "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606" ], "version": "==3.10.1" }, diff --git a/runtime.txt b/runtime.txt index 05802392e0..257b314f5f 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.7 \ No newline at end of file +python-3.7.6 \ No newline at end of file From 62a30dd033afe7cdb277353bd698c80007d15a74 Mon Sep 17 00:00:00 2001 From: SpyTec Date: Thu, 2 Jul 2020 20:37:57 +0200 Subject: [PATCH 046/705] Botched multiple config handler --- bot.py | 13 ++++++++----- core/config.py | 11 +++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/bot.py b/bot.py index 694f860cf1..d16c953bb3 100644 --- a/bot.py +++ b/bot.py @@ -48,7 +48,7 @@ class ModmailBot(commands.Bot): - def __init__(self): + def __init__(self, args): super().__init__(command_prefix=None) # implemented in `get_prefix` self._session = None self._api = None @@ -58,7 +58,10 @@ def __init__(self): self._connected = asyncio.Event() self.start_time = datetime.utcnow() - self.config = ConfigManager(self) + if len(args): + self.config = ConfigManager(self, args[0]) + else: + self.config = ConfigManager(self) self.config.populate_cache() self.threads = ThreadManager(self) @@ -1224,7 +1227,7 @@ async def before_post_metadata(self): self.metadata_loop.cancel() -def main(): +def main(args): try: # noinspection PyUnresolvedReferences import uvloop @@ -1234,9 +1237,9 @@ def main(): except ImportError: pass - bot = ModmailBot() + bot = ModmailBot(args) bot.run() if __name__ == "__main__": - main() + main(sys.argv[1:]) diff --git a/core/config.py b/core/config.py index a0eda4a2dc..64f603d758 100644 --- a/core/config.py +++ b/core/config.py @@ -5,7 +5,6 @@ import typing from copy import deepcopy -from dotenv import load_dotenv import isodate import discord @@ -17,7 +16,6 @@ from core.utils import strtobool logger = getLogger(__name__) -load_dotenv() class ConfigManager: @@ -135,11 +133,12 @@ class ConfigManager: defaults = {**public_keys, **private_keys, **protected_keys} all_keys = set(defaults.keys()) - def __init__(self, bot): + def __init__(self, bot, config_file = "config.json"): self.bot = bot self._cache = {} self.ready_event = asyncio.Event() self.config_help = {} + self.config_file = config_file def __repr__(self): return repr(self._cache) @@ -148,12 +147,12 @@ def populate_cache(self) -> dict: data = deepcopy(self.defaults) # populate from env var and .env file - data.update({k.lower(): v for k, v in os.environ.items() if k.lower() in self.all_keys}) + # data.update({k.lower(): v for k, v in os.environ.items() if k.lower() in self.all_keys}) config_json = os.path.join( - os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config.json" + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), self.config_file ) if os.path.exists(config_json): - logger.debug("Loading envs from config.json.") + logger.debug("Loading envs from {}".format(self.config_file)) with open(config_json, "r", encoding="utf-8") as f: # Config json should override env vars try: From baff27ef0e7c8970bc57c60ce03fb5ed9c9b2f06 Mon Sep 17 00:00:00 2001 From: RheaAyase Date: Thu, 2 Jul 2020 23:03:52 +0200 Subject: [PATCH 047/705] Unbotched support for multiple instances using config folders --- core/config.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/config.py b/core/config.py index 64f603d758..ddf3ace149 100644 --- a/core/config.py +++ b/core/config.py @@ -5,6 +5,7 @@ import typing from copy import deepcopy +from dotenv import load_dotenv import isodate import discord @@ -133,12 +134,13 @@ class ConfigManager: defaults = {**public_keys, **private_keys, **protected_keys} all_keys = set(defaults.keys()) - def __init__(self, bot, config_file = "config.json"): + def __init__(self, bot, config_path = os.path.dirname(os.path.abspath(__file__))): self.bot = bot self._cache = {} self.ready_event = asyncio.Event() self.config_help = {} - self.config_file = config_file + self.config_path = config_path + load_dotenv(dotenv_path=os.path.join(self.config_path, ".env")) def __repr__(self): return repr(self._cache) @@ -147,12 +149,10 @@ def populate_cache(self) -> dict: data = deepcopy(self.defaults) # populate from env var and .env file - # data.update({k.lower(): v for k, v in os.environ.items() if k.lower() in self.all_keys}) - config_json = os.path.join( - os.path.dirname(os.path.dirname(os.path.abspath(__file__))), self.config_file - ) + data.update({k.lower(): v for k, v in os.environ.items() if k.lower() in self.all_keys}) + config_json = os.path.join(self.config_path, "config.json") if os.path.exists(config_json): - logger.debug("Loading envs from {}".format(self.config_file)) + logger.debug("Loading envs from {}".format(config_json)) with open(config_json, "r", encoding="utf-8") as f: # Config json should override env vars try: From 9569e15092bda9447473657e13826b86af24832e Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 3 Jul 2020 18:15:32 +0800 Subject: [PATCH 048/705] Fix black from CI --- bot.py | 2 +- core/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index d16c953bb3..24f1218585 100644 --- a/bot.py +++ b/bot.py @@ -60,7 +60,7 @@ def __init__(self, args): if len(args): self.config = ConfigManager(self, args[0]) - else: + else: self.config = ConfigManager(self) self.config.populate_cache() diff --git a/core/config.py b/core/config.py index ddf3ace149..cfd79d9df9 100644 --- a/core/config.py +++ b/core/config.py @@ -134,7 +134,7 @@ class ConfigManager: defaults = {**public_keys, **private_keys, **protected_keys} all_keys = set(defaults.keys()) - def __init__(self, bot, config_path = os.path.dirname(os.path.abspath(__file__))): + def __init__(self, bot, config_path=os.path.dirname(os.path.abspath(__file__))): self.bot = bot self._cache = {} self.ready_event = asyncio.Event() From ee7d2360f73494b92cd76de08947603f0479746b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 3 Jul 2020 18:22:04 +0800 Subject: [PATCH 049/705] oops --- .github/ISSUE_TEMPLATE/command-request.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- .github/workflows/stale.yml | 2 +- CHANGELOG.md | 262 +++-- CONTRIBUTING.md | 17 +- README.md | 48 +- bot.py | 58 +- cogs/modmail.py | 290 ++--- cogs/plugins.py | 80 +- cogs/utility.py | 373 ++++--- core/config.py | 11 +- core/paginator.py | 2 +- core/thread.py | 54 +- core/time.py | 2 +- core/translations.py | 25 + languages/en.csv | 1172 +++++++++++++++++++++ plugins/registry.json | 31 +- poetry.lock | 467 ++------ pyproject.toml | 8 +- runtime.txt | 2 +- translation_files.py | 117 ++ 21 files changed, 2016 insertions(+), 1009 deletions(-) create mode 100644 core/translations.py create mode 100644 languages/en.csv create mode 100644 translation_files.py diff --git a/.github/ISSUE_TEMPLATE/command-request.md b/.github/ISSUE_TEMPLATE/command-request.md index d3c1673a6b..44902f2cf3 100644 --- a/.github/ISSUE_TEMPLATE/command-request.md +++ b/.github/ISSUE_TEMPLATE/command-request.md @@ -1,7 +1,7 @@ --- name: Command request about: Request a new command -title: "your title here" +title: "[COMMAND-REQUEST] your title here" labels: command-request assignees: '' diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 7cd7a506cd..48b986344d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: "your title here" +title: "[FEATURE-REQUEST] your title here" labels: feature-request assignees: '' diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index d0811bfd30..b3003ccf92 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,4 +14,4 @@ jobs: stale-issue-message: 'This issue is stale because it has been open for 100 days with no activity. Remove stale label or comment or this will be closed in 5 days. Please do not un-stale this issue unless it carries significant contribution.' days-before-stale: 100 days-before-close: 5 - exempt-issue-label: 'priority: high,approved,security,bug' + exempt-issue-label: 'high priority' diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dcb9acbcd..16c89216f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,22 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); -however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +however, insignificant breaking changes does not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). -# v3.4.1 - -### Fixed - -- Masked a bunch of noise errors when deleting messages. -- Added more checks for deleting messages. - -### Breaking - -- `thread_initiate` will be dispatched at the beginning of the setup process. -- `thread_create` is dispatched when the thread is registered as a thread by Modmail (i.e., when channel topic is edited). -- `thread_ready` is dispatched when a thread finishes its setup steps. +# v3.5.0-dev0 +Translations WIP. # v3.4.0 @@ -36,35 +26,35 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Multi-command alias is now more stable. With support for a single quote escape `\"`. - New command `?freply`, which behaves exactly like `?reply` with the addition that you can substitute `{channel}`, `{recipient}`, and `{author}` to be their respective values. - New command `?repair`, repair any broken Modmail thread (with help from @officialpiyush). -- Recipients get feedback when they edit their messages. +- Recipient get feedback when they edit message. - Chained delete for DMs now comes with a message. - poetry (in case someone needs it). ### Changed - The look of alias and snippet when previewing. -- The database now saves the message ID of the thread embed, instead of the original message. +- Message ID of the thread embed is saved in DB, instead of the original message. - Swapped the position of user and category for `?contact`. - The log file will no longer grow infinitely large. -- A hard limit of a maximum of 25 steps for aliases. +- Hard limit of maximum 25 steps for alias. - `?disable` is now `?disable new`. ### Fixed - Setting config vars using human time wasn't working. - Fixed some bugs with aliases. -- Fixed many issues with `?edit` and `?delete` and recipient message edit. +- Fixed a lot of issues with `?edit` and `?delete` and recipient message edit. - Masked the error: "AttributeError: 'int' object has no attribute 'name'" - Channel delete event will not be checked until discord.py fixes this issue. -- Chained reaction add/remove. +- Chained reaction add / remove. - Chained delete for thread channels. ### Internal -- Commit to black format line width max = 99, consistent with PyLint. -- No longer requires shlex for alias parsing. +- Commit to black format line width max = 99, consistent with pylint. +- Alias parser is rewritten without shlex. - New checks with thread create / find. -- No more flake8 and Travis. +- No more flake8 and travis. # v3.3.2 @@ -88,19 +78,19 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Three new config vars: - `enable_plugins` (yes/no default yes) - - When set to no, Modmail will not load plugins. + - When set to no, plugins will not be loaded into the bot. - `error_color` (color format, defaults discord red) - The color of error messages. - `anon_reply_without_command` (yes/no default no) (Thanks to papiersnipper PR#288) - When set, all non-command messages sent to thread channels are forwarded to the recipient anonymously without the need of `?anonreply`. - This config takes precedence over `reply_without_command`. -- `?logs responded [user]` command. It will show all the logs that the user has sent a reply. (Thanks to papiersnipper PR#288) +- `?logs responded [user]` command, it will show all logs that the user has sent an reply. (Thanks to papiersnipper PR#288) - `user` when not provided, defaults to the user who ran the command. -- Open threads in limbo now auto-close if Modmail cannot find the channel. Modmail does this check every time the bot restarts. +- Open threads in limbo now auto closes if the channel cannot be found. This check is done every time the bot restarts. - Ability to disable new threads from getting created. - - `?disable`. + - `?disable` - Ability to fully disable Modmail DM. - - `?disable all`. + - `?disable all` - To re-enable DM: `?enable`, and to see the current status: `?isenable`. - This disabled Modmail interface is customizable with the following config vars: - `disabled_new_thread_title` @@ -114,33 +104,33 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Changed -- `?contact` no longer send the "thread created" message to where the command was run, instead, it's now sent to the newly created thread channel. (Thanks to DAzVise) +- `?contact` no longer send the "thread created" message to where the command is ran, instead, it's now sent to the newly created thread channel. (Thanks to DAzVise) - Automatically delete notes command `?note` when there're no attachments attached. - Embed author links used to be inaccessible in many cases, now: - `?anonreply`, `?reply`, and `?note` in the thread channel will link to the sender's profile. - - `?reply` and the recipient's DM will also link the sender's profile. + - `?reply` and recipient's DM will also link the sender's profile. - `?anonreply` in DM channel will link to the first channel of the main guild. - Plugins update (mostly internal). - - `git` is no longer used to install plugins; it now downloads through zip files. + - `git` is no longer used to install plugins, it now downloads through zip files. - `?plugins enabled` renamed to `?plugins loaded` while `enabled` is still an alias to that command. - Reorganized plugins folder structure. - Logging / plugin-related messages change. - - Updating one plugin will not update other plugins; repositories no longer separate plugins, but the plugin name itself. -- The help command is in alphabetical order grouped by permissions. -- Notes are no longer always blurple; it's set to `MAIN_COLOR` now. + - Updating one plugin will not update all other plugins (plugins are no longer separated by repos, but the plugin name itself). +- Help command is in alphabetical order grouped by permissions. +- Notes are no longer always blurple, it's set to `MAIN_COLOR` now. - Added `?plugins update` for updating all installed plugins. - Reintroduce flake8 and use bandit for security issues detection. -- Add Travis checks for 3.6 in Linux and 3.7 for macOS and Windows. -- Debug logs not logs eval commands. +- Add travis checks for 3.6 in Linux and 3.7 for MacOS and Windows. +- Eval commands are logged in debug logs. - Presence updates 30 minutes instead of 45 now. -- Fixed an assortment of problems to do with `?block`. +- Fixed an assortment of problems to do with block. - Existing aliases can be used when creating new aliases. (Thanks to papiersnipper PR#402) ### Internal - Reworked `config.get` and `config.set`, it feeds through the converters before setting/getting. - To get/set the raw value, access through `config[]`. -- The prerelease naming scheme is now `x.x.x-devN`. +- Prerelease naming scheme is now `x.x.x-devN`. - `trigger_typing` has been moved to `core.utils.trigger_typing`, the original location is deprecated. - Simpler status and activity logic. - New logging logic. @@ -153,9 +143,9 @@ Security update! - Supporter permission users used to be able to "hack" snippets to reveal all your config vars, including your token and MongoURI. - Implemented some changes to address this bug: - - All customizable variables used in snippets, close messages, etc., using the `{}` syntax, now forbids chaining two or more attributes and attributes that start with `_`. -- We advise you to update to this version. -- If you felt your credentials had been leaked, consider changing your bot token / MongoURI. + - All customizable variables used in snippets, close messages, etc, using the `{}` syntax, now forbids chaining 2 or more attributes and attributes that starts with `_`. +- It is advised to update to this version. +- If you felt your credentials have been leaked, consider changing your bot token / mongo uri. # v3.2.1 @@ -185,7 +175,7 @@ Security update! ### Internal -- Use regex to parse Changes, Added, Fixed, etc. and description. +- Use regex to parse Changes, Added, Fixed, etc and description. - Adds `PermissionLevel.INVALID` when commands don't have a permission level. # v3.1.1 @@ -205,33 +195,33 @@ Security update! ### Added - `?sfw`, mark a thread as "safe for work", undos `?nsfw`. -- New config variable, `thread_auto_close_silently`, when set to a truthy value, no message will be sent when a thread is auto-closed. +- New config variable, `thread_auto_close_silently`, when set to a truthy value, no message will be sent when thread is auto-closed. - New configuration variable `thread_self_closable_creation_footer` — the footer when `recipient_thread_close` is enabled. - Added a minimalistic version of requirements.txt (named requirements.min.txt) that contains only the absolute minimum of Modmail. - For users having trouble with pipenv or any other reason. -- Multi-step alias, see `?help alias add`. Public beta testing might be unstable. +- Multi-step alias, see `?help alias add`. Public beta testing, might be unstable. - Misc commands without cogs are now displayed in `?help`. - `?help` works for alias and snippets. - `?config help ` shows a help embed for the configuration. -- Support setting permissions for subcommands. -- Support numbers (1-5) as substitutes for Permission Level REGULAR - OWNER in `?perms` subcommands. +- Support setting permissions for sub commands. +- Support numbers (1-5) as substitutes for Permission Level REGULAR - OWNER in `?perms` sub commands. ### Changes - `thread_auto_close_response` has a configurable variable `{timeout}`. - `?snippet` is now the default command name instead of `?snippets` (`?snippets` is still usable). This is to make this consistent with `?alias`/`?aliases`. -- `colorama` is no longer a necessity; this is due to some unsupported OS. -- Changelog command can now take a version argument to jump straight to the specified version. +- `colorama` is no longer a necessity, this is due to some unsupported OS. +- Changelog command can now take a version argument to jump straight to specified version. - `?plugin enabled` results are now sorted alphabetically. -- `?plugin registry` results are now sorted alphabetically, helps users find plugins more easily. +- `?plugin registry` results are now sorted alphabetically, helps user find plugins more easily. - `?plugin registry page-number` plugin registry can specify a page number for quick access. - A reworked interface for `?snippet` and `?alias`. - Add an `?snippet raw ` command for viewing the raw content of a snippet (escaped markdown). - - Add an `?alias raw ` command for displaying the raw content of an alias (escaped markdown). + - Add an `?alias raw ` command for viewing the raw content of a alias (escaped markdown). - The placeholder channel for the streaming status changed to https://www.twitch.tv/discordmodmail/. - Removed unclear `rm` alias for some `remove` commands. - Paginate `?config options`. -- All users configured with a permission level higher than REGULAR has access to the main Modmail category. +- All users configured with a permission level greater than REGULAR has access to the main Modmail category. - Category overrides also changes when a level is removed or added to a user or role. - `@everyone` is now accepted for `?perms add`. @@ -239,12 +229,12 @@ Security update! - `?notify` no longer carries over to the next thread. - `discord.NotFound` errors for `on_raw_reaction_add`. -- `mod_typing` ~~and `user_typing`~~ (`user_typing` is now by-design to show) will no longer show when the user is blocked. +- `mod_typing` ~~and `user_typing`~~ (`user_typing` is now by-design to show) will no longer show when user is blocked. - Better `?block` usage message. -- Resolved errors when mods sent messages after a thread is closed somehow. +- Resolves errors when message was sent by mods after thread is closed somehow. - Recipient join/leave server messages are limited to only the guild set by `GUILD_ID`. -- When creating snippets and aliases, it now checks if other snippets/aliases with the same name exist. -- Modmail looked for `config.json` in the wrong directory. +- When creating snippets and aliases, it now checks if another snippets/aliases with the same name exists. +- Was looking for `config.json` in the wrong directory. ### Internal @@ -264,13 +254,13 @@ Security update! ### Added - New commands, `?alias edit ` and `?snippets edit `. - - They can be used to edit aliases and snippets, respectively. + - They can be used to edit aliases and snippets respectively. # v3.0.2 ### Added -- A new command, `?blocked whitelist `, this command prevents users from getting blocked by any means. +- New command, `?blocked whitelist `, this command prevents users from getting blocked by any means. ### Changed @@ -280,30 +270,30 @@ Security update! ### Fixed -- Many bugs with `thread_auto_close`. +- A lot of bugs with `thread_auto_close` 😅 # v3.0.0 ### Added -- `?sponsors` command will list sponsors. -- An alert will now be sent to the log channel if a thread channel fails to create. This could be due to a variety of problems such as insufficient permissions, or the category channel limit is met. +- Sponsors command that will list sponsors. +- An alert will now be sent to the log channel if a thread channel fails to create. This could be due to a variety of problems such as insufficient permissions or the category channel limit is met. - Threads will close automatically after some time when `thread_auto_close` is set. -- Custom closing messages can be configured with `thread_auto_close_response`. +- Custom closing message can be set with `thread_auto_close_response`. ### Breaking Changes -- Removed auto-update functionality and the `?update` command in favor of the [Pull app](https://github.com/apps/pull). +- Removed autoupdate functionality and the `?update` command in favour of the [Pull app](https://github.com/apps/pull). Read more about updating your bot [here](https://github.com/kyb3r/modmail/wiki/updating) ### Changed -- Channel names now can contain Unicode characters. -- Debug logs are now located in a different file for each bot. (Internal change) +- Channel names now can contain unicode characters. +- Debug logs are now located in a unique file for each bot. (Internal change) - Default cogs always appear first in the help command now. ### Fixed -- Editing notes now work, minor bug with edit command is fixed. +- Editing notes now works, minor bug with edit command is fixed. - Bug in the `?oauth` command where the response message fails to send when an ID is provided. - Plugin requirement installation now works in virtual environments @@ -318,7 +308,7 @@ Fixed a bug with branches and `?plugin update`. ### Added -Branch support for `?plugin add` and in the registry. Typically for developers. +Branch support for `?plugin add` and in registry. Typically for developers. # v2.23.0 @@ -326,11 +316,11 @@ Branch support for `?plugin add` and in the registry. Typically for developers. Added a "Mutual servers" field to the genesis embed if: a) The user is not in the main guild. -b) The user shares more than one server with the bot. +b) The user shares more than 1 server with the bot. ### Changed -Notes with the `?note` command are now automatically pinned within the thread channel. +Notes taken with the `?note` command are now automatically pinned within the thread channel. # v2.22.0 @@ -372,14 +362,14 @@ Add your plugin in the `plugins/registry.json` file in the main repository. This update contains mostly internal changes. - Implemented support for the new discord.py v1.1.1. - Improved help text for most commands. - - Completely revamped help command, few users changes. - - Removed ABC (internal). + - Completely revamped help command, few user changes. + - Removed abc (internal). # v2.20.0 ### What's new? -New `?oauth whitelist` command, which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app, check the logviewer [repo](https://github.com/kyb3r/logviewer). +New `oauth` whitelist command which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app check the logviewer [repo](https://github.com/kyb3r/logviewer). # v2.19.1 @@ -387,7 +377,7 @@ New `?oauth whitelist` command, which allows you to whitelist users so they can - Ability to force an update despite having the same version number. Helpful to keep up-to-date with the latest GitHub commit. - `?update force`. -- Plugin developers now have a new event called `on_plugin_ready`; this is a coroutine and is awaited when all plugins are loaded. Use `on_plugin_ready` instead of `on_ready` since `on_ready` will not get called in plugins. +- Plugin developers now have a new event called `on_plugin_ready`, this is coroutine is awaited when all plugins are loaded. Use `on_plugin_ready` instead of `on_ready` since `on_ready` will not get called in plugins. # v2.19.0 @@ -408,17 +398,17 @@ Fix the teams permission bug. ### Changed -Commands now have better error messages. Instead of sending the help message for a command when an argument fails to be converted, the bot now says like "User 'bob' not found" instead. +Commands now have better error messages, instead of just sending the help message for a command when an argument fails to be converted to its specified object, the bot now says things like "User 'bob' not found" instead. # v2.18.1 -Un-deprecated the `OWNERS` config variable to support Discord developer team accounts. +Un-deprecated the `OWNERS` config variable to support discord developer team accounts. # v2.18.0 ### New Permissions System -- A brand new permission system! Replaced the old guild-based permissions (i.e., manage channels, manage messages), with the new system enables you to customize your desired permission level specific to a command or a group of commands for a role or user. +- A brand new permission system! Replacing the old guild-based permissions (ie. manage channels, manage messages), the new system enables you to customize your desired permission level specific to a command or a group of commands for a role or user. - There are five permission levels: - Owner [5] - Administrator [4] @@ -437,7 +427,7 @@ You may add a role or user to a permission group through any of the following me The same applies to individual commands permissions: - `?permissions add command command-name @member#1234` -- and the other methods listed above. +- ... and the other methods listed above. To revoke permission, use `remove` instead of `add`. @@ -450,11 +440,11 @@ By default, all newly set up Modmail will have `OWNER` set to the owner of the b ### Breaking When updating to this version, all prior permission settings with guild-based permissions will be invalidated. You will need to convert to the above system. -`OWNERS` will also get removed; you will need to set owners through `?permissions add level owner 212931293123129` or any way listed above. +`OWNERS` will also get removed, you will need to set owners through `?permissions add level owner 212931293123129` or any way listed above. ### New Command -- A `?delete` command, which is an alternative to manually deleting a message. This command is created to no longer require "manage messages" permission to recall thread messages. +- A `?delete` command, which is an alternative to manually deleting a message. This command is created to no longer requires manage messages permission to recall thread messages. ### Changed @@ -475,28 +465,28 @@ Stricter fallback genesis embed search. ### Changed -How Modmail checks if a channel is a thread: +How modmail checks if a channel is a thread: -1. The bot first checks if the channel topic is in the format `User ID: XXXX`, this means it is a thread. -2. If a channel topic is not found, the bot searches through the message history of a channel to find the thread creation embed. This step should never yield a thread for an average user. Still, in the case of another bot messing up the channel topic (happened to a user before), this extra step was added. +1. The bot first checks if the channel topic is in the format `User ID: xxxx`, this means it is a thread. +2. If a channel topic is not found, the bot searches through the message history of a channel to find the thread creation embed. This step should never yield a thread for a normal user, but in the case of another bot messing up the channel topic (happened to a user before) this extra step was added. # v2.17.0 ### What's new? -Added a config option `reply_without_command`, which, when present, enables the bot to forward any message sent in a thread channel to the recipient. (Replying without using a command) +Added a config option `reply_without_command` which when present, enables the bot to forward any message sent in a thread channel to the recipient. (Replying without using a command) To enable this functionality, do `?config set reply_without_command true` and to disable it, use `?config del reply_without_command`. ### Changed -The `move` command now only requires `manage_messages` perms instead of `manage_channels`. +The `move` command now only requires `manage_messages` perms instead of `manage_channels` # v2.16.1 ### Fixed -An issue where a scheduled close would not execute over a long time if the recipient no shares any servers with the bot. +An issue where a scheduled close would not execute over a long period of time if the recipient no shares any servers with the bot. # v2.16.0 @@ -526,8 +516,8 @@ Added the ability to change the default close message via the introduction of tw They will be provided by string variables that you can incorporate into them: - `closer` - the user object that closed the thread. -- `logkey` - the key for the thread logs, e.g. (`5219ccc82ad4`) -- `loglink` - the full link to the thread logs, e.g. (`https://logwebsite.com/logs/5219ccc82ad4`) +- `logkey` - the key for the thread logs e.g. (`5219ccc82ad4`) +- `loglink` - the full link to the thread logs e.g. (`https://logwebsite.com/logs/5219ccc82ad4`) Example usage would be: ``?config set thread_close_message {closer.mention} closed the thread, here is the link to your logs: [**`{logkey}`**]({loglink})`` @@ -556,9 +546,9 @@ You now have complete control of the look of the thread creation and close embed ### What's new? -Added the ability to disable the `sent_emoji` and `blocked_emoji` when a user messages Modmail. +Added the ability to disable the `sent_emoji` and `blocked_emoji` when a user messages modmail. -You can do this via `?config set sent_emoji disable`. +You can do this via `?config set sent_emoji disable` ### Fixed @@ -575,17 +565,17 @@ Added image link in title in case discord fails to embed an image. - Introduced a new configuration variable `account_age` for setting a minimum account creation age. - Users blocked by this reason will be stored in `blocked` along with other reasons for being blocked. - `account_age` needs to be an ISO-8601 Duration Format (examples: `P12DT3H` 12 days and 3 hours, `P3Y5M` 3 years and 5 months `PT4H14M999S` 4 hours 14 minutes and 999 seconds). https://en.wikipedia.org/wiki/ISO_8601#Durations. - - You can set `account_age` using `config set account_age time` where "time" can be a simple human-readable time string or an ISO-8601 Duration Format string. + - You can set `account_age` using `config set account_age time` where "time" can be a simple human readable time string or an ISO-8601 Duration Format string. ### Changed -- `?block` reason cannot start with `System Message: ` as it is now reserved for internal user blocking. -- `?block`, like `?close`, now supports a block duration (temp blocking). +- `block` reason cannot start with `System Message: ` as it is now reserved for internal user blocking. +- `block`, like `close`, now supports a block duration (temp blocking). # v2.13.10 ### Fixed - Fixed an issue where status and activity do not work if they were modified wrongly in the database. - - This was primarily an issue for older Modmail users, as the old `status` configuration variable clashes with the new `status` variable. + - This was especially an issue for older Modmail users, as the old `status` configuration variable clashes with the new `status` variable. # v2.13.9 @@ -604,7 +594,7 @@ Added image link in title in case discord fails to embed an image. ### What's new? - The ability to enable typing interactions. - - If you want the bot to type in the thread channel if the user is also typing, add the config variable `user_typing` and set it to "yes" or "true". Use `config del` to disable the functionality. The same thing in reverse is also possible if you want the user to see the bot type when someone is typing in the thread channel add the `mod_typing` config variable. + - If you want the bot to type in the thread channel if the user is also typing, add the config variable `user_typing` and set it to "yes" or "true". use `config del` to disable the functionality. The same thing in reverse is also possible if you want the user to see the bot type when someone is typing in the thread channel add the `mod_typing` config variable. - New `status` command, change the bot's status to `online`, `idle`, `dnd`, `invisible`, or `offline`. - To remove the status (change it back to default), use `status clear`. - This also introduces a new internal configuration variable: `status`. Possible values are `online`, `idle`, `dnd`, `invisible`, and `offline`. @@ -621,15 +611,15 @@ Added image link in title in case discord fails to embed an image. ### What's new? - You will no longer need to view your bot debug logs from Heroku. `debug` will show you the recent logs within 24h through a series of embeds. - - If you don't mind your data (may or may not be limited to user ID, guild ID, bot name) be on the internet, `debug hastebin` will upload a formatted logs file to https://hasteb.in. + - If you don't mind your data (may or may not be limited to: user ID, guild ID, bot name) be on the internet, `debug hastebin` will upload a formatted logs file to https://hasteb.in. - `debug clear` will clear the locally cached logs. - - Local logs are automatically erased at least once every 27h for bots hosted on Heroku. + - Local logs are automatically cleared at least once every 27h for bots hosted on Heroku. ### Fixed -- Will no longer show `Unclosed client session` and `Task was destroyed, but it is pending!` when the bot terminates. +- Will no longer show `Unclosed client session` and `Task was destroyed but it is pending!` when the bot terminates. - `thread.create` is now synchronous so that the first message sent can be queued to be sent as soon as a thread is created. - This fixes a problem where if multiple messages are sent in quick succession, the first message sent (which triggers the thread creation) is not sent in order. -- Trying to reply to someone who has DMs disabled or has blocked the bot is now handled, and the bot will send a message saying so. +- Trying to reply to someone who has DMs disabled or has blocked the bot is now handled and the bot will send a message saying so. ### Changed - `print` is replaced by logging. @@ -663,14 +653,14 @@ Added image link in title in case discord fails to embed an image. ### What's new? - Plugins: - - Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it. Add a welcome message to Modmail, or moderation commands? It's all up to your imagination! Have a niche feature request that you think only your server would benefit? Plugins are your go-to! + - Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it. Add a welcome message to Modmail, or moderation commands? It's all up to your imagination! Have a niche feature request that you think only your server would benefit from? Plugins are your go-to! - [Creating Plugins Documentation](https://github.com/kyb3r/modmail/wiki/Plugins). # v2.12.5 ### Fixed -- `config del` command will now work correctly on self-hosted DB bots. +- `config del` command will now work properly on self-hosted db bots. # v2.12.4 @@ -684,14 +674,14 @@ Added image link in title in case discord fails to embed an image. ### Fixed - Patched a bug where `logs` sub-commands were accessible by anyone. -- Patched a bug where an error was raised when a thread is open where the recipient left the server. +- Patched a bug where an error was raised if there was an open thread where the recipient had left the server. Huge thanks to Sasiko for reporting these issues. # v2.12.2 ### Fixed -- Fixed a bug in self-hosted `?update` command. +- Fixed a bug in self-hosted `update` command. # v2.12.1 @@ -702,12 +692,12 @@ Huge thanks to Sasiko for reporting these issues. # v2.12.0 ### Important -**In the future, the Modmail API (https://modmail.tk) will be deprecated. This is because we are providing free service without getting anything in return. Thus we do not have the resources to scale to accommodate more users. +**In the future, the Modmail API (https://modmail.tk) will be deprecated. This is due to the fact that we are providing a free service without getting anything in return, and thus we do not have the resources to scale to accommodate for more users. We recommend using your own database for logs. In the future you will soon get a `backup` command so you can download all your pre-existing data and migrate to your own database.** ### Changed - A lot of painful code cleanup, which is good for us (the developers), but shouldn't affect you. -- The appearance of the `?logs` command. It should be clearer with better info now. +- The appearance of the `logs` command. Should be clearer with better info now. - Bot owners get access to all commands regardless of server permissions. - Blocked users no longer receive a message, only the blocked emoji will be sent. @@ -715,10 +705,10 @@ We recommend using your own database for logs. In the future you will soon get a - **Note:** The following commands only work if you are self-hosting your logs. We recommend you to use your own database. - Log search queries, in the form of two new commands. - `logs search [query]` - this searches all log messages for a query string. -- `logs closed-by [user]` this returns all logs closed by a particular user +- `logs closed-by [user]` this returns all logs closed by a certain user ### Fixed -- `activity listening to music` no longer results in two "to"s ("listening to to music"). +- `activity listening to music` no longer result in two "to"s ("listening to to music"). - This may require you to change your activity message to accommodate this fix. - A problem where `main_category_id` and `log_channel_id` weren't updated when their corresponding channel or category get deleted. @@ -741,7 +731,7 @@ We recommend using your own database for logs. In the future you will soon get a ### What's new? - `anonreply` command to anonymously reply to the recipient. -The username of the anonymous user defaults to the `mod_tag` (the footer text of a mod reply message) — the avatar defaults to the guild icon URL. However, you can change both of these via the `anon_username`, `anon_avatar_url`, and `anon_tag` config variables. +The username of the anonymous user defaults to the `mod_tag` (the footer text of a mod reply message). The avatar defaults the guild icon URL. However you can change both of these via the `anon_username`, `anon_avatar_url` and `anon_tag` config variables. ### Changed - Your bot now logs all messages sent in a thread channel, including discussions that take place. You can now toggle to view them in the log viewer app. @@ -766,7 +756,7 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of - All commands are now blurple instead of green. ### Fixed -- Bug where the close command wouldn't work if you didn't configure a log channel. +- Bug where the close command wouldn't work if you didnt configure a log channel. ### What's new? - Ability to set your own custom `mod_color` and `recipient_color` for the thread message embeds. @@ -783,13 +773,13 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of # v2.9.0 ### What's new? -- New command `note` will add a system message to your thread logs. - - This is useful for noting the context of a conversation. +- New command `note` will add a system message to your thread logs. This is useful for noting the context of a conversation. # v2.8.1 ### Fixed - Fixed bug where thread logs were getting duplicated when using the `contact` command. -- Fixed bug where the wrong key was used for logs, which caused some `log` command log links to point to an HTTP 404 Not Found. +- Fixed bug where the wrong key was used for logs which caused some `log` command log links to point to an HTTP 404 Not Found. - A minor oversight from commit 1ba74d9. # v2.8.0 @@ -806,7 +796,7 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of ### Security Thread channels will now default to being private (`@everyone`'s read message perms set to `false`). - If the thread creation category could not be resolved. - - This will save you from some trouble if, for whatever reason, your configuration gets messed up. + - This will save you from some trouble if for whatever reason your configuration gets messed up. # v2.7.1 @@ -818,20 +808,20 @@ Thread channels will now default to being private (`@everyone`'s read message pe ### Note -- If your Modmail bot was set up a long time ago, you might experience an issue where messages were sent outside of the category. +- If your Modmail bot was set up a long time ago, you may experience an issue where messages were sent outside of the category. - To fix this, set `main_category_id` to the ID of the Modmail category. # v2.7.0 ### Changed -- `move` command now syncs thread channel permissions with the destination category. +- `move` command now syncs thread channel permissions with the category that it was moved to. - `contact` command now supports an optional category argument (where the thread channel will be created). # v2.6.3 ### Fixes -- Fixed small issue with finding threads. +- Fixed small issue with finding thread. # v2.6.2 @@ -851,8 +841,8 @@ Thread channels will now default to being private (`@everyone`'s read message pe ### Changed - Log URLs are moved to their own collection. - Log URLs are now `https://logs.modmail.tk/LOGKEY`, no more numbers before the log key. -- We still support the numbers to not break everyone's URLs so quickly, but both work at the moment. -- This is a huge change to the backend logging, and there might be migration errors. If so, please contact us in our [Discord server](https://discord.gg/2fMbf2N). +- We still support the numbers so as to not break everyone's URLs so quickly but both work at the moment. +- This is a huge change to the backend logging and there might be migration errors. If so, please contact us in our [discord server](https://discord.gg/2fMbf2N). # v2.5.2 @@ -862,13 +852,13 @@ Thread channels will now default to being private (`@everyone`'s read message pe # v2.5.1 ### Fixes -- Emergency patch to save configs. +- Emergency patch to save config. # v2.5.0 ### Background - Bots hosted by Heroku restart at least once every 27 hours. -- During this period, local caches will be deleted, which results in the inability to set the scheduled close time to longer than 24 hours. This update resolves this issue. +- During this period, local caches are deleted, which results in the inability to set the scheduled close time to longer than 24 hours. This update resolves this issue. - [PR #135](https://github.com/kyb3r/modmail/pull/135) ### Changed @@ -886,7 +876,7 @@ Fixed activity setting due to flawed logic in `config.get()` function. # v2.4.4 ### Fixed -Fixed a bug in the `?activity` command where it would fail to set the activity on bot restart if the activity type was `playing`. +Fixed a bug in activity command where it would fail to set the activity on bot restart if the activity type was `playing`. # v2.4.3 @@ -901,17 +891,17 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o # v2.4.1 ### Fixed -- Small bug in `?activity` command. +- Small bug in `activity` command. # v2.4.0 ### What's new? -- Added the `?activity` command for setting the activity -- [PR #131](https://github.com/kyb3r/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening`, and `streaming`). +- Added the `activity` command for setting the activity +- [PR #131](https://github.com/kyb3r/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening` and `streaming`). ### Removed - Removed the deprecated `status` command. -- This also means you will have to reset your bot status with the `?activity` command, as the `?status` command was removed. +- This also means you will have to reset your bot status with the `activity` command, as `status` command is removed. # v2.3.0 @@ -932,7 +922,7 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o ### What's new? - Notify command `notify [role]`. - Notify a given role or yourself to the next thread message received. - - Once a thread message is received, you will be pinged once only. + - Once a thread message is received you will be pinged once only. - Subscribe command `sub [role]` / `unsub [role]`. - Subscribes yourself or a given role to be notified when thread messages are received. @@ -949,15 +939,15 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o # v2.1.0 ### What's new? -- Ability to set a custom thread-creation-response message. +- Ability to set a custom thread creation response message. - Via `config set thread_creation_response [message]`. ### Changed -- Improve `?logs` command format. -- Improve thread log channel messages to have more relevant info. +- Improve logs command format. +- Improve thread log channel message to have more relevant info. - Improve close command. - - You can now close the thread after a delay and use a custom thread close message. - - You also now can close a thread silently. + - You now can close the thread after a delay and use a custom thread close message. + - You also now have the ability to close a thread silently. # v2.0.10 @@ -972,7 +962,7 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o ### Fixes - Support multiple images and file attachments in one message. -- This is only possible on mobile, so its good to handle it in code. +- This is only possible on mobile so its good to handle it in code. # v2.0.8 @@ -983,7 +973,7 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o - You can do this via the `config set main_category_id ` command. ### Changed -- You can now supply a reason when blocking a user. +- You now have the ability to supply a reason when blocking a user. - Blocked users are now stored in the database instead of in the channel topic. - This means you can delete the top channel in the Modmail category now (after migrating the currently blocked users). @@ -994,8 +984,8 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o ### Changed - `update` command now shows the latest changes directly from CHANGELOG.md. -- Auto-update messages also show the latest changes from the GitHub repo. -- Removed the "latest changes" section from the `about` command. +- Auto update messages also show the latest changes from the GitHub repo. +- Removed "latest changes" section from the `about` command. # v2.0.6 @@ -1008,20 +998,20 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o ### Changed - `alias` command now checks if you are adding a valid alias-command combo. -- Manually deleting a channel will now correctly close the thread and post logs. +- Deleting a channel manually will now correctly close the thread and post logs. # v2.0.4 ### Fixed -- Fixed a one-off bug where the channel topic disappears, but Modmail operations should continue. +- Fixed a one-off bug where the channel topic disappears, but Modmail operations should still continue. - Fixed `linked_message_id` issues. # v2.0.3 ### Fixed -- The thread creation embed now shows the correct number of past logs. +- Thread creation embed now shows the correct number of past logs. - If using a separate server setup, roles in the info embed now are shown as names instead of mentions. - - This is because you can't mention roles across servers. + - This is due to the fact that you can't mention roles across servers. # v2.0.2 @@ -1033,7 +1023,7 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o ### Changed - Improved `block` / `unblock` commands. - - They now take a more comprehensive range of arguments: usernames, nicknames, mentions, and user IDs. + - They now take a wider range of arguments: usernames, nicknames, mentions and user IDs. ### Fixed - Setup command now configures permissions correctly so that the bot will always be able to see the main operations category. @@ -1041,7 +1031,7 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o # v2.0.0 This release introduces the use of our centralized [API service](https://github.com/kyb3r/webserver) to enable dynamic configuration, auto-updates, and thread logs. -To use this release, you must acquire an API token from https://modmail.tk. +To use this release you must acquire an API token from https://modmail.tk. Read the updated installation guide [here](https://github.com/kyb3r/modmail/wiki/installation). ### Changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 568e5f2175..a95e344610 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,32 +15,33 @@ We use GitHub to host code, to track issues and feature requests, as well as acc ## We Use [Git Flow](https://atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) ![Simple Image Of A Git Flow Workflow](https://nvie.com/img/hotfix-branches@2x.png) -When contributing to this project, please make sure you follow this and name your branches appropriately! +When contributing to this project please make sure you follow this and name your branches appropriately! ## All Code Changes Happen Through Pull Requests Make sure you know how Git Flow works before contributing! Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests: 1. Fork the repo and create your branch from `master` or `development` according to Git Flow. -2. Update the CHANGELOG. -3. If you've changed `core/*` or `bot.py`, mark changelog as "BREAKING" since plugins may break. -4. Make sure your code passes the lint checks. -5. Create Issues and pull requests! +2. If you've added code that should be tested, add tests. +3. If you've changed APIs, update the documentation. +4. Ensure the test suite passes. +5. Make sure your code lints. +6. Issue that pull request! ## Any contributions you make will be under the GNU Affero General Public License v3.0 In short, when you submit code changes, your submissions are understood to be under the same [GNU Affero General Public License v3.0](https://www.gnu.org/licenses/agpl-3.0.en.html) that covers the project. Feel free to contact the maintainers if that's a concern. ## Report bugs using [Github Issues](https://github.com/kyb3r/modmail/issues) -We use GitHub issues to track public bugs. Report a bug by [opening a new Issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! +We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! ## Write bug reports with detail, background, and sample code **Great Bug Reports** tend to have: -- A quick summary and background +- A quick summary and/or background - Steps to reproduce - Be specific! - What you expected would happen -- What *actually* happens +- What actually happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) diff --git a/README.md b/README.md index 4b36c5a3d2..52e4c4abd8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
@@ -31,6 +31,10 @@ Made with Python 3.7 + + + + @@ -46,25 +50,25 @@ ## What is Modmail? -Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way. +Modmail is similar to Reddit's Modmail both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way. This bot is free for everyone and always will be. If you like this project and would like to show your appreciation, you can support us on **[Patreon](https://www.patreon.com/kyber)**, cool benefits included! ## How does it work? -When a member sends a direct message to the bot, Modmail will create a channel or "thread" into a designated category. All further DM messages will automatically relay to that channel; any available staff can respond within the channel. +When a member sends a direct message to the bot, Modmail will create a channel or "thread" within an isolated category. All further DM messages will automatically relay to that channel, for any available staff can respond within the channel. -Our Logviewer will save the threads so you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.logviewer.tech/example). +All threads are logged and you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.logviewer.tech/example). ## Features * **Highly Customisable:** * Bot activity, prefix, category, log channel, etc. * Command permission system. - * Interface elements (color, responses, reactions, etc.). + * Interface elements (color, responses, reactions, etc). * Snippets and *command aliases*. * Minimum duration for accounts to be created before allowed to contact Modmail (`account_age`). - * Minimum length for members to be in the guild before allowed to contact Modmail (`guild_age`). + * Minimum duration for members to be in the guild before allowed to contact Modmail (`guild_age`). * **Advanced Logging Functionality:** * When you close a thread, Modmail will generate a [log link](https://logs.logviewer.tech/example) and post it to your log channel. @@ -86,11 +90,11 @@ This list is ever-growing thanks to active development and our exceptional contr Where can I find the Modmail bot invite link? -Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time). +Unfortunately, due to how this bot functions, it cannot be invited. This is to ensure the individuality to your server and grant you full control over your bot and data. Nonetheless, you can easily obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time)... ### Heroku -You can host this bot on Heroku. +This bot can be hosted on Heroku. Installation via Heroku is possible with your web browser alone. The [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) (which includes a video tutorial!) will guide you through the entire installation process. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. @@ -104,11 +108,11 @@ To configure automatic updates: ### Hosting for Patreons -If you don't want to go through the trouble of setting up your very own Modmail bot or wish to support this project, we got a solution for you! We offer the complete installation, hosting, and maintenance of your Modmail with [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! +If you don't want to go through the trouble of setting up your very own Modmail bot, and/or want to support this project, we offer the all inclusive installation, hosting and maintenance of your Modmail with [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! ### Locally -Local hosting of Modmail is also possible. First, you will need [`Python 3.7`](https://www.python.org/downloads/release/python-376/). +Local hosting of Modmail is also possible, first you will need [`Python 3.7`](https://www.python.org/downloads/). Follow the [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) and disregard deploying the Heroku bot application. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. @@ -143,7 +147,7 @@ You can build your own Docker image: $ docker build . --tag=modmail ``` -Or run directly from a pre-built version from https://hub.docker.com/. +or run directly from a pre-built version from https://hub.docker.com/. Currently there are two community release of Modmail: - Kyber's: @@ -151,12 +155,22 @@ Or run directly from a pre-built version from https://hub.docker.com/. $ docker pull kyb3rr/modmail ``` +- Taku's: + +```console +$ docker pull taaku18/modmail +# You can also choose one of the following: +$ docker pull taaku18/modmail:dev +$ docker pull taaku18/modmail: ( ex: 3.2.0, 3.2, etc.) +``` + And to run your docker image: ```console -$ docker run --env-file .env kyb3rr/modmail +$ docker run --env-file .env user/modmail ``` -- `.env` should be the path to your env file; you can also supply a path: `/path/to/.env`. +- Replace `user/modmail` with `kyb3rr/modmail`, `taaku18/modmail`, `taaku18/modmail:3.2`, etc as above. +- `.env` should be the path to your env file, you can also supply a path: `/path/to/.env`. ## Sponsors @@ -166,7 +180,7 @@ Special thanks to our sponsors for supporting the project. - + @@ -175,9 +189,9 @@ Become a sponsor on [Patreon](https://patreon.com/kyber). ## Plugins Modmail supports the use of third-party plugins to extend or add functionalities to the bot. -Plugins allow niche features as well as anything else outside of the scope of the core functionality of Modmail. +This allows niche features as well as anything else outside of the scope of the core functionality of Modmail. -You can find a list of third-party plugins using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/kyb3r/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. +A list of third-party plugins can be found using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/kyb3r/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. To develop your own, check out the [plugins documentation](https://github.com/kyb3r/modmail/wiki/Plugins). @@ -185,6 +199,6 @@ Plugins requests and support is available in our [Modmail Plugins Server](https: ## Contributing -Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. +Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our contribution [guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. If you like this project and would like to show your appreciation, support us on **[Patreon](https://www.patreon.com/kyber)**! diff --git a/bot.py b/bot.py index 24f1218585..ddbeec2d31 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.4.1" +__version__ = "3.5.0-dev0" import asyncio @@ -31,7 +31,7 @@ except ImportError: pass -from core import checks +from core import checks, translations from core.clients import ApiClient, PluginDatabaseClient from core.config import ConfigManager from core.utils import human_join, normalize_alias @@ -48,7 +48,7 @@ class ModmailBot(commands.Bot): - def __init__(self, args): + def __init__(self): super().__init__(command_prefix=None) # implemented in `get_prefix` self._session = None self._api = None @@ -58,10 +58,7 @@ def __init__(self, args): self._connected = asyncio.Event() self.start_time = datetime.utcnow() - if len(args): - self.config = ConfigManager(self, args[0]) - else: - self.config = ConfigManager(self) + self.config = ConfigManager(self) self.config.populate_cache() self.threads = ThreadManager(self) @@ -472,7 +469,7 @@ async def on_ready(self): { "open": False, "closed_at": str(datetime.utcnow()), - "close_message": "Channel has been deleted, no closer found.", + "close_message": _("Channel has been deleted, no closer found."), "closer": { "id": str(self.user.id), "name": self.user.name, @@ -552,7 +549,7 @@ def check_account_age(self, author: discord.Member) -> bool: logger.debug("Blocked due to account age, user %s.", author.name) if str(author.id) not in self.blocked_users: - new_reason = f"System Message: New Account. Required to wait for {delta}." + new_reason = _("System Message: New Account. Required to wait for {time}.").format(time=delta) self.blocked_users[str(author.id)] = new_reason return False @@ -618,7 +615,7 @@ def check_manual_blocked(self, author: discord.Member) -> bool: return False async def _process_blocked(self, message): - _, blocked_emoji = await self.retrieve_emoji() + x, blocked_emoji = await self.retrieve_emoji() if await self.is_blocked(message.author, channel=message.channel, send_message=True): await self.add_reaction(message, blocked_emoji) return True @@ -988,7 +985,7 @@ async def handle_reaction_events(self, payload, *, add): if not thread: return try: - _, linked_message = await thread.find_linked_messages( + x, linked_message = await thread.find_linked_messages( message.id, either_direction=True ) except ValueError as e: @@ -1072,32 +1069,19 @@ async def on_member_join(self, member): async def on_message_delete(self, message): """Support for deleting linked messages""" # TODO: use audit log to check if modmail deleted the message - if isinstance(message.channel, discord.DMChannel): - thread = await self.threads.find(recipient=message.author) - if not thread: - return + if message.embeds and not isinstance(message.channel, discord.DMChannel): + thread = await self.threads.find(channel=message.channel) try: - message = await thread.find_linked_message_from_dm(message) + await thread.delete_message(message) except ValueError as e: - if str(e) != "Thread channel message not found.": + if str(e) not in {"DM message not found.", " Malformed thread message."}: logger.warning("Failed to find linked message to delete: %s", e) - return + else: + thread = await self.threads.find(recipient=message.author) + message = await thread.find_linked_message_from_dm(message) embed = message.embeds[0] embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=embed.footer.icon_url) await message.edit(embed=embed) - return - - thread = await self.threads.find(channel=message.channel) - if not thread: - return - try: - await thread.delete_message(message, note=False) - except ValueError as e: - if str(e) not in {"DM message not found.", "Malformed thread message."}: - logger.warning("Failed to find linked message to delete: %s", e) - return - except discord.NotFound: - return async def on_bulk_message_delete(self, messages): await discord.utils.async_all(self.on_message_delete(msg) for msg in messages) @@ -1110,13 +1094,10 @@ async def on_message_edit(self, before, after): if isinstance(after.channel, discord.DMChannel): thread = await self.threads.find(recipient=before.author) - if not thread: - return - try: await thread.edit_dm_message(after, after.content) except ValueError: - _, blocked_emoji = await self.retrieve_emoji() + x, blocked_emoji = await self.retrieve_emoji() await self.add_reaction(after, blocked_emoji) else: embed = discord.Embed( @@ -1227,7 +1208,7 @@ async def before_post_metadata(self): self.metadata_loop.cancel() -def main(args): +def main(): try: # noinspection PyUnresolvedReferences import uvloop @@ -1237,9 +1218,10 @@ def main(args): except ImportError: pass - bot = ModmailBot(args) + translations.init() + bot = ModmailBot() bot.run() if __name__ == "__main__": - main(sys.argv[1:]) + main() diff --git a/cogs/modmail.py b/cogs/modmail.py index 3b9c591294..7f5b2fe15b 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -41,17 +41,17 @@ async def setup(self, ctx): if ctx.guild != self.bot.modmail_guild: return await ctx.send( - f"You can only setup in the Modmail guild: {self.bot.modmail_guild}." + _("You can only setup in the Modmail guild: {guild_name}.".format(guild_name=self.bot.modmail_guild)) ) if self.bot.main_category is not None: logger.debug("Can't re-setup server, main_category is found.") - return await ctx.send(f"{self.bot.modmail_guild} is already set up.") + return await ctx.send(_("{guild_name} is already set up.").format(guild_name=self.bot.modmail_guild)) if self.bot.modmail_guild is None: embed = discord.Embed( - title="Error", - description="Modmail functioning guild not found.", + title=_("Error"), + description=_("Modmail functioning guild not found."), color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -88,21 +88,23 @@ async def setup(self, ctx): ) embed = discord.Embed( - title="Friendly Reminder", - description=f"You may use the `{self.bot.prefix}config set log_channel_id " - "` command to set up a custom log channel, then you can delete this default " - f"{log_channel.mention} log channel.", + title=_("Friendly Reminder"), + description=_("You may use the `{prefix}config set log_channel_id " + "` command to set up a custom log channel, then you can delete this default " + "{log_channel} log channel.").format(prefix=self.bot.prefix, log_channel=log_channel.mention), color=self.bot.main_color, ) embed.add_field( - name="Thanks for using our bot!", - value="If you like what you see, consider giving the " - "[repo a star](https://github.com/kyb3r/modmail) :star: and if you are " - "feeling extra generous, buy us coffee on [Patreon](https://patreon.com/kyber) :heart:!", + name=_("Thanks for using the bot!"), + value=_("If you like what you see, consider giving the " + "[repo a star](https://github.com/kyb3r/modmail) :star: or if you are " + "feeling generous, check us out on [Patreon](https://patreon.com/kyber)!"), ) - embed.set_footer(text=f'Type "{self.bot.prefix}help" for a complete list of commands.') + embed.set_footer( + text=_('Type "{prefix}help" for a complete list of commands.').format(prefix=self.bot.prefix) + ) await log_channel.send(embed=embed) self.bot.config["main_category_id"] = category.id @@ -110,12 +112,12 @@ async def setup(self, ctx): await self.bot.config.update() await ctx.send( - "**Successfully set up server.**\n" - "Consider setting permission levels to give access to roles " - "or users the ability to use Modmail.\n\n" - f"Type:\n- `{self.bot.prefix}permissions` and `{self.bot.prefix}permissions add` " - "for more info on setting permissions.\n" - f"- `{self.bot.prefix}config help` for a list of available customizations." + _("**Successfully set up server.**\n" + "Consider setting permission levels " + "to give access to roles or users the ability to use Modmail.\n\n" + "Type:\n- `{prefix}permissions` and `{prefix}permissions add` " + "for more info on setting permissions.\n" + "- `{prefix}config help` for a list of available customizations.").format(prefix=self.bot.prefix) ) if not self.bot.config["command_permissions"] and not self.bot.config["level_permissions"]: @@ -170,7 +172,7 @@ async def snippet(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): description = format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url) + embed.set_author(name=_("Snippets"), icon_url=ctx.guild.icon_url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -212,25 +214,25 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte """ if name in self.bot.snippets: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"Snippet `{name}` already exists.", + description=_("Snippet `{name}` already exists.").format(name=name), ) return await ctx.send(embed=embed) if name in self.bot.aliases: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"An alias that shares the same name exists: `{name}`.", + description=_("An alias with the same name already exists: `{name}`.").format(name=name), ) return await ctx.send(embed=embed) if len(name) > 120: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description="Snippet names cannot be longer than 120 characters.", + description=_("Snippet names cannot be longer than 120 characters."), ) return await ctx.send(embed=embed) @@ -251,9 +253,9 @@ async def snippet_remove(self, ctx, *, name: str.lower): if name in self.bot.snippets: embed = discord.Embed( - title="Removed snippet", + title=_("Removed snippet"), color=self.bot.main_color, - description=f"Snippet `{name}` is now deleted.", + description=_("Snippet `{name}` is now deleted.").format(name=name), ) self.bot.snippets.pop(name) await self.bot.config.update() @@ -276,9 +278,9 @@ async def snippet_edit(self, ctx, name: str.lower, *, value): await self.bot.config.update() embed = discord.Embed( - title="Edited snippet", + title=_("Edited snippet"), color=self.bot.main_color, - description=f'`{name}` will now send "{value}".', + description=f_('`{name}` will now send "{value}".'), ) else: embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") @@ -305,13 +307,13 @@ async def move(self, ctx, category: discord.CategoryChannel, *, specifics: str = if self.bot.config["thread_move_notify"] and not silent: embed = discord.Embed( - title="Thread Moved", + title=_("Thread Moved"), description=self.bot.config["thread_move_response"], color=self.bot.main_color, ) await thread.recipient.send(embed=embed) - sent_emoji, _ = await self.bot.retrieve_emoji() + sent_emoji, x = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) async def send_scheduled_close_message(self, ctx, after, silent=False): @@ -320,15 +322,17 @@ async def send_scheduled_close_message(self, ctx, after, silent=False): silent = "*silently* " if silent else "" embed = discord.Embed( - title="Scheduled close", - description=f"This thread will close {silent}in {human_delta}.", + title=_("Scheduled close"), + description=_("This thread will close {silent}in {time}.").format(silent=silent, time=human_delta), color=self.bot.error_color, ) if after.arg and not silent: - embed.add_field(name="Message", value=after.arg) + embed.add_field(name=_("Message"), value=after.arg) - embed.set_footer(text="Closing will be cancelled if a thread message is sent.") + embed.set_footer( + text=_("Closing will be cancelled if a thread message is sent.") + ) embed.timestamp = after.dt await ctx.send(embed=embed) @@ -362,20 +366,21 @@ async def close(self, ctx, *, after: UserFriendlyTime = None): close_after = (after.dt - now).total_seconds() if after else 0 message = after.arg if after else None - silent = str(message).lower() in {"silent", "silently"} - cancel = str(message).lower() == "cancel" + silent = str(message).lower() in {_("silent"), _("silently")} + cancel = str(message).lower() == _("cancel") if cancel: if thread.close_task is not None or thread.auto_close_task is not None: await thread.cancel_closure(all=True) embed = discord.Embed( - color=self.bot.error_color, description="Scheduled close has been cancelled." + color=self.bot.error_color, + description=_("Scheduled close has been cancelled."), ) else: embed = discord.Embed( color=self.bot.error_color, - description="This thread has not already been scheduled to close.", + description=_("This thread has not already been scheduled to close."), ) return await ctx.send(embed=embed) @@ -425,14 +430,15 @@ async def notify( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=f"{mention} is already going to be mentioned.", + description=_("{mention} is already going to be mentioned.").format(mention=mention), ) else: mentions.append(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=f"{mention} will be mentioned on the next message received.", + description=_("{mention} will be mentioned " + "on the next message received.").format(mention=mention), ) return await ctx.send(embed=embed) @@ -463,13 +469,14 @@ async def unnotify( if mention not in mentions: embed = discord.Embed( color=self.bot.error_color, - description=f"{mention} does not have a pending notification.", + description=_("{mention} does not have a pending notification.").format(mention=mention), ) else: mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( - color=self.bot.main_color, description=f"{mention} will no longer be notified." + color=self.bot.main_color, + description=_("{mention} will no longer be notified.").format(mention=mention), ) return await ctx.send(embed=embed) @@ -502,14 +509,15 @@ async def subscribe( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=f"{mention} is not subscribed to this thread.", + description=_("{mention} is already subscribed to this thread.").format(mention=mention), ) else: mentions.append(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=f"{mention} will now be notified of all messages received.", + description=_("{mention} will now be " + "notified of all messages received.").format(mention=mention), ) return await ctx.send(embed=embed) @@ -540,14 +548,14 @@ async def unsubscribe( if mention not in mentions: embed = discord.Embed( color=self.bot.error_color, - description=f"{mention} is not already subscribed to this thread.", + description=_("{mention} is not already subscribed to this thread.").format(mention=mention), ) else: mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=f"{mention} is now unsubscribed from this thread.", + description=_("{mention} is now unsubscribed to this thread.").format(mention=mention), ) return await ctx.send(embed=embed) @@ -557,7 +565,7 @@ async def unsubscribe( async def nsfw(self, ctx): """Flags a Modmail thread as NSFW (not safe for work).""" await ctx.channel.edit(nsfw=True) - sent_emoji, _ = await self.bot.retrieve_emoji() + sent_emoji, x = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -566,7 +574,7 @@ async def nsfw(self, ctx): async def sfw(self, ctx): """Flags a Modmail thread as SFW (safe for work).""" await ctx.channel.edit(nsfw=False) - sent_emoji, _ = await self.bot.retrieve_emoji() + sent_emoji, x = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -599,24 +607,26 @@ def format_log_embeds(self, logs, avatar_url): embed.add_field(name="Created", value=duration(created_at, now=datetime.utcnow())) closer = entry.get("closer") if closer is None: - closer_msg = "Unknown" + closer_msg = _("Unknown") else: closer_msg = f"<@{closer['id']}>" - embed.add_field(name="Closed By", value=closer_msg) + embed.add_field(name=_("Closed By"), value=closer_msg) if entry["recipient"]["id"] != entry["creator"]["id"]: - embed.add_field(name="Created by", value=f"<@{entry['creator']['id']}>") + embed.add_field(name=_("Created by"), value=f"<@{entry['creator']['id']}>") - embed.add_field(name="Preview", value=format_preview(entry["messages"]), inline=False) + embed.add_field( + name=_("Preview"), value=format_preview(entry["messages"]), inline=False + ) if closer is not None: # BUG: Currently, logviewer can't display logs without a closer. - embed.add_field(name="Link", value=log_url) + embed.add_field(name=_("Link"), value=log_url) else: logger.debug("Invalid log entry: no closer.") - embed.add_field(name="Log Key", value=f"`{entry['key']}`") + embed.add_field(name=_("Log Key"), value=f"`{entry['key']}`") - embed.set_footer(text="Recipient ID: " + str(entry["recipient"]["id"])) + embed.set_footer(text=_("Recipient ID") + ": " + str(entry["recipient"]["id"])) embeds.append(embed) return embeds @@ -647,7 +657,7 @@ async def logs(self, ctx, *, user: User = None): if not any(not log["open"] for log in logs): embed = discord.Embed( color=self.bot.error_color, - description="This user does not have any previous logs.", + description=_("This user does not have any previous logs."), ) return await ctx.send(embed=embed) @@ -680,7 +690,7 @@ async def logs_closed_by(self, ctx, *, user: User = None): if not embeds: embed = discord.Embed( color=self.bot.error_color, - description="No log entries have been found for that query.", + description=_("No log entries have been found for that query"), ) return await ctx.send(embed=embed) @@ -699,14 +709,14 @@ async def logs_delete(self, ctx, key_or_link: str): if not success: embed = discord.Embed( - title="Error", - description=f"Log entry `{key}` not found.", + title=_("Error"), + description=_("Log entry `{key}` not found.").format(key=key), color=self.bot.error_color, ) else: embed = discord.Embed( title="Success", - description=f"Log entry `{key}` successfully deleted.", + description=_("Log entry `{key}` successfully deleted.").format(key=key), color=self.bot.main_color, ) @@ -730,7 +740,7 @@ async def logs_responded(self, ctx, *, user: User = None): if not embeds: embed = discord.Embed( color=self.bot.error_color, - description=f"{getattr(user, 'mention', user.id)} has not responded to any threads.", + description=_("{mention} has not responded to any threads.").format(mention=getattr(user, 'mention', user.id)), ) return await ctx.send(embed=embed) @@ -763,7 +773,7 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): if not embeds: embed = discord.Embed( color=self.bot.error_color, - description="No log entries have been found for that query.", + description=_("No log entries have been found for that query."), ) return await ctx.send(embed=embed) @@ -856,13 +866,13 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): except ValueError: return await ctx.send( embed=discord.Embed( - title="Failed", - description="Cannot find a message to edit.", + title=_("Failed"), + description=_("Cannot find a message to edit."), color=self.bot.error_color, ) ) - sent_emoji, _ = await self.bot.retrieve_emoji() + sent_emoji, x = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -886,7 +896,8 @@ async def contact( if user.bot: embed = discord.Embed( - color=self.bot.error_color, description="Cannot start a thread with a bot." + color=self.bot.error_color, + description=_("Cannot start a thread with a bot."), ) return await ctx.send(embed=embed) @@ -894,8 +905,8 @@ async def contact( if exists: embed = discord.Embed( color=self.bot.error_color, - description="A thread for this user already " - f"exists in {exists.channel.mention}.", + description=_("A thread for this user already " + "exists in {mention}.").format(mention=exists.channel.mention), ) await ctx.channel.send(embed=embed) @@ -905,13 +916,14 @@ async def contact( logger.info("Contacting user %s when Modmail DM is disabled.", user) embed = discord.Embed( - title="Created Thread", - description=f"Thread started by {ctx.author.mention} for {user.mention}.", + title=_("Created Thread"), + description=_("Thread started by {author_mention} " + "for {user_mention}.").format(author_mention=ctx.author.mention, user_mention=user.mention), color=self.bot.main_color, ) await thread.wait_until_ready() await thread.channel.send(embed=embed) - sent_emoji, _ = await self.bot.retrieve_emoji() + sent_emoji, x = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) await asyncio.sleep(3) await ctx.message.delete() @@ -922,7 +934,11 @@ async def contact( async def blocked(self, ctx): """Retrieve a list of blocked users.""" - embeds = [discord.Embed(title="Blocked Users", color=self.bot.main_color, description="")] + embeds = [ + discord.Embed( + title=_("Blocked Users"), color=self.bot.main_color, description="" + ) + ] users = [] @@ -941,10 +957,10 @@ async def blocked(self, ctx): embed = embeds[0] for mention, reason in users: - line = mention + f" - {reason or 'No Reason Provided'}\n" + line = mention + f" - {reason or _('No Reason Provided')}\n" if len(embed.description) + len(line) > 2048: embed = discord.Embed( - title="Blocked Users (Continued)", + title=_("Blocked Users") + " " + _("(Continued)"), color=self.bot.main_color, description=line, ) @@ -952,7 +968,7 @@ async def blocked(self, ctx): else: embed.description += line else: - embeds[0].description = "Currently there are no blocked users." + embeds[0].description = _("Currently there are no blocked users.") session = EmbedPaginatorSession(ctx, *embeds) await session.run() @@ -978,8 +994,8 @@ async def blocked_whitelist(self, ctx, *, user: User = None): if str(user.id) in self.bot.blocked_whitelisted_users: embed = discord.Embed( - title="Success", - description=f"{mention} is no longer whitelisted.", + title=_("Success"), + description=_("{mention} is no longer whitelisted.").format(mention=mention), color=self.bot.main_color, ) self.bot.blocked_whitelisted_users.remove(str(user.id)) @@ -999,8 +1015,8 @@ async def blocked_whitelist(self, ctx, *, user: User = None): reason = msg[16:].strip().rstrip(".") embed = discord.Embed( title="Success", - description=f"{mention} was previously blocked internally for " - f'"{reason}". {mention} is now whitelisted.', + description=_("{mention} was previously blocked internally for " + '"{reason}". {mention} is now whitelisted.').format(mention=mention, reason=reason), color=self.bot.main_color, ) else: @@ -1040,8 +1056,8 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi if str(user.id) in self.bot.blocked_whitelisted_users: embed = discord.Embed( - title="Error", - description=f"Cannot block {mention}, user is whitelisted.", + title=_("Error"), + description=_("Cannot block {mention}, user is whitelisted.").format(mention=mention), color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -1065,16 +1081,16 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi if str(user.id) in self.bot.blocked_users and msg: old_reason = msg.strip().rstrip(".") embed = discord.Embed( - title="Success", - description=f"{mention} was previously blocked {old_reason}.\n" - f"{mention} is now blocked {reason}", + title=_("Success"), + description=_("{mention} was previously blocked {old_reason}.\n" + "{mention} is now blocked {reason}").format(mention=mention, old_reason=old_reason, reason=reason), color=self.bot.main_color, ) else: embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f"{mention} is now blocked {reason}", + description=_("{mention} is now blocked {reason}").format(mention=mention, reason=reason), ) self.bot.blocked_users[str(user.id)] = reason await self.bot.config.update() @@ -1113,24 +1129,28 @@ async def unblock(self, ctx, *, user: User = None): reason = msg[16:].strip().rstrip(".") or "no reason" embed = discord.Embed( title="Success", - description=f"{mention} was previously blocked internally {reason}.\n" - f"{mention} is no longer blocked.", + description=_("{mention} was previously blocked internally " + "{reason}.\n{mention} is no longer blocked.").format(mention=mention, reason=reason), color=self.bot.main_color, ) embed.set_footer( - text="However, if the original system block reason still applies, " - f"{name} will be automatically blocked again. " - f'Use "{self.bot.prefix}blocked whitelist {user.id}" to whitelist the user.' + text=_("However, if the original system block reason still applies, " + "{name} will be automatically blocked again. Use " + '"{self.bot.prefix}blocked whitelist {user.id}" to whitelist the user.').format( + name=name, prefix=self.bot.prefix, user_id=user.id + ) ) else: embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f"{mention} is no longer blocked.", + description=_("{mention} is no longer blocked.").format(mention=mention), ) else: embed = discord.Embed( - title="Error", description=f"{mention} is not blocked.", color=self.bot.error_color + title=_("Error"), + description=_("{mention} is not blocked.").format(mention=mention), + color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -1150,18 +1170,17 @@ async def delete(self, ctx, message_id: int = None): thread = ctx.thread try: - await thread.delete_message(message_id, note=True) - except ValueError as e: - logger.warning("Failed to delete message: %s.", e) + await thread.delete_message(message_id) + except ValueError: return await ctx.send( embed=discord.Embed( - title="Failed", - description="Cannot find a message to delete.", + title=_("Failed"), + description=_("Cannot find a message to delete."), color=self.bot.error_color, ) ) - sent_emoji, _ = await self.bot.retrieve_emoji() + sent_emoji, x = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -1283,15 +1302,20 @@ async def enable(self, ctx): Undo's the `{prefix}disable` command, all DM will be relayed after running this command. """ - embed = discord.Embed( - title="Success", - description="Modmail will now accept all DM messages.", - color=self.bot.main_color, - ) if self.bot.config["dm_disabled"] != 0: + embed = discord.Embed( + title=_("Success"), + description=_("Modmail will now accept **all** DM messages."), + color=self.bot.main_color, + ) self.bot.config["dm_disabled"] = 0 await self.bot.config.update() + else: + embed = discord.Embed( + description=_("Modmail is already accepting all DM messages."), + color=self.bot.error_color, + ) return await ctx.send(embed=embed) @@ -1315,12 +1339,25 @@ async def disable_new(self, ctx): No new threads can be created through DM. """ - embed = discord.Embed( - title="Success", - description="Modmail will not create any new threads.", - color=self.bot.main_color, - ) if self.bot.config["dm_disabled"] < 1: + embed = discord.Embed( + title=_("Success"), + description=_("Modmail will not create any **new** threads."), + color=self.bot.main_color, + ) + self.bot.config["dm_disabled"] = 1 + await self.bot.config.update() + elif self.bot.config["dm_disabled"] == 1: + embed = discord.Embed( + description=_("Modmail is already not creating any new threads."), + color=self.bot.error_color, + ) + else: + embed = discord.Embed( + title=_("Success"), + description=_("Modmail will not create **new** threads, but existing threads will now be functioning."), + color=self.bot.main_color, + ) self.bot.config["dm_disabled"] = 1 await self.bot.config.update() @@ -1334,15 +1371,20 @@ async def disable_all(self, ctx): No new threads can be created through DM nor no further DM messages will be relayed. """ - embed = discord.Embed( - title="Success", - description="Modmail will not accept any DM messages.", - color=self.bot.main_color, - ) - if self.bot.config["dm_disabled"] != 2: + if self.bot.config["dm_disabled"] < 2: + embed = discord.Embed( + title=_("Success"), + description=_("Modmail will not accept **any** DM messages."), + color=self.bot.main_color, + ) self.bot.config["dm_disabled"] = 2 await self.bot.config.update() + else: + embed = discord.Embed( + description=_("Modmail is already not accepting any DM messages."), + color=self.bot.error_color, + ) return await ctx.send(embed=embed) @@ -1355,20 +1397,20 @@ async def isenable(self, ctx): if self.bot.config["dm_disabled"] == 1: embed = discord.Embed( - title="New Threads Disabled", - description="Modmail is not creating new threads.", + title=_("New Threads Disabled"), + description=_("Modmail is not creating new threads."), color=self.bot.error_color, ) elif self.bot.config["dm_disabled"] == 2: embed = discord.Embed( - title="All DM Disabled", - description="Modmail is not accepting any DM messages for new and existing threads.", + title=_("All DM Disabled"), + description=_("Modmail is not accepting any DM messages for new and existing threads."), color=self.bot.error_color, ) else: embed = discord.Embed( - title="Enabled", - description="Modmail is accepting all DM messages.", + title=_("Enabled"), + description=_("Modmail is accepting all DM messages."), color=self.bot.main_color, ) diff --git a/cogs/plugins.py b/cogs/plugins.py index d14035286d..8868df3e77 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -104,7 +104,7 @@ def __init__(self, bot): self.bot.loop.create_task(self.populate_registry()) - if self.bot.config.get("enable_plugins"): + if getattr(self.bot, 'config', None) and self.bot.config.get("enable_plugins"): self.bot.loop.create_task(self.initial_load_plugins()) else: logger.info("Plugins not loaded since ENABLE_PLUGINS=false.") @@ -187,7 +187,7 @@ async def load_plugin(self, plugin): if req_txt.exists(): # Install PIP requirements - venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env + venv = hasattr(sys, "real_prefix") # in a virtual env user_install = " --user" if not venv else "" proc = await asyncio.create_subprocess_shell( f"{sys.executable} -m pip install --upgrade{user_install} -r {req_txt} -q -q", @@ -227,7 +227,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if not self._ready_event.is_set(): embed = discord.Embed( - description="Plugins are still loading, please try again later.", + description=_("Plugins are still loading, please try again later."), color=self.bot.main_color, ) await ctx.send(embed=embed) @@ -243,8 +243,8 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if required_version and self.bot.version < parse_version(required_version): embed = discord.Embed( - description="Your bot's version is too low. " - f"This plugin requires version `{required_version}`.", + description=_("Your bot's version is too low. " + "This plugin requires version `{required_version}`.").format(required_version=required_version), color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -257,9 +257,9 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): plugin = Plugin.from_string(plugin_name) except InvalidPluginError: embed = discord.Embed( - description="Invalid plugin name, double check the plugin name " - "or use one of the following formats: " - "username/repo/plugin, username/repo/plugin@branch.", + description=_("Invalid plugin name, double check the plugin name " + "or use one of the following formats: " + "username/repo/plugin, username/repo/plugin@branch."), color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -292,20 +292,21 @@ async def plugins_add(self, ctx, *, plugin_name: str): if str(plugin) in self.bot.config["plugins"]: embed = discord.Embed( - description="This plugin is already installed.", color=self.bot.error_color + description=_("This plugin is already installed."), + color=self.bot.error_color, ) return await ctx.send(embed=embed) if plugin.name in self.bot.cogs: # another class with the same name embed = discord.Embed( - description="Cannot install this plugin (dupe cog name).", + description=_("Cannot install this plugin (dupe cog name)."), color=self.bot.error_color, ) return await ctx.send(embed=embed) embed = discord.Embed( - description=f"Starting to download plugin from {plugin.link}...", + description=_("Starting to download plugin from {plugin_link}...").format(plugin_link=plugin.link), color=self.bot.main_color, ) msg = await ctx.send(embed=embed) @@ -316,7 +317,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): logger.warning("Unable to download plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description="Failed to download plugin, check logs for error.", + description=_("Failed to download plugin, check logs for error."), color=self.bot.error_color, ) @@ -335,24 +336,24 @@ async def plugins_add(self, ctx, *, plugin_name: str): logger.warning("Unable to load plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description="Failed to download plugin, check logs for error.", + description=_("Failed to download plugin, check logs for error."), color=self.bot.error_color, ) else: embed = discord.Embed( - description="Successfully installed plugin.\n" - "*Friendly reminder, plugins have absolute control over your bot. " - "Please only install plugins from developers you trust.*", + description=_("Successfully installed plugin.\n" + "*Friendly reminder, plugins have absolute control over your bot. " + "Please only install plugins from developers you trust.*"), color=self.bot.main_color, ) else: embed = discord.Embed( - description="Successfully installed plugin.\n" - "*Friendly reminder, plugins have absolute control over your bot. " - "Please only install plugins from developers you trust.*\n\n" - "This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, " - "to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot.", + description=_("Successfully installed plugin.\n" + "*Friendly reminder, plugins have absolute control over your bot. " + "Please only install plugins from developers you trust.*") + "\n\n" + + _("This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, " + "to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot."), color=self.bot.main_color, ) return await msg.edit(embed=embed) @@ -372,7 +373,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): if str(plugin) not in self.bot.config["plugins"]: embed = discord.Embed( - description="Plugin is not installed.", color=self.bot.error_color + description=_("Plugin is not installed."), color=self.bot.error_color ) return await ctx.send(embed=embed) @@ -398,7 +399,8 @@ async def plugins_remove(self, ctx, *, plugin_name: str): pass # dir not empty embed = discord.Embed( - description="The plugin is successfully uninstalled.", color=self.bot.main_color + description=_("The plugin is successfully uninstalled."), + color=self.bot.main_color, ) await ctx.send(embed=embed) @@ -410,7 +412,7 @@ async def update_plugin(self, ctx, plugin_name): if str(plugin) not in self.bot.config["plugins"]: embed = discord.Embed( - description="Plugin is not installed.", color=self.bot.error_color + description=_("Plugin is not installed."), color=self.bot.error_color ) return await ctx.send(embed=embed) @@ -424,7 +426,8 @@ async def update_plugin(self, ctx, plugin_name): await self.load_plugin(plugin) logger.debug("Updated %s.", plugin_name) embed = discord.Embed( - description=f"Successfully updated {plugin.name}.", color=self.bot.main_color + description=_("Successfully updated {plugin_name}.").format(plugin_name=plugin.name), + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -456,22 +459,23 @@ async def plugins_loaded(self, ctx): if not self.bot.config.get("enable_plugins"): embed = discord.Embed( - description="No plugins are loaded due to `ENABLE_PLUGINS=false`, " - "to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot.", + description=_("No plugins are loaded due to `ENABLE_PLUGINS=false`, " + "to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot."), color=self.bot.error_color, ) return await ctx.send(embed=embed) if not self._ready_event.is_set(): embed = discord.Embed( - description="Plugins are still loading, please try again later.", + description=_("Plugins are still loading, please try again later."), color=self.bot.main_color, ) return await ctx.send(embed=embed) if not self.loaded_plugins: embed = discord.Embed( - description="There are no plugins currently loaded.", color=self.bot.error_color + description=_("There are no plugins currently loaded."), + color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -491,7 +495,7 @@ async def plugins_loaded(self, ctx): embeds = [] for page in pages: embed = discord.Embed( - title="Loaded plugins:", description=page, color=self.bot.main_color + title=_("Loaded plugins:"), description=page, color=self.bot.main_color ) embeds.append(embed) paginator = EmbedPaginatorSession(ctx, *embeds) @@ -527,14 +531,15 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N if not index and plugin_name is not None: embed = discord.Embed( color=self.bot.error_color, - description=f'Could not find a plugin with name "{plugin_name}" within the registry.', + description=_('Could not find a plugin with name "{plugin_name}" within the registry.').format(plugin_name=plugin_name), ) matches = get_close_matches(plugin_name, self.registry.keys()) if matches: embed.add_field( - name="Perhaps you meant:", value="\n".join(f"`{m}`" for m in matches) + name=_("Perhaps you meant:"), + value="\n".join(f"`{m}`" for m in matches), ) return await ctx.send(embed=embed) @@ -554,7 +559,8 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N ) embed.add_field( - name="Installation", value=f"```{self.bot.prefix}plugins add {name}```" + name=_("Installation"), + value=f"```{self.bot.prefix}plugins add {plugin_name}```", ) embed.set_author( @@ -573,11 +579,11 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N required_version = details.get("bot_version", False) if required_version and self.bot.version < parse_version(required_version): embed.set_footer( - text="Your bot is unable to install this plugin, " - f"minimum required version is v{required_version}." + text=_("Your bot is unable to install this plugin, " + "minimum required version is v{required_version}.").format(required_version=required_version) ) else: - embed.set_footer(text="Your bot is able to install this plugin.") + embed.set_footer(text=_("Your bot is able to install this plugin.")) embeds.append(embed) @@ -632,7 +638,7 @@ async def plugins_registry_compact(self, ctx): for page in pages: embed = discord.Embed(color=self.bot.main_color, description=page) - embed.set_author(name="Plugin Registry", icon_url=self.bot.user.avatar_url) + embed.set_author(name=_("Plugin Registry"), icon_url=self.bot.user.avatar_url) embeds.append(embed) paginator = EmbedPaginatorSession(ctx, *embeds) diff --git a/cogs/utility.py b/cogs/utility.py index f8460c7d52..2704e57f1b 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -47,7 +47,7 @@ async def format_cog_help(self, cog, *, no_cog=False): else: format_ = f"`[{perm_level}] {prefix + cmd.qualified_name}` " - format_ += f"- {cmd.short_doc}\n" + format_ += f"- {_(cmd.short_doc)}\n" if not format_.strip(): continue if len(format_) + len(formats[-1]) >= 1024: @@ -58,21 +58,25 @@ async def format_cog_help(self, cog, *, no_cog=False): embeds = [] for format_ in formats: description = ( - cog.description or "No description." + _(cog.description) or _("No description.") if not no_cog - else "Miscellaneous commands without a category." + else _("Miscellaneous commands without a category.") ) embed = discord.Embed(description=f"*{description}*", color=bot.main_color) - embed.add_field(name="Commands", value=format_ or "No commands.") + embed.add_field(name=_("Commands"), value=format_ or _("No commands.")) - continued = " (Continued)" if embeds else "" - name = cog.qualified_name + " - Help" if not no_cog else "Miscellaneous Commands" + continued = " " + _("(Continued)") if embeds else "" + name = ( + cog.qualified_name + " - " + _("Help") + if not no_cog + else _("Miscellaneous Commands") + ) embed.set_author(name=name + continued, icon_url=bot.user.avatar_url) embed.set_footer( - text=f'Type "{prefix}{self.command_attrs["name"]} command" ' - "for more info on a specific command." + text=_('Type "{prefix}{command} command" ' + "for more info on a specific command.").format(prefix=prefix, command=self.command_attrs["name"]) ) embeds.append(embed) return embeds @@ -112,19 +116,19 @@ async def _get_help_embed(self, topic): if perm_level is not PermissionLevel.INVALID: perm_level = f"{perm_level.name} [{perm_level}]" else: - perm_level = "NONE" + perm_level = _("NONE") embed = discord.Embed( title=f"`{self.get_command_signature(topic)}`", color=self.context.bot.main_color, - description=self.process_help_msg(topic.help), + description=self.process_help_msg(_(topic.help)), ) return embed, perm_level async def send_command_help(self, command): topic = await self._get_help_embed(command) if topic is not None: - topic[0].set_footer(text=f"Permission level: {topic[1]}") + topic[0].set_footer(text=_("Permission level: {level}").format(level=topic[1])) await self.get_destination().send(embed=topic[0]) async def send_group_help(self, group): @@ -132,7 +136,7 @@ async def send_group_help(self, group): if topic is None: return embed = topic[0] - embed.add_field(name="Permission Level", value=topic[1], inline=False) + embed.add_field(name=_("Permission Level"), value=topic[1], inline=False) format_ = "" length = len(group.commands) @@ -146,12 +150,12 @@ async def send_group_help(self, group): branch = "└─" else: branch = "├─" - format_ += f"`{branch} {command.name}` - {command.short_doc}\n" + format_ += f"`{branch} {command.name}` - {_(command.short_doc)}\n" - embed.add_field(name="Sub Command(s)", value=format_[:1024], inline=False) + embed.add_field(name=_("Sub Command(s)"), value=format_[:1024], inline=False) embed.set_footer( - text=f'Type "{self.clean_prefix}{self.command_attrs["name"]} command" ' - "for more info on a command." + text=_('Type "{prefix}{command} command" ' + "for more info on a command.").format(prefix=self.clean_prefix, command=self.command_attrs["name"]) ) await self.get_destination().send(embed=embed) @@ -161,7 +165,7 @@ async def send_error_message(self, error): val = self.context.bot.snippets.get(command) if val is not None: embed = discord.Embed( - title=f"{command} is a snippet.", color=self.context.bot.main_color + title=_("{command} is a snippet.").format(command=command), color=self.context.bot.main_color ) embed.add_field(name=f"`{command}` will send:", value=val) return await self.get_destination().send(embed=embed) @@ -172,10 +176,10 @@ async def send_error_message(self, error): if not values: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.context.bot.error_color, - description=f"Alias `{command}` is invalid, this alias will now be deleted." - "This alias will now be deleted.", + description=_("Alias `{command}` is invalid, this alias will now be deleted." + "This alias will now be deleted.").format(command=command), ) embed.add_field(name=f"{command}` used to be:", value=val) self.context.bot.aliases.pop(command) @@ -183,28 +187,28 @@ async def send_error_message(self, error): else: if len(values) == 1: embed = discord.Embed( - title=f"{command} is an alias.", color=self.context.bot.main_color + title=_("{command} is an alias.").format(command=command), color=self.context.bot.main_color ) - embed.add_field(name=f"`{command}` points to:", value=values[0]) + embed.add_field(name=_("`{command}` points to:").format(command=command), value=values[0]) else: embed = discord.Embed( - title=f"{command} is an alias.", + title=_("{command} is an alias.").format(command=command), color=self.context.bot.main_color, - description=f"**`{command}` points to the following steps:**", + description=_("**`{command}` points to the following steps:**").format(command=command), ) for i, val in enumerate(values, start=1): - embed.add_field(name=f"Step {i}:", value=val) + embed.add_field(name=_("Step") + f" {i}:", value=val) embed.set_footer( - text=f'Type "{self.clean_prefix}{self.command_attrs["name"]} alias" ' - "for more details on aliases." + text=_('Type "{prefix}{command} alias" ' + "for more details on aliases.").format(prefix=self.clean_prefix, command=self.command_attrs["name"]) ) return await self.get_destination().send(embed=embed) logger.warning("CommandNotFound: %s", error) embed = discord.Embed(color=self.context.bot.error_color) - embed.set_footer(text=f'Command/Category "{command}" not found.') + embed.set_footer(text=_('Command/Category "{command}" not found.').format(command=command)) choices = set() @@ -214,12 +218,14 @@ async def send_error_message(self, error): closest = get_close_matches(command, choices) if closest: - embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) + embed.add_field( + name=_("Perhaps you meant:"), value="\n".join(f"`{x}`" for x in closest) + ) else: - embed.title = "Cannot find command or category" + embed.title = _("Cannot find command or category") embed.set_footer( - text=f'Type "{self.clean_prefix}{self.command_attrs["name"]}" ' - "for a list of all available commands." + text=_('Type "{prefix}{command}" ' + "for a list of all available commands.").format(prefix=self.clean_prefix, command=self.command_attrs["name"]) ) await self.get_destination().send(embed=embed) @@ -233,7 +239,7 @@ def __init__(self, bot): self.bot.help_command = ModmailHelpCommand( verify_checks=False, command_attrs={ - "help": "Shows this help message.", + "help": _("Shows this help message."), "checks": [checks.has_permissions_predicate(PermissionLevel.REGULAR)], }, ) @@ -257,7 +263,7 @@ async def changelog(self, ctx, version: str.lower = ""): return await ctx.send( embed=discord.Embed( color=self.bot.error_color, - description=f"The specified version `{version}` could not be found.", + description=_("The specified version `{version}` could not be found.").format(version=version), ) ) @@ -273,7 +279,7 @@ async def changelog(self, ctx, version: str.lower = ""): finally: logger.warning("Failed to display changelog.", exc_info=True) await ctx.send( - f"View the changelog here: {changelog.latest_version.changelog_url}#v{version[::2]}" + _("View the changelog here: {url}").format(url=f'{changelog.latest_version.changelog_url}#v{version[::2]}') ) @commands.command(aliases=["info"]) @@ -283,21 +289,21 @@ async def about(self, ctx): """Shows information about this bot.""" embed = discord.Embed(color=self.bot.main_color, timestamp=datetime.utcnow()) embed.set_author( - name="Modmail - About", + name=_("Modmail - About"), icon_url=self.bot.user.avatar_url, url="https://discord.gg/F34cRU8", ) embed.set_thumbnail(url=self.bot.user.avatar_url) - desc = "This is an open source Discord bot that serves as a means for " - desc += "members to easily communicate with server administrators in " - desc += "an organised manner." + desc = _("This is an open source Discord bot that serves as a means for " + "members to easily communicate with server administrators in " + "an organised manner.") embed.description = desc - embed.add_field(name="Uptime", value=self.bot.uptime) - embed.add_field(name="Latency", value=f"{self.bot.latency * 1000:.2f} ms") - embed.add_field(name="Version", value=f"`{self.bot.version}`") - embed.add_field(name="Authors", value="`kyb3r`, `Taki`, `fourjr`") + embed.add_field(name=_("Uptime"), value=self.bot.uptime) + embed.add_field(name=_("Latency"), value=f"{self.bot.latency * 1000:.2f} ms") + embed.add_field(name=_("Version"), value=f"`{self.bot.version}`") + embed.add_field(name=_("Authors"), value="`kyb3r`, `Taki`, `fourjr`") changelog = await Changelog.from_url(self.bot) latest = changelog.latest_version @@ -306,26 +312,24 @@ async def about(self, ctx): stable = next( filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions) ) - footer = ( - f"You are on the prerelease version • the latest version is v{stable.version}." - ) + footer = _("You are on the prerelease version • the latest version is v{version}.").format(version=stable.version) elif self.bot.version < parse_version(latest.version): - footer = f"A newer version is available v{latest.version}." + footer = _("A newer version is available v{version}.").format(version=latest.version) else: - footer = "You are up to date with the latest version." + footer = _("You are up to date with the latest version.") embed.add_field( - name="Want Modmail in Your Server?", - value="Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " - "and join our [Discord server](https://discord.gg/F34cRU8/)!", + name=_("Want Modmail in Your Server?"), + value=_("Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " + "and join our [Discord server](https://discord.gg/F34cRU8/)!"), inline=False, ) embed.add_field( - name="Support the Developers", - value="This bot is completely free for everyone. We rely on kind individuals " - "like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) " - "to keep this bot free forever!", + name=_("Support the Developers"), + value=_("This bot is completely free for everyone. We rely on kind individuals " + "like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) " + "to keep this bot free forever!"), inline=False, ) @@ -372,10 +376,10 @@ async def debug(self, ctx): if not logs: embed = discord.Embed( color=self.bot.main_color, - title="Debug Logs:", - description="You don't have any logs at the moment.", + title=_("Debug Logs:"), + description=_("You don't have any logs at the moment."), ) - embed.set_footer(text="Go to Heroku to see your logs.") + embed.set_footer(text=_("Go to Heroku to see your logs.")) return await ctx.send(embed=embed) messages = [] @@ -401,7 +405,7 @@ async def debug(self, ctx): messages.append(msg) embed = discord.Embed(color=self.bot.main_color) - embed.set_footer(text="Debug logs - Navigate using the reactions below.") + embed.set_footer(text=_("Debug logs - Navigate using the reactions below.")) session = MessagePaginatorSession(ctx, *messages, embed=embed) session.current = len(messages) - 1 @@ -433,7 +437,7 @@ async def debug_hastebin(self, ctx): logger.error(data["message"]) raise embed = discord.Embed( - title="Debug Logs", + title=_("Debug Logs"), color=self.bot.main_color, description=f"{haste_url}/" + key, ) @@ -441,9 +445,9 @@ async def debug_hastebin(self, ctx): embed = discord.Embed( title="Debug Logs", color=self.bot.main_color, - description="Something's wrong. We're unable to upload your logs to hastebin.", + description=_("Something's wrong. We're unable to upload your logs to hastebin."), ) - embed.set_footer(text="Go to Heroku to see your logs.") + embed.set_footer(text=_("Go to Heroku to see your logs.")) await ctx.send(embed=embed) @debug.command(name="clear", aliases=["wipe"]) @@ -463,7 +467,7 @@ async def debug_clear(self, ctx): pass await ctx.send( embed=discord.Embed( - color=self.bot.main_color, description="Cached logs are now cleared." + color=self.bot.main_color, description=_("Cached logs are now cleared.") ) ) @@ -494,7 +498,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): self.bot.config.remove("activity_message") await self.bot.config.update() await self.set_presence() - embed = discord.Embed(title="Activity Removed", color=self.bot.main_color) + embed = discord.Embed(title=_("Activity Removed"), color=self.bot.main_color) return await ctx.send(embed=embed) if not message: @@ -505,7 +509,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): except KeyError: raise commands.MissingRequiredArgument(SimpleNamespace(name="activity")) - activity, _ = await self.set_presence( + activity, x = await self.set_presence( activity_type=activity_type, activity_message=message ) @@ -513,13 +517,15 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): self.bot.config["activity_message"] = activity.name await self.bot.config.update() - msg = f"Activity set to: {activity.type.name.capitalize()} " + msg = _("Activity set to: {name} ").format(name=activity.type.name.capitalize()) if activity.type == ActivityType.listening: - msg += f"to {activity.name}." + msg += _("to {name}.").format(name=activity.name) else: msg += f"{activity.name}." - embed = discord.Embed(title="Activity Changed", description=msg, color=self.bot.main_color) + embed = discord.Embed( + title=_("Activity Changed"), description=msg, color=self.bot.main_color + ) return await ctx.send(embed=embed) @commands.command() @@ -541,7 +547,7 @@ async def status(self, ctx, *, status_type: str.lower): self.bot.config.remove("status") await self.bot.config.update() await self.set_presence() - embed = discord.Embed(title="Status Removed", color=self.bot.main_color) + embed = discord.Embed(title=_("Status Removed"), color=self.bot.main_color) return await ctx.send(embed=embed) status_type = status_type.replace(" ", "_") @@ -550,13 +556,15 @@ async def status(self, ctx, *, status_type: str.lower): except KeyError: raise commands.MissingRequiredArgument(SimpleNamespace(name="status")) - _, status = await self.set_presence(status=status) + x, status = await self.set_presence(status=status) self.bot.config["status"] = status.value await self.bot.config.update() - msg = f"Status set to: {status.value}." - embed = discord.Embed(title="Status Changed", description=msg, color=self.bot.main_color) + msg = _("Status set to: {value}.").format(value=status.value) + embed = discord.Embed( + title=_("Status Changed"), description=msg, color=self.bot.main_color + ) return await ctx.send(embed=embed) async def set_presence(self, *, status=None, activity_type=None, activity_message=None): @@ -627,7 +635,7 @@ async def before_loop_presence(self): async def ping(self, ctx): """Pong! Returns your websocket latency.""" embed = discord.Embed( - title="Pong! Websocket Latency:", + title=_("Pong! Websocket Latency:"), description=f"{self.bot.ws.latency * 1000:.4f} ms", color=self.bot.main_color, ) @@ -646,12 +654,14 @@ async def mention(self, ctx, *, mention: str = None): if mention is None: embed = discord.Embed( - title="Current mention:", color=self.bot.main_color, description=str(current) + title=_("Current mention:"), + color=self.bot.main_color, + description=str(current), ) else: embed = discord.Embed( - title="Changed mention!", - description=f'On thread creation the bot now says "{mention}".', + title=_("Changed mention!"), + description=_('On thread creation the bot now says "{mention}".').format(mention=mention), color=self.bot.main_color, ) self.bot.config["mention"] = mention @@ -670,14 +680,14 @@ async def prefix(self, ctx, *, prefix=None): current = self.bot.prefix embed = discord.Embed( - title="Current prefix", color=self.bot.main_color, description=f"{current}" + title=_("Current prefix"), color=self.bot.main_color, description=f"{current}" ) if prefix is None: await ctx.send(embed=embed) else: - embed.title = "Changed prefix!" - embed.description = f"Set prefix to `{prefix}`" + embed.title = _("Changed prefix!") + embed.description = _("Set prefix to `{prefix}`").format(prefix=prefix) self.bot.config["prefix"] = prefix await self.bot.config.update() await ctx.send(embed=embed) @@ -712,7 +722,7 @@ async def config_options(self, ctx): f"`{name}`" for name in takewhile(lambda x: x is not None, names) ) embed = discord.Embed( - title="Available configuration keys:", + title=_("Available configuration keys:"), color=self.bot.main_color, description=description, ) @@ -733,18 +743,20 @@ async def config_set(self, ctx, key: str.lower, *, value: str): self.bot.config.set(key, value) await self.bot.config.update() embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f"Set `{key}` to `{self.bot.config[key]}`.", + description=_("Set `{key}` to `{value}`.").format(key=key, value=self.bot.config[key]), ) except InvalidConfigError as exc: embed = exc.embed else: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." + title=_("Error"), + color=self.bot.error_color, + description=_("{key} is an invalid key.").format(key=key), ) valid_keys = [f"`{k}`" for k in sorted(keys)] - embed.add_field(name="Valid keys", value=", ".join(valid_keys)) + embed.add_field(name=_("Valid keys"), value=", ".join(valid_keys)) return await ctx.send(embed=embed) @@ -757,16 +769,18 @@ async def config_remove(self, ctx, *, key: str.lower): self.bot.config.remove(key) await self.bot.config.update() embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f"`{key}` had been reset to default.", + description=_("`{key}` had been reset to default.").format(key=key), ) else: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." + title=_("Error"), + color=self.bot.error_color, + description=_("{key} is an invalid key.").format(key=key), ) valid_keys = [f"`{k}`" for k in sorted(keys)] - embed.add_field(name="Valid keys", value=", ".join(valid_keys)) + embed.add_field(name=_("Valid keys"), value=", ".join(valid_keys)) return await ctx.send(embed=embed) @@ -782,24 +796,30 @@ async def config_get(self, ctx, *, key: str.lower = None): if key: if key in keys: - desc = f"`{key}` is set to `{self.bot.config[key]}`" + desc = _("`{key}` is set to `{value}`").format(key=key, value=self.bot.config[key]) embed = discord.Embed(color=self.bot.main_color, description=desc) - embed.set_author(name="Config variable", icon_url=self.bot.user.avatar_url) + embed.set_author( + name=_("Config variable"), icon_url=self.bot.user.avatar_url + ) else: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"`{key}` is an invalid key.", + description=_("`{key}` is an invalid key.").format(key=key), ) embed.set_footer( - text=f'Type "{self.bot.prefix}config options" for a list of config variables.' + text=_('Type "{prefix}config options" for a list of config variables.').format(prefix=self.bot.prefix) ) else: embed = discord.Embed( color=self.bot.main_color, - description="Here is a list of currently set configuration variable(s).", + description=_("Here is a list of currently " + "set configuration variable(s)."), + ) + embed.set_author( + name=_("Current config(s):"), icon_url=self.bot.user.avatar_url ) embed.set_author(name="Current config(s):", icon_url=self.bot.user.avatar_url) config = self.bot.config.filter_default(self.bot.config) @@ -823,9 +843,9 @@ async def config_help(self, ctx, key: str.lower = None): key, {**self.bot.config.public_keys, **self.bot.config.protected_keys} ) embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"`{key}` is an invalid key.", + description=_("`{key}` is an invalid key.").format(key=key), ) if closest: embed.add_field( @@ -837,9 +857,9 @@ async def config_help(self, ctx, key: str.lower = None): if key is not None and key not in config_help: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"No help details found for `{key}`.", + description=_("No help details found for `{key}`.").format(key=key), ) return await ctx.send(embed=embed) @@ -852,21 +872,24 @@ def fmt(val): if current_key == key: index = i embed = discord.Embed( - title=f"Configuration description on {current_key}:", color=self.bot.main_color + title=_("Configuration description on {current_key}:").format(current_key=current_key), + color=self.bot.main_color, ) embed.add_field(name="Default:", value=fmt(info["default"]), inline=False) - embed.add_field(name="Information:", value=fmt(info["description"]), inline=False) + embed.add_field( + name=_("Information:"), value=fmt(info["description"]), inline=False + ) if info["examples"]: example_text = "" for example in info["examples"]: example_text += f"- {fmt(example)}\n" - embed.add_field(name="Example(s):", value=example_text, inline=False) + embed.add_field(name=_("Example(s):"), value=example_text, inline=False) note_text = "" for note in info["notes"]: note_text += f"- {fmt(note)}\n" if note_text: - embed.add_field(name="Note(s):", value=note_text, inline=False) + embed.add_field(name=_("Note(s):"), value=note_text, inline=False) if info.get("image") is not None: embed.set_image(url=fmt(info["image"])) @@ -911,10 +934,10 @@ async def alias(self, ctx, *, name: str.lower = None): if not values: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"Alias `{name}` is invalid, this alias will now be deleted." - "This alias will now be deleted.", + description=_("Alias `{name}` is invalid, it used to be `{value}`. " + "This alias will now be deleted.").format(name=name, value=escape_markdown(val)), ) embed.add_field(name=f"{name}` used to be:", value=utils.truncate(val, 1024)) self.bot.aliases.pop(name) @@ -923,7 +946,7 @@ async def alias(self, ctx, *, name: str.lower = None): if len(values) == 1: embed = discord.Embed( - title=f'Alias - "{name}":', description=values[0], color=self.bot.main_color + title=_("Alias") + f' - "{name}":', description=values[0], color=self.bot.main_color ) return await ctx.send(embed=embed) @@ -941,10 +964,11 @@ async def alias(self, ctx, *, name: str.lower = None): if not self.bot.aliases: embed = discord.Embed( - color=self.bot.error_color, description="You dont have any aliases at the moment." + color=self.bot.error_color, + description=_("You dont have any aliases at the moment."), ) - embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') - embed.set_author(name="Aliases", icon_url=ctx.guild.icon_url) + embed.set_footer(text=_("Do {prefix}help alias for more commands.").format(prefix=self.bot.prefix)) + embed.set_author(name=_("Aliases"), icon_url=ctx.guild.icon_url) return await ctx.send(embed=embed) embeds = [] @@ -952,7 +976,7 @@ async def alias(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.aliases)),) * 15)): description = utils.format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Command Aliases", icon_url=ctx.guild.icon_url) + embed.set_author(name=_("Command Aliases"), icon_url=ctx.guild.icon_url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -980,9 +1004,9 @@ async def make_alias(self, name, value, action): values = utils.parse_alias(value) if not values: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description="Invalid multi-step alias, try wrapping each steps in quotes.", + description=_("Invalid multi-step alias, try wrapping each steps in quotes."), ) embed.set_footer(text=f'See "{self.bot.prefix}alias add" for more details.') return embed @@ -997,12 +1021,12 @@ async def make_alias(self, name, value, action): multiple_alias = len(values) > 1 - embed = discord.Embed(title=f"{action} alias", color=self.bot.main_color) + embed = discord.Embed(title=_("{action} alias").format(action), color=self.bot.main_color) if not multiple_alias: - embed.add_field(name=f"`{name}` points to:", value=utils.truncate(values[0], 1024)) + embed.add_field(name=_("`{name}` points to:").format(name=name), value=utils.truncate(values[0], 1024)) else: - embed.description = f"`{name}` now points to the following steps:" + embed.description = _("`{name}` now points to the following steps:").format(name=name) for i, val in enumerate(values, start=1): view = StringView(val) @@ -1018,20 +1042,20 @@ async def make_alias(self, name, value, action): if multiple_alias: embed.description = ( - "The command you are attempting to point " - f"to does not exist: `{linked_command}`." + _("The command you are attempting to point " + "to does not exist: `{command}`.").format(command=linked_command) ) else: embed.description = ( - "The command you are attempting to point " - f"to on step {i} does not exist: `{linked_command}`." + _("The command you are attempting to point " + "to on step {number} does not exist: `{command}`.").format(number=i, command=linked_command) ) return embed else: save_aliases.append(val) if multiple_alias: - embed.add_field(name=f"Step {i}:", value=utils.truncate(val, 1024)) + embed.add_field(name=_("Step") + f" {i}:", value=utils.truncate(val, 1024)) self.bot.aliases[name] = " && ".join(f'"{a}"' for a in save_aliases) await self.bot.config.update() @@ -1056,30 +1080,30 @@ async def alias_add(self, ctx, name: str.lower, *, value): embed = None if self.bot.get_command(name): embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"A command with the same name already exists: `{name}`.", + description=_("A command with the same name already exists: `{name}`.").format(name=name), ) elif name in self.bot.aliases: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"Another alias with the same name already exists: `{name}`.", + description=_("Another alias with the same name already exists: `{name}`.").format(name=name), ) elif name in self.bot.snippets: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"A snippet with the same name already exists: `{name}`.", + description=_("A snippet with the same name already exists: `{name}`.").format(name=name), ) elif len(name) > 120: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description="Alias names cannot be longer than 120 characters.", + description=_("Alias names cannot be longer than 120 characters."), ) if embed is None: @@ -1096,9 +1120,9 @@ async def alias_remove(self, ctx, *, name: str.lower): await self.bot.config.update() embed = discord.Embed( - title="Removed alias", + title=_("Removed alias"), color=self.bot.main_color, - description=f"Successfully deleted `{name}`.", + description=_("Successfully deleted `{name}`.").format(name=name), ) else: embed = utils.create_not_found_embed(name, self.bot.aliases.keys(), "Alias") @@ -1202,9 +1226,9 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name level = self._parse_level(level_name) if level is PermissionLevel.INVALID: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"The referenced level does not exist: `{level_name}`.", + description=_("The referenced level does not exist: `{level}`.").format(level=level_name), ) else: logger.info( @@ -1216,10 +1240,10 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name await self.bot.config.update() embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description="Successfully set command permission level for " - f"`{command.qualified_name}` to `{level.name}`.", + description=_("Successfully set command permission level for " + "`{command}` to `{level}`.").format(command=command.qualified_name, level=level.name), ) return await ctx.send(embed=embed) @@ -1262,9 +1286,9 @@ async def permissions_add( if not check: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"The referenced {type_} does not exist: `{name}`.", + description=_("The referenced {type} does not exist: `{name}`.").format(type=type_, name=name), ) return await ctx.send(embed=embed) @@ -1287,9 +1311,9 @@ async def permissions_add( await self.bot.main_category.set_permissions(key, read_messages=True) embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f"Permission for `{name}` was successfully updated.", + description=_("Permission for `{name}` was successfully updated.").format(name=name), ) return await ctx.send(embed=embed) @@ -1338,10 +1362,10 @@ async def permissions_remove( if level is None: perm = self.bot.command_perm(name) embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"The command permission level was never overridden: `{name}`, " - f"current permission level is {perm.name}.", + description=_("The command permission level was never overridden: `{name}`, " + "current permission level is {perm_name}.").format(name=name, perm_name=perm.name), ) else: logger.info("Restored command permission level for `%s`.", name) @@ -1349,9 +1373,9 @@ async def permissions_remove( await self.bot.config.update() perm = self.bot.command_perm(name) embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f"Command permission level for `{name}` was successfully restored to {perm.name}.", + description=_("Command permission level for `{name}` was successfully restored to {perm_name}.").format(name=name, perm_name=perm.name), ) return await ctx.send(embed=embed) @@ -1363,9 +1387,9 @@ async def permissions_remove( level = self._parse_level(name) if level is PermissionLevel.INVALID: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"The referenced level does not exist: `{name}`.", + description=_("The referenced level does not exist: `{name}`.").format(name=name), ) return await ctx.send(embed=embed) name = level.name @@ -1390,9 +1414,9 @@ async def permissions_remove( await self.bot.main_category.set_permissions(member, overwrite=None) embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f"Permission for `{name}` was successfully updated.", + description=_("Permission for `{name}` was successfully updated.").format(name=name), ) return await ctx.send(embed=embed) @@ -1403,8 +1427,8 @@ def _get_perm(self, ctx, name, type_): permissions = self.bot.config["level_permissions"].get(name, []) if not permissions: embed = discord.Embed( - title=f"Permission entries for {type_} `{name}`:", - description="No permission entries found.", + title=_("Permission entries for {type} `{name}`:").format(type=type_, name=name), + description=_("No permission entries found."), color=self.bot.main_color, ) else: @@ -1428,7 +1452,7 @@ def _get_perm(self, ctx, name, type_): values.append(str(perm)) embed = discord.Embed( - title=f"Permission entries for {type_} `{name}`:", + title=_("Permission entries for {type} `{name}`:").format(type=type_, name=name), description=", ".join(values), color=self.bot.main_color, ) @@ -1491,22 +1515,22 @@ async def permissions_get( desc_cmd = ( ", ".join(map(lambda x: f"`{x}`", cmds)) if cmds - else "No permission entries found." + else _("No permission entries found.") ) desc_level = ( ", ".join(map(lambda x: f"`{x}`", levels)) if levels - else "No permission entries found." + else _("No permission entries found.") ) embeds = [ discord.Embed( - title=f"{mention} has permission with the following commands:", + title=_("{mention} has permission with the following commands:").format(mention=mention), description=desc_cmd, color=self.bot.main_color, ), discord.Embed( - title=f"{mention} has permission with the following permission levels:", + title=_("{mention} has permission with the following permission levels:").format(mention=mention), description=desc_level, color=self.bot.main_color, ), @@ -1531,8 +1555,8 @@ async def permissions_get( if not overrides: embeds.append( discord.Embed( - title="Permission Overrides", - description="You don't have any command level overrides at the moment.", + title=_("Permission Overrides"), + description=_("You don't have any command level overrides at the moment."), color=self.bot.error_color, ) ) @@ -1546,7 +1570,7 @@ async def permissions_get( color=self.bot.main_color, description=description ) embed.set_author( - name="Permission Overrides", icon_url=ctx.guild.icon_url + name=_("Permission Overrides"), icon_url=ctx.guild.icon_url ) embeds.append(embed) @@ -1559,16 +1583,16 @@ async def permissions_get( perm = self.bot.command_perm(name) if level is None: embed = discord.Embed( - title="Error", + title=_("Error"), color=self.bot.error_color, - description=f"The command permission level was never overridden: `{name}`, " - f"current permission level is {perm.name}.", + description=_("The command permission level was never overridden: `{name}`, " + "current permission level is {perm_name}.").format(name=name, perm_name=perm.name), ) else: embed = discord.Embed( - title="Success", + title=_("Success"), color=self.bot.main_color, - description=f'Permission override for command "{name}" is "{perm.name}".', + description=_('Permission override for command "{name}" is "{perm_name}".').format(name=name, perm_name=perm.name), ) return await ctx.send(embed=embed) @@ -1644,14 +1668,19 @@ async def oauth_whitelist(self, ctx, target: Union[discord.Role, utils.User]): await self.bot.config.update() embed = discord.Embed(color=self.bot.main_color) - embed.title = "Success" + embed.title = _("Success") if not hasattr(target, "mention"): target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role(target.id) - embed.description = ( - f"{'Un-w' if removed else 'W'}hitelisted {target.mention} to view logs." - ) + if removed: + embed.description = ( + _("Un-whitelisted {target_mention} to view logs.").format(target_mention=target.mention) + ) + else: + embed.description = ( + _("Whitelisted {target_mention} to view logs.").format(target_mention=target.mention) + ) await ctx.send(embed=embed) @@ -1673,10 +1702,14 @@ async def oauth_show(self, ctx): roles.append(role) embed = discord.Embed(color=self.bot.main_color) - embed.title = "Oauth Whitelist" + embed.title = _("Oauth Whitelist") - embed.add_field(name="Users", value=" ".join(u.mention for u in users) or "None") - embed.add_field(name="Roles", value=" ".join(r.mention for r in roles) or "None") + embed.add_field( + name=_("Users"), value=" ".join(u.mention for u in users) or _("None") + ) + embed.add_field( + name="Roles", value=" ".join(r.mention for r in roles) or "None" + ) await ctx.send(embed=embed) diff --git a/core/config.py b/core/config.py index cfd79d9df9..a0eda4a2dc 100644 --- a/core/config.py +++ b/core/config.py @@ -17,6 +17,7 @@ from core.utils import strtobool logger = getLogger(__name__) +load_dotenv() class ConfigManager: @@ -134,13 +135,11 @@ class ConfigManager: defaults = {**public_keys, **private_keys, **protected_keys} all_keys = set(defaults.keys()) - def __init__(self, bot, config_path=os.path.dirname(os.path.abspath(__file__))): + def __init__(self, bot): self.bot = bot self._cache = {} self.ready_event = asyncio.Event() self.config_help = {} - self.config_path = config_path - load_dotenv(dotenv_path=os.path.join(self.config_path, ".env")) def __repr__(self): return repr(self._cache) @@ -150,9 +149,11 @@ def populate_cache(self) -> dict: # populate from env var and .env file data.update({k.lower(): v for k, v in os.environ.items() if k.lower() in self.all_keys}) - config_json = os.path.join(self.config_path, "config.json") + config_json = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config.json" + ) if os.path.exists(config_json): - logger.debug("Loading envs from {}".format(config_json)) + logger.debug("Loading envs from config.json.") with open(config_json, "r", encoding="utf-8") as f: # Config json should override env vars try: diff --git a/core/paginator.py b/core/paginator.py index 7ba1c98b60..45c059f844 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -176,7 +176,7 @@ async def close(self, delete: bool = True) -> typing.Optional[Message]: """ self.running = False - sent_emoji, _ = await self.ctx.bot.retrieve_emoji() + sent_emoji, x = await self.ctx.bot.retrieve_emoji() await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) if delete: diff --git a/core/thread.py b/core/thread.py index 960dafe0f7..0926a0acd0 100644 --- a/core/thread.py +++ b/core/thread.py @@ -72,13 +72,15 @@ def ready(self) -> bool: def ready(self, flag: bool): if flag: self._ready_event.set() - self.bot.dispatch("thread_create", self) + self.bot.dispatch("thread_ready", self) else: self._ready_event.clear() async def setup(self, *, creator=None, category=None): """Create the thread channel and other io related initialisation tasks""" - self.bot.dispatch("thread_initiate", self) + + self.bot.dispatch("thread_create", self) + recipient = self.recipient # in case it creates a channel outside of category @@ -173,7 +175,6 @@ async def send_recipient_genesis_message(): await self.bot.add_reaction(msg, close_emoji) await asyncio.gather(send_genesis_message(), send_recipient_genesis_message()) - self.bot.dispatch("thread_ready", self) def _format_info_embed(self, user, log_url, log_count, color): """Get information about a member of a server @@ -456,14 +457,9 @@ async def find_linked_messages( message_id: typing.Optional[int] = None, either_direction: bool = False, message1: discord.Message = None, - note: bool = True, ) -> typing.Tuple[discord.Message, typing.Optional[discord.Message]]: if message1 is not None: - if ( - not message1.embeds - or not message1.embeds[0].author.url - or message1.author != self.bot.user - ): + if not message1.embeds or not message1.embeds[0].author.url: raise ValueError("Malformed thread message.") elif message_id is not None: @@ -473,18 +469,13 @@ async def find_linked_messages( raise ValueError("Thread message not found.") if not ( - message1.embeds - and message1.embeds[0].author.url - and message1.embeds[0].color - and message1.author == self.bot.user + message1.embeds and message1.embeds[0].author.url and message1.embeds[0].color ): raise ValueError("Thread message not found.") if message1.embeds[0].color.value == self.bot.main_color and message1.embeds[ 0 ].author.name.startswith("Note"): - if not note: - raise ValueError("Thread message not found.") return message1, None if message1.embeds[0].color.value != self.bot.mod_color and not ( @@ -504,8 +495,6 @@ async def find_linked_messages( and message1.embeds[0].color.value == self.bot.recipient_color ) ) - and message1.embeds[0].author.url.split("#")[-1].isdigit() - and message1.author == self.bot.user ): break else: @@ -527,7 +516,7 @@ async def find_linked_messages( if int(msg.embeds[0].author.url.split("#")[-1]) == joint_id: return message1, msg except ValueError: - continue + raise ValueError("DM message not found.") raise ValueError("DM message not found.") async def edit_message(self, message_id: typing.Optional[int], message: str) -> None: @@ -548,13 +537,16 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> await asyncio.gather(*tasks) - async def delete_message( - self, message: typing.Union[int, discord.Message] = None, note: bool = True - ) -> None: - if isinstance(message, discord.Message): - message1, message2 = await self.find_linked_messages(message1=message, note=note) - else: - message1, message2 = await self.find_linked_messages(message, note=note) + async def delete_message(self, message: typing.Union[int, discord.Message] = None) -> None: + try: + if isinstance(message, discord.Message): + message1, message2 = await self.find_linked_messages(message1=message) + else: + message1, message2 = await self.find_linked_messages(message) + except ValueError as e: + logger.warning("Failed to delete message: %s.", e) + raise + tasks = [] if not isinstance(message, discord.Message): tasks += [message1.delete()] @@ -579,12 +571,12 @@ async def find_linked_message_from_dm(self, message, either_direction=False): return linked_message msg_id = url.split("#")[-1] - if not msg_id.isdigit(): - continue - msg_id = int(msg_id) - if int(msg_id) == message.id: - return linked_message - raise ValueError("Thread channel message not found.") + try: + if int(msg_id) == message.id: + return linked_message + except ValueError: + raise ValueError("Malformed dm channel message.") + raise ValueError("DM channel message not found.") async def edit_dm_message(self, message: discord.Message, content: str) -> None: try: diff --git a/core/time.py b/core/time.py index 331e26349f..cc30d84f30 100644 --- a/core/time.py +++ b/core/time.py @@ -134,7 +134,7 @@ def convert(self, ctx, argument): # foo date time # first the first two cases: - dt, status, begin, end, _ = elements[0] + dt, status, begin, end, x = elements[0] if not status.hasDateOrTime: return self.check_constraints(self.now, argument) diff --git a/core/translations.py b/core/translations.py new file mode 100644 index 0000000000..218b5f91ae --- /dev/null +++ b/core/translations.py @@ -0,0 +1,25 @@ +import builtins +import csv +import os + + +class Translator: + def __init__(self): + self.language = os.getenv('language', 'en') + self.texts = {} + self.generate_texts() + + def generate_texts(self): + with open(f'languages/{self.language}.csv', encoding='utf8') as f: + reader = csv.reader(f, dialect='unix') + + for n, row in enumerate(reader): + if n != 0: + self.texts[row[0]] = row[1] + + def translate(self, identifier): + return self.texts.get(identifier, identifier) + + +def init(): + builtins._ = Translator().translate diff --git a/languages/en.csv b/languages/en.csv new file mode 100644 index 0000000000..388091bab5 --- /dev/null +++ b/languages/en.csv @@ -0,0 +1,1172 @@ +"Identifier","English","Context" +"You can only setup in the Modmail guild: {guild_name}.","You can only setup in the Modmail guild: {guild_name}.","File: cogs\modmail.py/L44" +"{guild_name} is already set up.","{guild_name} is already set up.","File: cogs\modmail.py/L49" +"Error","Error","File: cogs\modmail.py/L53/L217/L225/L233/L712/L1059/L1151 cogs\utility.py/L168/L748/L774/L802/L822/L892/L979/L1045/L1085/L1092/L1099/L1125/L1245/L1316/L1378/L1559" +"Modmail functioning guild not found.","Modmail functioning guild not found.","File: cogs\modmail.py/L54" +"Friendly Reminder","Friendly Reminder","File: cogs\modmail.py/L91" +"You may use the `{prefix}config set log_channel_id ` command to set up a custom log channel, then you can delete this default {log_channel} log channel.","You may use the `{prefix}config set log_channel_id ` command to set up a custom log channel, then you can delete this default {log_channel} log channel.","File: cogs\modmail.py/L92" +"Thanks for using the bot!","Thanks for using the bot!","File: cogs\modmail.py/L99" +"If you like what you see, consider giving the [repo a star](https://github.com/kyb3r/modmail) :star: or if you are feeling generous, check us out on [Patreon](https://patreon.com/kyber)!","If you like what you see, consider giving the [repo a star](https://github.com/kyb3r/modmail) :star: or if you are feeling generous, check us out on [Patreon](https://patreon.com/kyber)!","File: cogs\modmail.py/L100" +"Type ""{prefix}help"" for a complete list of commands.","Type ""{prefix}help"" for a complete list of commands.","File: cogs\modmail.py/L106" +"**Successfully set up server.**\nConsider setting permission levels to give access to roles or users the ability to use Modmail.\n\nType:\n- `{prefix}permissions` and `{prefix}permissions add` for more info on setting permissions.\n- `{prefix}config help` for a list of available customizations.","**Successfully set up server.**\nConsider setting permission levels to give access to roles or users the ability to use Modmail.\n\nType:\n- `{prefix}permissions` and `{prefix}permissions add` for more info on setting permissions.\n- `{prefix}config help` for a list of available customizations.","File: cogs\modmail.py/L115" +"Snippets","Snippets","File: cogs\modmail.py/L175" +"Snippet `{name}` already exists.","Snippet `{name}` already exists.","File: cogs\modmail.py/L219" +"An alias with the same name already exists: `{name}`.","An alias with the same name already exists: `{name}`.","File: cogs\modmail.py/L227" +"Snippet names cannot be longer than 120 characters.","Snippet names cannot be longer than 120 characters.","File: cogs\modmail.py/L235" +"Removed snippet","Removed snippet","File: cogs\modmail.py/L256" +"Snippet `{name}` is now deleted.","Snippet `{name}` is now deleted.","File: cogs\modmail.py/L258" +"Edited snippet","Edited snippet","File: cogs\modmail.py/L281" +"Thread Moved","Thread Moved","File: cogs\modmail.py/L310" +"Scheduled close","Scheduled close","File: cogs\modmail.py/L325" +"This thread will close {silent}in {time}.","This thread will close {silent}in {time}.","File: cogs\modmail.py/L326" +"Message","Message","File: cogs\modmail.py/L331" +"Closing will be cancelled if a thread message is sent.","Closing will be cancelled if a thread message is sent.","File: cogs\modmail.py/L334" +"silent","silent","File: cogs\modmail.py/L369" +"silently","silently","File: cogs\modmail.py/L369" +"cancel","cancel","File: cogs\modmail.py/L370" +"Scheduled close has been cancelled.","Scheduled close has been cancelled.","File: cogs\modmail.py/L378" +"This thread has not already been scheduled to close.","This thread has not already been scheduled to close.","File: cogs\modmail.py/L383" +"{mention} is already going to be mentioned.","{mention} is already going to be mentioned.","File: cogs\modmail.py/L433" +"{mention} will be mentioned on the next message received.","{mention} will be mentioned on the next message received.","File: cogs\modmail.py/L440" +"{mention} does not have a pending notification.","{mention} does not have a pending notification.","File: cogs\modmail.py/L472" +"{mention} will no longer be notified.","{mention} will no longer be notified.","File: cogs\modmail.py/L479" +"{mention} is already subscribed to this thread.","{mention} is already subscribed to this thread.","File: cogs\modmail.py/L512" +"{mention} will now be notified of all messages received.","{mention} will now be notified of all messages received.","File: cogs\modmail.py/L519" +"{mention} is not already subscribed to this thread.","{mention} is not already subscribed to this thread.","File: cogs\modmail.py/L551" +"{mention} is now unsubscribed to this thread.","{mention} is now unsubscribed to this thread.","File: cogs\modmail.py/L558" +"Unknown","Unknown","File: cogs\modmail.py/L610" +"Closed By","Closed By","File: cogs\modmail.py/L613" +"Created by","Created by","File: cogs\modmail.py/L616" +"Preview","Preview","File: cogs\modmail.py/L619" +"Link","Link","File: cogs\modmail.py/L624" +"Log Key","Log Key","File: cogs\modmail.py/L627" +"Recipient ID","Recipient ID","File: cogs\modmail.py/L629" +"This user does not have any previous logs.","This user does not have any previous logs.","File: cogs\modmail.py/L660" +"No log entries have been found for that query","No log entries have been found for that query","File: cogs\modmail.py/L693" +"Log entry `{key}` not found.","Log entry `{key}` not found.","File: cogs\modmail.py/L713" +"Log entry `{key}` successfully deleted.","Log entry `{key}` successfully deleted.","File: cogs\modmail.py/L719" +"{mention} has not responded to any threads.","{mention} has not responded to any threads.","File: cogs\modmail.py/L743" +"No log entries have been found for that query.","No log entries have been found for that query.","File: cogs\modmail.py/L776" +"Failed","Failed","File: cogs\modmail.py/L869/L1177" +"Cannot find a message to edit.","Cannot find a message to edit.","File: cogs\modmail.py/L870" +"Cannot start a thread with a bot.","Cannot start a thread with a bot.","File: cogs\modmail.py/L900" +"A thread for this user already exists in {mention}.","A thread for this user already exists in {mention}.","File: cogs\modmail.py/L908" +"Created Thread","Created Thread","File: cogs\modmail.py/L919" +"Thread started by {author_mention} for {user_mention}.","Thread started by {author_mention} for {user_mention}.","File: cogs\modmail.py/L920" +"Blocked Users","Blocked Users","File: cogs\modmail.py/L939/L960" +"No Reason Provided","No Reason Provided","File: cogs\modmail.py/L960" +"(Continued)","(Continued)","File: cogs\modmail.py/L963 cogs\utility.py/L67" +"Currently there are no blocked users.","Currently there are no blocked users.","File: cogs\modmail.py/L971" +"Success","Success","File: cogs\modmail.py/L997/L1084/L1091/L1308/L1344/L1357/L1377/L1358 cogs\utility.py/L725/L759/L1231/L1291/L1367/L1392/L1559/L1595" +"{mention} is no longer whitelisted.","{mention} is no longer whitelisted.","File: cogs\modmail.py/L998" +"{mention} was previously blocked internally for ","{mention} was previously blocked internally for ","File: cogs\modmail.py/L1018" +"Cannot block {mention}, user is whitelisted.","Cannot block {mention}, user is whitelisted.","File: cogs\modmail.py/L1060" +"{mention} was previously blocked {old_reason}.\n{mention} is now blocked {reason}","{mention} was previously blocked {old_reason}.\n{mention} is now blocked {reason}","File: cogs\modmail.py/L1085" +"{mention} is now blocked {reason}","{mention} is now blocked {reason}","File: cogs\modmail.py/L1093" +"{mention} was previously blocked internally {reason}.\n{mention} is no longer blocked.","{mention} was previously blocked internally {reason}.\n{mention} is no longer blocked.","File: cogs\modmail.py/L1132" +"However, if the original system block reason still applies, {name} will be automatically blocked again. Use ","However, if the original system block reason still applies, {name} will be automatically blocked again. Use ","File: cogs\modmail.py/L1137" +"{mention} is no longer blocked.","{mention} is no longer blocked.","File: cogs\modmail.py/L1147" +"{mention} is not blocked.","{mention} is not blocked.","File: cogs\modmail.py/L1152" +"Cannot find a message to delete.","Cannot find a message to delete.","File: cogs\modmail.py/L1178" +"Modmail will now accept **all** DM messages.","Modmail will now accept **all** DM messages.","File: cogs\modmail.py/L1309" +"Modmail is already accepting all DM messages.","Modmail is already accepting all DM messages.","File: cogs\modmail.py/L1316" +"Modmail will not create any **new** threads.","Modmail will not create any **new** threads.","File: cogs\modmail.py/L1345" +"Modmail is already not creating any new threads.","Modmail is already not creating any new threads.","File: cogs\modmail.py/L1352" +"Modmail will not create **new** threads, but existing threads will now be functioning.","Modmail will not create **new** threads, but existing threads will now be functioning.","File: cogs\modmail.py/L1358" +"Modmail will not accept **any** DM messages.","Modmail will not accept **any** DM messages.","File: cogs\modmail.py/L1378" +"Modmail is already not accepting any DM messages.","Modmail is already not accepting any DM messages.","File: cogs\modmail.py/L1385" +"New Threads Disabled","New Threads Disabled","File: cogs\modmail.py/L1400" +"Modmail is not creating new threads.","Modmail is not creating new threads.","File: cogs\modmail.py/L1401" +"All DM Disabled","All DM Disabled","File: cogs\modmail.py/L1406" +"Modmail is not accepting any DM messages for new and existing threads.","Modmail is not accepting any DM messages for new and existing threads.","File: cogs\modmail.py/L1407" +"Enabled","Enabled","File: cogs\modmail.py/L1412" +"Modmail is accepting all DM messages.","Modmail is accepting all DM messages.","File: cogs\modmail.py/L1413" +"Plugins are still loading, please try again later.","Plugins are still loading, please try again later.","File: cogs\plugins.py/L230/L470" +"Your bot's version is too low. This plugin requires version `{required_version}`.","Your bot's version is too low. This plugin requires version `{required_version}`.","File: cogs\plugins.py/L246" +"Invalid plugin name, double check the plugin name or use one of the following formats: username/repo/plugin, username/repo/plugin@branch.","Invalid plugin name, double check the plugin name or use one of the following formats: username/repo/plugin, username/repo/plugin@branch.","File: cogs\plugins.py/L260" +"This plugin is already installed.","This plugin is already installed.","File: cogs\plugins.py/L295" +"Cannot install this plugin (dupe cog name).","Cannot install this plugin (dupe cog name).","File: cogs\plugins.py/L303" +"Starting to download plugin from {plugin_link}...","Starting to download plugin from {plugin_link}...","File: cogs\plugins.py/L309" +"Failed to download plugin, check logs for error.","Failed to download plugin, check logs for error.","File: cogs\plugins.py/L320" +"Successfully installed plugin.\n*Friendly reminder, plugins have absolute control over your bot. Please only install plugins from developers you trust.*","Successfully installed plugin.\n*Friendly reminder, plugins have absolute control over your bot. Please only install plugins from developers you trust.*","File: cogs\plugins.py/L345" +"This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot.","This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot.","File: cogs\plugins.py/L355" +"Plugin is not installed.","Plugin is not installed.","File: cogs\plugins.py/L376/L415" +"The plugin is successfully uninstalled.","The plugin is successfully uninstalled.","File: cogs\plugins.py/L402" +"Successfully updated {plugin_name}.","Successfully updated {plugin_name}.","File: cogs\plugins.py/L429" +"No plugins are loaded due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot.","No plugins are loaded due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot.","File: cogs\plugins.py/L462" +"There are no plugins currently loaded.","There are no plugins currently loaded.","File: cogs\plugins.py/L477" +"Loaded plugins:","Loaded plugins:","File: cogs\plugins.py/L498" +"Could not find a plugin with name ""{plugin_name}"" within the registry.","Could not find a plugin with name ""{plugin_name}"" within the registry.","File: cogs\plugins.py/L534" +"Perhaps you meant:","Perhaps you meant:","File: cogs\plugins.py/L541 cogs\utility.py/L211" +"Installation","Installation","File: cogs\plugins.py/L562" +"Your bot is unable to install this plugin, minimum required version is v{required_version}.","Your bot is unable to install this plugin, minimum required version is v{required_version}.","File: cogs\plugins.py/L582" +"Your bot is able to install this plugin.","Your bot is able to install this plugin.","File: cogs\plugins.py/L586" +"Plugin Registry","Plugin Registry","File: cogs\plugins.py/L641" +" + if not format_.strip(): + continue + if len(format_) + len(formats[-1]) >= 1024: + formats.append(format_) + else: + formats[-1] += format_ + + embeds = [] + for format_ in formats: + description = ( + _(cog.description) or _()"," + if not format_.strip(): + continue + if len(format_) + len(formats[-1]) >= 1024: + formats.append(format_) + else: + formats[-1] += format_ + + embeds = [] + for format_ in formats: + description = ( + _(cog.description) or _()","File: cogs\utility.py/L50" +"Miscellaneous commands without a category.","Miscellaneous commands without a category.","File: cogs\utility.py/L63" +"Commands","Commands","File: cogs\utility.py/L67" +"No commands.","No commands.","File: cogs\utility.py/L67" +"Help","Help","File: cogs\utility.py/L71" +"Miscellaneous Commands","Miscellaneous Commands","File: cogs\utility.py/L73" +"Type ""{prefix}{command} command"" ","Type ""{prefix}{command} command"" ","File: cogs\utility.py/L78/L153" +"NONE","NONE","File: cogs\utility.py/L119" +"","","File: cogs\utility.py/L124" +"Permission Level","Permission Level","File: cogs\utility.py/L139" +" + + embed.add_field(name=_()"," + + embed.add_field(name=_()","File: cogs\utility.py/L153" +"{command} is a snippet.","{command} is a snippet.","File: cogs\utility.py/L168" +"Alias `{command}` is invalid, this alias will now be deleted.This alias will now be deleted.","Alias `{command}` is invalid, this alias will now be deleted.This alias will now be deleted.","File: cogs\utility.py/L181" +"{command} is an alias.","{command} is an alias.","File: cogs\utility.py/L190/L192" +"`{command}` points to:","`{command}` points to:","File: cogs\utility.py/L192" +"**`{command}` points to the following steps:**","**`{command}` points to the following steps:**","File: cogs\utility.py/L197" +"Step","Step","File: cogs\utility.py/L200/L1045" +"Type ""{prefix}{command} alias"" ","Type ""{prefix}{command} alias"" ","File: cogs\utility.py/L203" +"Command/Category ""{command}"" not found.","Command/Category ""{command}"" not found.","File: cogs\utility.py/L211" +"Cannot find command or category","Cannot find command or category","File: cogs\utility.py/L225" +"Type ""{prefix}{command}"" ","Type ""{prefix}{command}"" ","File: cogs\utility.py/L227" +"Shows this help message.","Shows this help message.","File: cogs\utility.py/L242" +"The specified version `{version}` could not be found.","The specified version `{version}` could not be found.","File: cogs\utility.py/L266" +"View the changelog here: {url}","View the changelog here: {url}","File: cogs\utility.py/L282" +"Modmail - About","Modmail - About","File: cogs\utility.py/L292" +"This is an open source Discord bot that serves as a means for members to easily communicate with server administrators in an organised manner.","This is an open source Discord bot that serves as a means for members to easily communicate with server administrators in an organised manner.","File: cogs\utility.py/L298" +"Uptime","Uptime","File: cogs\utility.py/L303" +"Latency","Latency","File: cogs\utility.py/L304" +"Version","Version","File: cogs\utility.py/L305" +"Authors","Authors","File: cogs\utility.py/L306" +"You are on the prerelease version • the latest version is v{version}.","You are on the prerelease version • the latest version is v{version}.","File: cogs\utility.py/L315" +"A newer version is available v{version}.","A newer version is available v{version}.","File: cogs\utility.py/L317" +"You are up to date with the latest version.","You are up to date with the latest version.","File: cogs\utility.py/L319" +"Want Modmail in Your Server?","Want Modmail in Your Server?","File: cogs\utility.py/L322" +"Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) and join our [Discord server](https://discord.gg/F34cRU8/)!","Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) and join our [Discord server](https://discord.gg/F34cRU8/)!","File: cogs\utility.py/L323" +"Support the Developers","Support the Developers","File: cogs\utility.py/L329" +"This bot is completely free for everyone. We rely on kind individuals like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) to keep this bot free forever!","This bot is completely free for everyone. We rely on kind individuals like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) to keep this bot free forever!","File: cogs\utility.py/L330" +"Debug Logs:","Debug Logs:","File: cogs\utility.py/L379" +"You don't have any logs at the moment.","You don't have any logs at the moment.","File: cogs\utility.py/L380" +"Go to Heroku to see your logs.","Go to Heroku to see your logs.","File: cogs\utility.py/L382/L450" +"Debug logs - Navigate using the reactions below.","Debug logs - Navigate using the reactions below.","File: cogs\utility.py/L408" +"Debug Logs","Debug Logs","File: cogs\utility.py/L440" +"Something's wrong. We're unable to upload your logs to hastebin.","Something's wrong. We're unable to upload your logs to hastebin.","File: cogs\utility.py/L448" +"Cached logs are now cleared.","Cached logs are now cleared.","File: cogs\utility.py/L470" +"Activity Removed","Activity Removed","File: cogs\utility.py/L501" +"Activity set to: {name} ","Activity set to: {name} ","File: cogs\utility.py/L520" +"to {name}.","to {name}.","File: cogs\utility.py/L522" +"Activity Changed","Activity Changed","File: cogs\utility.py/L527" +"Status Removed","Status Removed","File: cogs\utility.py/L550" +"Status set to: {value}.","Status set to: {value}.","File: cogs\utility.py/L564" +"Status Changed","Status Changed","File: cogs\utility.py/L566" +"Pong! Websocket Latency:","Pong! Websocket Latency:","File: cogs\utility.py/L638" +"Current mention:","Current mention:","File: cogs\utility.py/L657" +"Changed mention!","Changed mention!","File: cogs\utility.py/L663" +"On thread creation the bot now says ""{mention}"".","On thread creation the bot now says ""{mention}"".","File: cogs\utility.py/L664" +"Current prefix","Current prefix","File: cogs\utility.py/L683" +"Changed prefix!","Changed prefix!","File: cogs\utility.py/L689" +"Set prefix to `{prefix}`","Set prefix to `{prefix}`","File: cogs\utility.py/L690" +"Available configuration keys:","Available configuration keys:","File: cogs\utility.py/L725" +"Set `{key}` to `{value}`.","Set `{key}` to `{value}`.","File: cogs\utility.py/L748" +"{key} is an invalid key.","{key} is an invalid key.","File: cogs\utility.py/L756/L780" +"Valid keys","Valid keys","File: cogs\utility.py/L759/L783" +"`{key}` had been reset to default.","`{key}` had been reset to default.","File: cogs\utility.py/L774" +"`{key}` is set to `{value}`","`{key}` is set to `{value}`","File: cogs\utility.py/L799" +"Config variable","Config variable","File: cogs\utility.py/L802" +"`{key}` is an invalid key.","`{key}` is an invalid key.","File: cogs\utility.py/L809/L822" +"Type ""{prefix}config options"" for a list of config variables.","Type ""{prefix}config options"" for a list of config variables.","File: cogs\utility.py/L812" +"Here is a list of currently set configuration variable(s).","Here is a list of currently set configuration variable(s).","File: cogs\utility.py/L818" +"Current config(s):","Current config(s):","File: cogs\utility.py/L822" +"No help details found for `{key}`.","No help details found for `{key}`.","File: cogs\utility.py/L862" +"Configuration description on {current_key}:","Configuration description on {current_key}:","File: cogs\utility.py/L875" +"Information:","Information:","File: cogs\utility.py/L880" +"Example(s):","Example(s):","File: cogs\utility.py/L886" +"Note(s):","Note(s):","File: cogs\utility.py/L892" +"Alias `{name}` is invalid, it used to be `{value}`. This alias will now be deleted.","Alias `{name}` is invalid, it used to be `{value}`. This alias will now be deleted.","File: cogs\utility.py/L939" +"Alias","Alias","File: cogs\utility.py/L949" +"You dont have any aliases at the moment.","You dont have any aliases at the moment.","File: cogs\utility.py/L968" +"Do {prefix}help alias for more commands.","Do {prefix}help alias for more commands.","File: cogs\utility.py/L970" +"Aliases","Aliases","File: cogs\utility.py/L971" +"Command Aliases","Command Aliases","File: cogs\utility.py/L979" +"Invalid multi-step alias, try wrapping each steps in quotes.","Invalid multi-step alias, try wrapping each steps in quotes.","File: cogs\utility.py/L1009" +"{action} alias","{action} alias","File: cogs\utility.py/L1024" +"`{name}` points to:","`{name}` points to:","File: cogs\utility.py/L1027" +"`{name}` now points to the following steps:","`{name}` now points to the following steps:","File: cogs\utility.py/L1029" +"The command you are attempting to point to does not exist: `{command}`.","The command you are attempting to point to does not exist: `{command}`.","File: cogs\utility.py/L1045" +"The command you are attempting to point to on step {number} does not exist: `{command}`.","The command you are attempting to point to on step {number} does not exist: `{command}`.","File: cogs\utility.py/L1045" +"A command with the same name already exists: `{name}`.","A command with the same name already exists: `{name}`.","File: cogs\utility.py/L1085" +"Another alias with the same name already exists: `{name}`.","Another alias with the same name already exists: `{name}`.","File: cogs\utility.py/L1092" +"A snippet with the same name already exists: `{name}`.","A snippet with the same name already exists: `{name}`.","File: cogs\utility.py/L1099" +"Alias names cannot be longer than 120 characters.","Alias names cannot be longer than 120 characters.","File: cogs\utility.py/L1106" +"Removed alias","Removed alias","File: cogs\utility.py/L1123" +"Successfully deleted `{name}`.","Successfully deleted `{name}`.","File: cogs\utility.py/L1125" +"The referenced level does not exist: `{level}`.","The referenced level does not exist: `{level}`.","File: cogs\utility.py/L1231" +"Successfully set command permission level for `{command}` to `{level}`.","Successfully set command permission level for `{command}` to `{level}`.","File: cogs\utility.py/L1245" +"The referenced {type} does not exist: `{name}`.","The referenced {type} does not exist: `{name}`.","File: cogs\utility.py/L1291" +"Permission for `{name}` was successfully updated.","Permission for `{name}` was successfully updated.","File: cogs\utility.py/L1316/L1419" +"The command permission level was never overridden: `{name}`, current permission level is {perm_name}.","The command permission level was never overridden: `{name}`, current permission level is {perm_name}.","File: cogs\utility.py/L1367/L1559" +"Command permission level for `{name}` was successfully restored to {perm_name}.","Command permission level for `{name}` was successfully restored to {perm_name}.","File: cogs\utility.py/L1378" +"The referenced level does not exist: `{name}`.","The referenced level does not exist: `{name}`.","File: cogs\utility.py/L1392" +"Permission entries for {type} `{name}`:","Permission entries for {type} `{name}`:","File: cogs\utility.py/L1430/L1455" +"No permission entries found.","No permission entries found.","File: cogs\utility.py/L1431/L1523" +"{mention} has permission with the following commands:","{mention} has permission with the following commands:","File: cogs\utility.py/L1528" +"{mention} has permission with the following permission levels:","{mention} has permission with the following permission levels:","File: cogs\utility.py/L1533" +"Permission Overrides","Permission Overrides","File: cogs\utility.py/L1558/L1559" +"You don't have any command level overrides at the moment.","You don't have any command level overrides at the moment.","File: cogs\utility.py/L1559" +"Permission override for command ""{name}"" is ""{perm_name}"".","Permission override for command ""{name}"" is ""{perm_name}"".","File: cogs\utility.py/L1595" +"Un-whitelisted {target_mention} to view logs.","Un-whitelisted {target_mention} to view logs.","File: cogs\utility.py/L1678" +"Whitelisted {target_mention} to view logs.","Whitelisted {target_mention} to view logs.","File: cogs\utility.py/L1682" +"Oauth Whitelist","Oauth Whitelist","File: cogs\utility.py/L1705" +"Users","Users","File: cogs\utility.py/L1708" +"None","None","File: cogs\utility.py/L1708" +"Channel has been deleted, no closer found.","Channel has been deleted, no closer found.","File: bot.py/L472" +"System Message: New Account. Required to wait for {time}.","System Message: New Account. Required to wait for {time}.","File: bot.py/L552" +"Commands directly related to Modmail functionality.","Commands directly related to Modmail functionality.","Cog: Modmail" +"Sets up a server for Modmail.","Sets up a server for Modmail.","Cog: Modmail +Command: setup" +"Sets up a server for Modmail. + +You only need to run this command +once after configuring Modmail.","Sets up a server for Modmail. + +You only need to run this command +once after configuring Modmail.","Cog: Modmail +Command: setup" +"Create pre-defined messages for use in threads.","Create pre-defined messages for use in threads.","Cog: Modmail +Command: snippet" +"Create pre-defined messages for use in threads. + +When `{prefix}snippet` is used by itself, this will retrieve +a list of snippets that are currently set. `{prefix}snippet-name` will show what the +snippet point to. + +To create a snippet: +- `{prefix}snippet add snippet-name A pre-defined text.` + +You can use your snippet in a thread channel +with `{prefix}snippet-name`, the message ""A pre-defined text."" +will be sent to the recipient. + +Currently, there is not a built-in anonymous snippet command; however, a workaround +is available using `{prefix}alias`. Here is how: +- `{prefix}alias add snippet-name anonreply A pre-defined anonymous text.` + +See also `{prefix}alias`.","Create pre-defined messages for use in threads. + +When `{prefix}snippet` is used by itself, this will retrieve +a list of snippets that are currently set. `{prefix}snippet-name` will show what the +snippet point to. + +To create a snippet: +- `{prefix}snippet add snippet-name A pre-defined text.` + +You can use your snippet in a thread channel +with `{prefix}snippet-name`, the message ""A pre-defined text."" +will be sent to the recipient. + +Currently, there is not a built-in anonymous snippet command; however, a workaround +is available using `{prefix}alias`. Here is how: +- `{prefix}alias add snippet-name anonreply A pre-defined anonymous text.` + +See also `{prefix}alias`.","Cog: Modmail +Command: snippet" +"View the raw content of a snippet.","View the raw content of a snippet.","Cog: Modmail +Command: snippet raw" +"View the raw content of a snippet.","View the raw content of a snippet.","Cog: Modmail +Command: snippet raw" +"Add a snippet.","Add a snippet.","Cog: Modmail +Command: snippet add" +"Add a snippet. + +Simply to add a snippet, do: ``` +{prefix}snippet add hey hello there :) +``` +then when you type `{prefix}hey`, ""hello there :)"" will get sent to the recipient. + +To add a multi-word snippet name, use quotes: ``` +{prefix}snippet add ""two word"" this is a two word snippet. +```","Add a snippet. + +Simply to add a snippet, do: ``` +{prefix}snippet add hey hello there :) +``` +then when you type `{prefix}hey`, ""hello there :)"" will get sent to the recipient. + +To add a multi-word snippet name, use quotes: ``` +{prefix}snippet add ""two word"" this is a two word snippet. +```","Cog: Modmail +Command: snippet add" +"Remove a snippet.","Remove a snippet.","Cog: Modmail +Command: snippet remove" +"Remove a snippet.","Remove a snippet.","Cog: Modmail +Command: snippet remove" +"Edit a snippet.","Edit a snippet.","Cog: Modmail +Command: snippet edit" +"Edit a snippet. + +To edit a multi-word snippet name, use quotes: ``` +{prefix}snippet edit ""two word"" this is a new two word snippet. +```","Edit a snippet. + +To edit a multi-word snippet name, use quotes: ``` +{prefix}snippet edit ""two word"" this is a new two word snippet. +```","Cog: Modmail +Command: snippet edit" +"Move a thread to another category.","Move a thread to another category.","Cog: Modmail +Command: move" +"Move a thread to another category. + +`category` may be a category ID, mention, or name. +`specifics` is a string which takes in arguments on how to perform the move. Ex: ""silently""","Move a thread to another category. + +`category` may be a category ID, mention, or name. +`specifics` is a string which takes in arguments on how to perform the move. Ex: ""silently""","Cog: Modmail +Command: move" +"Close the current thread.","Close the current thread.","Cog: Modmail +Command: close" +"Close the current thread. + +Close after a period of time: +- `{prefix}close in 5 hours` +- `{prefix}close 2m30s` + +Custom close messages: +- `{prefix}close 2 hours The issue has been resolved.` +- `{prefix}close We will contact you once we find out more.` + +Silently close a thread (no message) +- `{prefix}close silently` +- `{prefix}close in 10m silently` + +Stop a thread from closing: +- `{prefix}close cancel`","Close the current thread. + +Close after a period of time: +- `{prefix}close in 5 hours` +- `{prefix}close 2m30s` + +Custom close messages: +- `{prefix}close 2 hours The issue has been resolved.` +- `{prefix}close We will contact you once we find out more.` + +Silently close a thread (no message) +- `{prefix}close silently` +- `{prefix}close in 10m silently` + +Stop a thread from closing: +- `{prefix}close cancel`","Cog: Modmail +Command: close" +"Notify a user or role when the next thread message received.","Notify a user or role when the next thread message received.","Cog: Modmail +Command: notify" +"Notify a user or role when the next thread message received. + +Once a thread message is received, `user_or_role` will be pinged once. + +Leave `user_or_role` empty to notify yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name. role ID, mention, name, ""everyone"", or ""here"".","Notify a user or role when the next thread message received. + +Once a thread message is received, `user_or_role` will be pinged once. + +Leave `user_or_role` empty to notify yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name. role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail +Command: notify" +"Un-notify a user, role, or yourself from a thread.","Un-notify a user, role, or yourself from a thread.","Cog: Modmail +Command: unnotify" +"Un-notify a user, role, or yourself from a thread. + +Leave `user_or_role` empty to un-notify yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Un-notify a user, role, or yourself from a thread. + +Leave `user_or_role` empty to un-notify yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail +Command: unnotify" +"Notify a user, role, or yourself for every thread message received.","Notify a user, role, or yourself for every thread message received.","Cog: Modmail +Command: subscribe" +"Notify a user, role, or yourself for every thread message received. + +You will be pinged for every thread message received until you unsubscribe. + +Leave `user_or_role` empty to subscribe yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Notify a user, role, or yourself for every thread message received. + +You will be pinged for every thread message received until you unsubscribe. + +Leave `user_or_role` empty to subscribe yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail +Command: subscribe" +"Unsubscribe a user, role, or yourself from a thread.","Unsubscribe a user, role, or yourself from a thread.","Cog: Modmail +Command: unsubscribe" +"Unsubscribe a user, role, or yourself from a thread. + +Leave `user_or_role` empty to unsubscribe yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Unsubscribe a user, role, or yourself from a thread. + +Leave `user_or_role` empty to unsubscribe yourself. +`@here` and `@everyone` can be substituted with `here` and `everyone`. +`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail +Command: unsubscribe" +"Flags a Modmail thread as NSFW (not safe for work).","Flags a Modmail thread as NSFW (not safe for work).","Cog: Modmail +Command: nsfw" +"Flags a Modmail thread as NSFW (not safe for work).","Flags a Modmail thread as NSFW (not safe for work).","Cog: Modmail +Command: nsfw" +"Flags a Modmail thread as SFW (safe for work).","Flags a Modmail thread as SFW (safe for work).","Cog: Modmail +Command: sfw" +"Flags a Modmail thread as SFW (safe for work).","Flags a Modmail thread as SFW (safe for work).","Cog: Modmail +Command: sfw" +"Retrieves the link to the current thread's logs.","Retrieves the link to the current thread's logs.","Cog: Modmail +Command: loglink" +"Retrieves the link to the current thread's logs.","Retrieves the link to the current thread's logs.","Cog: Modmail +Command: loglink" +"Get previous Modmail thread logs of a member.","Get previous Modmail thread logs of a member.","Cog: Modmail +Command: logs" +"Get previous Modmail thread logs of a member. + +Leave `user` blank when this command is used within a +thread channel to show logs for the current recipient. +`user` may be a user ID, mention, or name.","Get previous Modmail thread logs of a member. + +Leave `user` blank when this command is used within a +thread channel to show logs for the current recipient. +`user` may be a user ID, mention, or name.","Cog: Modmail +Command: logs" +"Get all logs closed by the specified user.","Get all logs closed by the specified user.","Cog: Modmail +Command: logs closed-by" +"Get all logs closed by the specified user. + +If no `user` is provided, the user will be the person who sent this command. +`user` may be a user ID, mention, or name.","Get all logs closed by the specified user. + +If no `user` is provided, the user will be the person who sent this command. +`user` may be a user ID, mention, or name.","Cog: Modmail +Command: logs closed-by" +"Wipe a log entry from the database.","Wipe a log entry from the database.","Cog: Modmail +Command: logs delete" +"Wipe a log entry from the database.","Wipe a log entry from the database.","Cog: Modmail +Command: logs delete" +"Get all logs where the specified user has responded at least once.","Get all logs where the specified user has responded at least once.","Cog: Modmail +Command: logs responded" +"Get all logs where the specified user has responded at least once. + +If no `user` is provided, the user will be the person who sent this command. +`user` may be a user ID, mention, or name.","Get all logs where the specified user has responded at least once. + +If no `user` is provided, the user will be the person who sent this command. +`user` may be a user ID, mention, or name.","Cog: Modmail +Command: logs responded" +"Retrieve all logs that contain messages with your query.","Retrieve all logs that contain messages with your query.","Cog: Modmail +Command: logs search" +"Retrieve all logs that contain messages with your query. + +Provide a `limit` to specify the maximum number of logs the bot should find.","Retrieve all logs that contain messages with your query. + +Provide a `limit` to specify the maximum number of logs the bot should find.","Cog: Modmail +Command: logs search" +"Reply to a Modmail thread.","Reply to a Modmail thread.","Cog: Modmail +Command: reply" +"Reply to a Modmail thread. + +Supports attachments and images as well as +automatically embedding image URLs.","Reply to a Modmail thread. + +Supports attachments and images as well as +automatically embedding image URLs.","Cog: Modmail +Command: reply" +"Reply to a Modmail thread with variables.","Reply to a Modmail thread with variables.","Cog: Modmail +Command: freply" +"Reply to a Modmail thread with variables. + +Works just like `{prefix}reply`, however with the addition of three variables: + - `{{channel}}` - the `discord.TextChannel` object + - `{{recipient}}` - the `discord.User` object of the recipient + - `{{author}}` - the `discord.User` object of the author + +Supports attachments and images as well as +automatically embedding image URLs.","Reply to a Modmail thread with variables. + +Works just like `{prefix}reply`, however with the addition of three variables: + - `{{channel}}` - the `discord.TextChannel` object + - `{{recipient}}` - the `discord.User` object of the recipient + - `{{author}}` - the `discord.User` object of the author + +Supports attachments and images as well as +automatically embedding image URLs.","Cog: Modmail +Command: freply" +"Reply to a thread anonymously.","Reply to a thread anonymously.","Cog: Modmail +Command: areply" +"Reply to a thread anonymously. + +You can edit the anonymous user's name, +avatar and tag using the config command. + +Edit the `anon_username`, `anon_avatar_url` +and `anon_tag` config variables to do so.","Reply to a thread anonymously. + +You can edit the anonymous user's name, +avatar and tag using the config command. + +Edit the `anon_username`, `anon_avatar_url` +and `anon_tag` config variables to do so.","Cog: Modmail +Command: areply" +"Take a note about the current thread.","Take a note about the current thread.","Cog: Modmail +Command: note" +"Take a note about the current thread. + +Useful for noting context.","Take a note about the current thread. + +Useful for noting context.","Cog: Modmail +Command: note" +"Edit a message that was sent using the reply or anonreply command.","Edit a message that was sent using the reply or anonreply command.","Cog: Modmail +Command: edit" +"Edit a message that was sent using the reply or anonreply command. + +If no `message_id` is provided, +the last message sent by a staff will be edited. + +Note: attachments **cannot** be edited.","Edit a message that was sent using the reply or anonreply command. + +If no `message_id` is provided, +the last message sent by a staff will be edited. + +Note: attachments **cannot** be edited.","Cog: Modmail +Command: edit" +"Create a thread with a specified member.","Create a thread with a specified member.","Cog: Modmail +Command: contact" +"Create a thread with a specified member. + +If `category` is specified, the thread +will be created in that specified category. + +`category`, if specified, may be a category ID, mention, or name. +`user` may be a user ID, mention, or name.","Create a thread with a specified member. + +If `category` is specified, the thread +will be created in that specified category. + +`category`, if specified, may be a category ID, mention, or name. +`user` may be a user ID, mention, or name.","Cog: Modmail +Command: contact" +"Retrieve a list of blocked users.","Retrieve a list of blocked users.","Cog: Modmail +Command: blocked" +"Retrieve a list of blocked users.","Retrieve a list of blocked users.","Cog: Modmail +Command: blocked" +"Whitelist or un-whitelist a user from getting blocked.","Whitelist or un-whitelist a user from getting blocked.","Cog: Modmail +Command: blocked whitelist" +"Whitelist or un-whitelist a user from getting blocked. + +Useful for preventing users from getting blocked by account_age/guild_age restrictions.","Whitelist or un-whitelist a user from getting blocked. + +Useful for preventing users from getting blocked by account_age/guild_age restrictions.","Cog: Modmail +Command: blocked whitelist" +"Block a user from using Modmail.","Block a user from using Modmail.","Cog: Modmail +Command: block" +"Block a user from using Modmail. + +You may choose to set a time as to when the user will automatically be unblocked. + +Leave `user` blank when this command is used within a +thread channel to block the current recipient. +`user` may be a user ID, mention, or name. +`duration` may be a simple ""human-readable"" time text. See `{prefix}help close` for examples.","Block a user from using Modmail. + +You may choose to set a time as to when the user will automatically be unblocked. + +Leave `user` blank when this command is used within a +thread channel to block the current recipient. +`user` may be a user ID, mention, or name. +`duration` may be a simple ""human-readable"" time text. See `{prefix}help close` for examples.","Cog: Modmail +Command: block" +"Unblock a user from using Modmail.","Unblock a user from using Modmail.","Cog: Modmail +Command: unblock" +"Unblock a user from using Modmail. + +Leave `user` blank when this command is used within a +thread channel to unblock the current recipient. +`user` may be a user ID, mention, or name.","Unblock a user from using Modmail. + +Leave `user` blank when this command is used within a +thread channel to unblock the current recipient. +`user` may be a user ID, mention, or name.","Cog: Modmail +Command: unblock" +"Delete a message that was sent using the reply command or a note.","Delete a message that was sent using the reply command or a note.","Cog: Modmail +Command: delete" +"Delete a message that was sent using the reply command or a note. + +Deletes the previous message, unless a message ID is provided, +which in that case, deletes the message with that message ID. + +Notes can only be deleted when a note ID is provided.","Delete a message that was sent using the reply command or a note. + +Deletes the previous message, unless a message ID is provided, +which in that case, deletes the message with that message ID. + +Notes can only be deleted when a note ID is provided.","Cog: Modmail +Command: delete" +"Repair a thread broken by Discord.","Repair a thread broken by Discord.","Cog: Modmail +Command: repair" +"Repair a thread broken by Discord.","Repair a thread broken by Discord.","Cog: Modmail +Command: repair" +"Re-enables DM functionalities of Modmail.","Re-enables DM functionalities of Modmail.","Cog: Modmail +Command: enable" +"Re-enables DM functionalities of Modmail. + +Undo's the `{prefix}disable` command, all DM will be relayed after running this command.","Re-enables DM functionalities of Modmail. + +Undo's the `{prefix}disable` command, all DM will be relayed after running this command.","Cog: Modmail +Command: enable" +"Disable partial or full Modmail thread functions.","Disable partial or full Modmail thread functions.","Cog: Modmail +Command: disable" +"Disable partial or full Modmail thread functions. + +To stop all new threads from being created, do `{prefix}disable new`. +To stop all existing threads from DMing Modmail, do `{prefix}disable all`. +To check if the DM function for Modmail is enabled, do `{prefix}isenable`.","Disable partial or full Modmail thread functions. + +To stop all new threads from being created, do `{prefix}disable new`. +To stop all existing threads from DMing Modmail, do `{prefix}disable all`. +To check if the DM function for Modmail is enabled, do `{prefix}isenable`.","Cog: Modmail +Command: disable" +"Stop accepting new Modmail threads.","Stop accepting new Modmail threads.","Cog: Modmail +Command: disable new" +"Stop accepting new Modmail threads. + +No new threads can be created through DM.","Stop accepting new Modmail threads. + +No new threads can be created through DM.","Cog: Modmail +Command: disable new" +"Disables all DM functionalities of Modmail.","Disables all DM functionalities of Modmail.","Cog: Modmail +Command: disable all" +"Disables all DM functionalities of Modmail. + +No new threads can be created through DM nor no further DM messages will be relayed.","Disables all DM functionalities of Modmail. + +No new threads can be created through DM nor no further DM messages will be relayed.","Cog: Modmail +Command: disable all" +"Check if the DM functionalities of Modmail is enabled.","Check if the DM functionalities of Modmail is enabled.","Cog: Modmail +Command: isenable" +"Check if the DM functionalities of Modmail is enabled.","Check if the DM functionalities of Modmail is enabled.","Cog: Modmail +Command: isenable" +"Plugins expand Modmail functionality by allowing third-party addons. + +These addons could have a range of features from moderation to simply +making your life as a moderator easier! +Learn how to create a plugin yourself here: +https://github.com/kyb3r/modmail/wiki/Plugins","Plugins expand Modmail functionality by allowing third-party addons. + +These addons could have a range of features from moderation to simply +making your life as a moderator easier! +Learn how to create a plugin yourself here: +https://github.com/kyb3r/modmail/wiki/Plugins","Cog: Plugins" +"Manage plugins for Modmail.","Manage plugins for Modmail.","Cog: Plugins +Command: plugins" +"Manage plugins for Modmail.","Manage plugins for Modmail.","Cog: Plugins +Command: plugins" +"Install a new plugin for the bot.","Install a new plugin for the bot.","Cog: Plugins +Command: plugins add" +"Install a new plugin for the bot. + +`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, +or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Install a new plugin for the bot. + +`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, +or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Cog: Plugins +Command: plugins add" +"Remove an installed plugin of the bot.","Remove an installed plugin of the bot.","Cog: Plugins +Command: plugins remove" +"Remove an installed plugin of the bot. + +`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference +to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Remove an installed plugin of the bot. + +`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference +to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Cog: Plugins +Command: plugins remove" +"Update a plugin for the bot.","Update a plugin for the bot.","Cog: Plugins +Command: plugins update" +"Update a plugin for the bot. + +`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference +to a GitHub hosted plugin (in the format `user/repo/name[@branch]`). + +To update all plugins, do `{prefix}plugins update`.","Update a plugin for the bot. + +`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference +to a GitHub hosted plugin (in the format `user/repo/name[@branch]`). + +To update all plugins, do `{prefix}plugins update`.","Cog: Plugins +Command: plugins update" +"Show a list of currently loaded plugins.","Show a list of currently loaded plugins.","Cog: Plugins +Command: plugins loaded" +"Show a list of currently loaded plugins.","Show a list of currently loaded plugins.","Cog: Plugins +Command: plugins loaded" +"Shows a list of all approved plugins.","Shows a list of all approved plugins.","Cog: Plugins +Command: plugins registry" +"Shows a list of all approved plugins. + +Usage: +`{prefix}plugin registry` Details about all plugins. +`{prefix}plugin registry plugin-name` Details about the indicated plugin. +`{prefix}plugin registry page-number` Jump to a page in the registry.","Shows a list of all approved plugins. + +Usage: +`{prefix}plugin registry` Details about all plugins. +`{prefix}plugin registry plugin-name` Details about the indicated plugin. +`{prefix}plugin registry page-number` Jump to a page in the registry.","Cog: Plugins +Command: plugins registry" +"Shows a compact view of all plugins within the registry.","Shows a compact view of all plugins within the registry.","Cog: Plugins +Command: plugins registry compact" +"Shows a compact view of all plugins within the registry.","Shows a compact view of all plugins within the registry.","Cog: Plugins +Command: plugins registry compact" +"General commands that provide utility.","General commands that provide utility.","Cog: Utility" +"Shows the changelog of the Modmail.","Shows the changelog of the Modmail.","Cog: Utility +Command: changelog" +"Shows the changelog of the Modmail.","Shows the changelog of the Modmail.","Cog: Utility +Command: changelog" +"Shows information about this bot.","Shows information about this bot.","Cog: Utility +Command: about" +"Shows information about this bot.","Shows information about this bot.","Cog: Utility +Command: about" +"Shows a list of sponsors.","Shows a list of sponsors.","Cog: Utility +Command: sponsors" +"Shows a list of sponsors.","Shows a list of sponsors.","Cog: Utility +Command: sponsors" +"Shows the recent application logs of the bot.","Shows the recent application logs of the bot.","Cog: Utility +Command: debug" +"Shows the recent application logs of the bot.","Shows the recent application logs of the bot.","Cog: Utility +Command: debug" +"Posts application-logs to Hastebin.","Posts application-logs to Hastebin.","Cog: Utility +Command: debug hastebin" +"Posts application-logs to Hastebin.","Posts application-logs to Hastebin.","Cog: Utility +Command: debug hastebin" +"Clears the locally cached logs.","Clears the locally cached logs.","Cog: Utility +Command: debug clear" +"Clears the locally cached logs.","Clears the locally cached logs.","Cog: Utility +Command: debug clear" +"Set an activity status for the bot.","Set an activity status for the bot.","Cog: Utility +Command: activity" +"Set an activity status for the bot. + +Possible activity types: + - `playing` + - `streaming` + - `listening` + - `watching` + +When activity type is set to `listening`, +it must be followed by a ""to"": ""listening to..."" + +When activity type is set to `streaming`, you can set +the linked twitch page: +- `{prefix}config set twitch_url https://www.twitch.tv/somechannel/` + +To remove the current activity status: +- `{prefix}activity clear`","Set an activity status for the bot. + +Possible activity types: + - `playing` + - `streaming` + - `listening` + - `watching` + +When activity type is set to `listening`, +it must be followed by a ""to"": ""listening to..."" + +When activity type is set to `streaming`, you can set +the linked twitch page: +- `{prefix}config set twitch_url https://www.twitch.tv/somechannel/` + +To remove the current activity status: +- `{prefix}activity clear`","Cog: Utility +Command: activity" +"Set a status for the bot.","Set a status for the bot.","Cog: Utility +Command: status" +"Set a status for the bot. + +Possible status types: + - `online` + - `idle` + - `dnd` or `do not disturb` + - `invisible` or `offline` + +To remove the current status: +- `{prefix}status clear`","Set a status for the bot. + +Possible status types: + - `online` + - `idle` + - `dnd` or `do not disturb` + - `invisible` or `offline` + +To remove the current status: +- `{prefix}status clear`","Cog: Utility +Command: status" +"Pong! Returns your websocket latency.","Pong! Returns your websocket latency.","Cog: Utility +Command: ping" +"Pong! Returns your websocket latency.","Pong! Returns your websocket latency.","Cog: Utility +Command: ping" +"Change what the bot mentions at the start of each thread.","Change what the bot mentions at the start of each thread.","Cog: Utility +Command: mention" +"Change what the bot mentions at the start of each thread. + +Type only `{prefix}mention` to retrieve your current ""mention"" message.","Change what the bot mentions at the start of each thread. + +Type only `{prefix}mention` to retrieve your current ""mention"" message.","Cog: Utility +Command: mention" +"Change the prefix of the bot.","Change the prefix of the bot.","Cog: Utility +Command: prefix" +"Change the prefix of the bot. + +Type only `{prefix}prefix` to retrieve your current bot prefix.","Change the prefix of the bot. + +Type only `{prefix}prefix` to retrieve your current bot prefix.","Cog: Utility +Command: prefix" +"Modify changeable configuration variables for this bot.","Modify changeable configuration variables for this bot.","Cog: Utility +Command: config" +"Modify changeable configuration variables for this bot. + +Type `{prefix}config options` to view a list +of valid configuration variables. + +Type `{prefix}config help config-name` for info + on a config. + +To set a configuration variable: +- `{prefix}config set config-name value here` + +To remove a configuration variable: +- `{prefix}config remove config-name`","Modify changeable configuration variables for this bot. + +Type `{prefix}config options` to view a list +of valid configuration variables. + +Type `{prefix}config help config-name` for info + on a config. + +To set a configuration variable: +- `{prefix}config set config-name value here` + +To remove a configuration variable: +- `{prefix}config remove config-name`","Cog: Utility +Command: config" +"Return a list of valid configuration names you can change.","Return a list of valid configuration names you can change.","Cog: Utility +Command: config options" +"Return a list of valid configuration names you can change.","Return a list of valid configuration names you can change.","Cog: Utility +Command: config options" +"Set a configuration variable and its value.","Set a configuration variable and its value.","Cog: Utility +Command: config set" +"Set a configuration variable and its value.","Set a configuration variable and its value.","Cog: Utility +Command: config set" +"Delete a set configuration variable.","Delete a set configuration variable.","Cog: Utility +Command: config remove" +"Delete a set configuration variable.","Delete a set configuration variable.","Cog: Utility +Command: config remove" +"Show the configuration variables that are currently set.","Show the configuration variables that are currently set.","Cog: Utility +Command: config get" +"Show the configuration variables that are currently set. + +Leave `key` empty to show all currently set configuration variables.","Show the configuration variables that are currently set. + +Leave `key` empty to show all currently set configuration variables.","Cog: Utility +Command: config get" +"Show information on a specified configuration.","Show information on a specified configuration.","Cog: Utility +Command: config help" +"Show information on a specified configuration.","Show information on a specified configuration.","Cog: Utility +Command: config help" +"Create shortcuts to bot commands.","Create shortcuts to bot commands.","Cog: Utility +Command: alias" +"Create shortcuts to bot commands. + +When `{prefix}alias` is used by itself, this will retrieve +a list of alias that are currently set. `{prefix}alias-name` will show what the +alias point to. + +To use alias: + +First create an alias using: +- `{prefix}alias add alias-name other-command` + +For example: +- `{prefix}alias add r reply` +- Now you can use `{prefix}r` as an replacement for `{prefix}reply`. + +See also `{prefix}snippet`.","Create shortcuts to bot commands. + +When `{prefix}alias` is used by itself, this will retrieve +a list of alias that are currently set. `{prefix}alias-name` will show what the +alias point to. + +To use alias: + +First create an alias using: +- `{prefix}alias add alias-name other-command` + +For example: +- `{prefix}alias add r reply` +- Now you can use `{prefix}r` as an replacement for `{prefix}reply`. + +See also `{prefix}snippet`.","Cog: Utility +Command: alias" +"View the raw content of an alias.","View the raw content of an alias.","Cog: Utility +Command: alias raw" +"View the raw content of an alias.","View the raw content of an alias.","Cog: Utility +Command: alias raw" +"Add an alias.","Add an alias.","Cog: Utility +Command: alias add" +"Add an alias. + +Alias also supports multi-step aliases, to create a multi-step alias use quotes +to wrap each step and separate each step with `&&`. For example: + +- `{prefix}alias add movenreply ""move admin-category"" && ""reply Thanks for reaching out to the admins""` + +However, if you run into problems, try wrapping the command with quotes. For example: + +- This will fail: `{prefix}alias add reply You'll need to type && to work` +- Correct method: `{prefix}alias add reply ""You'll need to type && to work""`","Add an alias. + +Alias also supports multi-step aliases, to create a multi-step alias use quotes +to wrap each step and separate each step with `&&`. For example: + +- `{prefix}alias add movenreply ""move admin-category"" && ""reply Thanks for reaching out to the admins""` + +However, if you run into problems, try wrapping the command with quotes. For example: + +- This will fail: `{prefix}alias add reply You'll need to type && to work` +- Correct method: `{prefix}alias add reply ""You'll need to type && to work""`","Cog: Utility +Command: alias add" +"Remove an alias.","Remove an alias.","Cog: Utility +Command: alias remove" +"Remove an alias.","Remove an alias.","Cog: Utility +Command: alias remove" +"Edit an alias.","Edit an alias.","Cog: Utility +Command: alias edit" +"Edit an alias.","Edit an alias.","Cog: Utility +Command: alias edit" +"Set the permissions for Modmail commands.","Set the permissions for Modmail commands.","Cog: Utility +Command: permissions" +"Set the permissions for Modmail commands. + +You may set permissions based on individual command names, or permission +levels. + +Acceptable permission levels are: + - **Owner** [5] (absolute control over the bot) + - **Administrator** [4] (administrative powers such as setting activities) + - **Moderator** [3] (ability to block) + - **Supporter** [2] (access to core Modmail supporting functions) + - **Regular** [1] (most basic interactions such as help and about) + +By default, owner is set to the absolute bot owner and regular is `@everyone`. + +To set permissions, see `{prefix}help permissions add`; and to change permission level for specific +commands see `{prefix}help permissions override`. + +Note: You will still have to manually give/take permission to the Modmail +category to users/roles.","Set the permissions for Modmail commands. + +You may set permissions based on individual command names, or permission +levels. + +Acceptable permission levels are: + - **Owner** [5] (absolute control over the bot) + - **Administrator** [4] (administrative powers such as setting activities) + - **Moderator** [3] (ability to block) + - **Supporter** [2] (access to core Modmail supporting functions) + - **Regular** [1] (most basic interactions such as help and about) + +By default, owner is set to the absolute bot owner and regular is `@everyone`. + +To set permissions, see `{prefix}help permissions add`; and to change permission level for specific +commands see `{prefix}help permissions override`. + +Note: You will still have to manually give/take permission to the Modmail +category to users/roles.","Cog: Utility +Command: permissions" +"Change a permission level for a specific command.","Change a permission level for a specific command.","Cog: Utility +Command: permissions override" +"Change a permission level for a specific command. + +Examples: +- `{prefix}perms override reply administrator` +- `{prefix}perms override ""plugin enabled"" moderator` + +To undo a permission override, see `{prefix}help permissions remove`. + +Example: +- `{prefix}perms remove override reply` +- `{prefix}perms remove override plugin enabled` + +You can retrieve a single or all command level override(s), see`{prefix}help permissions get`.","Change a permission level for a specific command. + +Examples: +- `{prefix}perms override reply administrator` +- `{prefix}perms override ""plugin enabled"" moderator` + +To undo a permission override, see `{prefix}help permissions remove`. + +Example: +- `{prefix}perms remove override reply` +- `{prefix}perms remove override plugin enabled` + +You can retrieve a single or all command level override(s), see`{prefix}help permissions get`.","Cog: Utility +Command: permissions override" +"Add a permission to a command or a permission level.","Add a permission to a command or a permission level.","Cog: Utility +Command: permissions add" +"Add a permission to a command or a permission level. + +For sub commands, wrap the complete command name with quotes. +To find a list of permission levels, see `{prefix}help perms`. + +Examples: +- `{prefix}perms add level REGULAR everyone` +- `{prefix}perms add command reply @user` +- `{prefix}perms add command ""plugin enabled"" @role` +- `{prefix}perms add command help 984301093849028` + +Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Add a permission to a command or a permission level. + +For sub commands, wrap the complete command name with quotes. +To find a list of permission levels, see `{prefix}help perms`. + +Examples: +- `{prefix}perms add level REGULAR everyone` +- `{prefix}perms add command reply @user` +- `{prefix}perms add command ""plugin enabled"" @role` +- `{prefix}perms add command help 984301093849028` + +Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Cog: Utility +Command: permissions add" +"Remove permission to use a command, permission level, or command level override.","Remove permission to use a command, permission level, or command level override.","Cog: Utility +Command: permissions remove" +"Remove permission to use a command, permission level, or command level override. + +For sub commands, wrap the complete command name with quotes. +To find a list of permission levels, see `{prefix}help perms`. + +Examples: +- `{prefix}perms remove level REGULAR everyone` +- `{prefix}perms remove command reply @user` +- `{prefix}perms remove command ""plugin enabled"" @role` +- `{prefix}perms remove command help 984301093849028` +- `{prefix}perms remove override block` +- `{prefix}perms remove override ""snippet add""` + +Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Remove permission to use a command, permission level, or command level override. + +For sub commands, wrap the complete command name with quotes. +To find a list of permission levels, see `{prefix}help perms`. + +Examples: +- `{prefix}perms remove level REGULAR everyone` +- `{prefix}perms remove command reply @user` +- `{prefix}perms remove command ""plugin enabled"" @role` +- `{prefix}perms remove command help 984301093849028` +- `{prefix}perms remove override block` +- `{prefix}perms remove override ""snippet add""` + +Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Cog: Utility +Command: permissions remove" +"View the currently-set permissions.","View the currently-set permissions.","Cog: Utility +Command: permissions get" +"View the currently-set permissions. + +To find a list of permission levels, see `{prefix}help perms`. + +To view all command and level permissions: + +Examples: +- `{prefix}perms get @user` +- `{prefix}perms get 984301093849028` + +To view all users and roles of a command or level permission: + +Examples: +- `{prefix}perms get command reply` +- `{prefix}perms get command plugin remove` +- `{prefix}perms get level SUPPORTER` + +To view command level overrides: + +Examples: +- `{prefix}perms get override block` +- `{prefix}perms get override permissions add` + +Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","View the currently-set permissions. + +To find a list of permission levels, see `{prefix}help perms`. + +To view all command and level permissions: + +Examples: +- `{prefix}perms get @user` +- `{prefix}perms get 984301093849028` + +To view all users and roles of a command or level permission: + +Examples: +- `{prefix}perms get command reply` +- `{prefix}perms get command plugin remove` +- `{prefix}perms get level SUPPORTER` + +To view command level overrides: + +Examples: +- `{prefix}perms get override block` +- `{prefix}perms get override permissions add` + +Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Cog: Utility +Command: permissions get" +"Commands relating to logviewer oauth2 login authentication.","Commands relating to logviewer oauth2 login authentication.","Cog: Utility +Command: oauth" +"Commands relating to logviewer oauth2 login authentication. + +This functionality on your logviewer site is a [**Patron**](https://patreon.com/kyber) only feature.","Commands relating to logviewer oauth2 login authentication. + +This functionality on your logviewer site is a [**Patron**](https://patreon.com/kyber) only feature.","Cog: Utility +Command: oauth" +"Whitelist or un-whitelist a user or role to have access to logs.","Whitelist or un-whitelist a user or role to have access to logs.","Cog: Utility +Command: oauth whitelist" +"Whitelist or un-whitelist a user or role to have access to logs. + +`target` may be a role ID, name, mention, user ID, name, or mention.","Whitelist or un-whitelist a user or role to have access to logs. + +`target` may be a role ID, name, mention, user ID, name, or mention.","Cog: Utility +Command: oauth whitelist" +"Shows a list of users and roles that are whitelisted to view logs.","Shows a list of users and roles that are whitelisted to view logs.","Cog: Utility +Command: oauth show" +"Shows a list of users and roles that are whitelisted to view logs.","Shows a list of users and roles that are whitelisted to view logs.","Cog: Utility +Command: oauth show" +"Evaluates Python code.","Evaluates Python code.","Cog: Utility +Command: eval" +"Evaluates Python code.","Evaluates Python code.","Cog: Utility +Command: eval" +"Shows this help message.","Shows this help message.","Cog: Utility +Command: help" +"Shows this help message.","Shows this help message.","Cog: Utility +Command: help" diff --git a/plugins/registry.json b/plugins/registry.json index b15bb374dc..1c268d89be 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -170,7 +170,7 @@ "thumbnail_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png" }, "stats": { - "repository": "KarateWumpus/modmail-plugins", + "repository": "MiTonder/modmail-plugins", "branch": "master", "description": "Get useful stats directly in an embed about either the Modmail bot, a user or the server.", "bot_version": "2.24.1", @@ -190,37 +190,10 @@ "serverstats": { "repository": "dazvise/modmail-plugins", "branch": "master", - "description": "Voice channels containing interesting and accurate statistics about your server such as Member Count.", + "description": "Interesting and accurate statistics about your server.", "bot_version": "2.20.1", "title": "Server Stats", "icon_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png", "thumbnail_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png" - }, - "suggest": { - "repository": "realcyguy/modmail-plugins", - "branch": "master", - "description": "Send suggestions to a selected server! It even has moderation...", - "bot_version": "3.4.1", - "title": "Suggest stuff.", - "icon_url": "https://i.imgur.com/qtE7AH8.png", - "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" - }, - "githubstats": { - "repository": "mischievousdev/modmail-plugins", - "branch": "master", - "description": "Github statistics in discord", - "bot_version": "2.20.1", - "title": "Github Stats", - "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", - "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" - }, - "slowmode": { - "repository": "teen1/modmail-plugins", - "branch": "master", - "description": "Configure slow mode for your channels with Modmail!", - "bot_version": "2.20.1", - "title": "Slow Mode", - "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", - "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" } } diff --git a/poetry.lock b/poetry.lock index f4b23956b8..1841d893a1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,9 +13,6 @@ chardet = ">=2.0,<4.0" multidict = ">=4.0,<5.0" yarl = ">=1.0,<2.0" -[package.extras] -speedups = ["aiodns", "brotlipy", "cchardet"] - [[package]] category = "dev" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." @@ -57,12 +54,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "19.3.0" -[package.extras] -azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] -dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] -docs = ["sphinx", "zope.interface"] -tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] - [[package]] category = "dev" description = "Security oriented static analyser for python code." @@ -92,9 +83,6 @@ attrs = ">=18.1.0" click = ">=6.5" toml = ">=0.9.4" -[package.extras] -d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] - [[package]] category = "main" description = "Universal encoding detector for Python 2 and 3" @@ -108,8 +96,8 @@ category = "dev" description = "Composable command line interface toolkit" name = "click" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "7.1.1" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "7.0" [[package]] category = "main" @@ -131,10 +119,6 @@ version = "1.2.5" aiohttp = ">=3.3.0,<3.6.0" websockets = ">=6.0,<7.0" -[package.extras] -docs = ["sphinx (1.7.4)", "sphinxcontrib-asyncio", "sphinxcontrib-websupport"] -voice = ["PyNaCl (1.3.0)"] - [[package]] category = "main" description = "DNS toolkit" @@ -143,10 +127,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "1.16.0" -[package.extras] -DNSSEC = ["pycryptodome", "ecdsa (>=0.13)"] -IDNA = ["idna (>=2.1)"] - [[package]] category = "main" description = "Emoji for Python" @@ -155,9 +135,6 @@ optional = false python-versions = "*" version = "0.5.4" -[package.extras] -dev = ["nose", "coverage", "coveralls"] - [[package]] category = "main" description = "Backport of the concurrent.futures package from Python 3.2" @@ -169,24 +146,24 @@ version = "3.1.1" [[package]] category = "dev" description = "Git Object Database" -name = "gitdb" +name = "gitdb2" optional = false -python-versions = ">=3.4" -version = "4.0.4" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.0.6" [package.dependencies] -smmap = ">=3.0.1,<4" +smmap2 = ">=2.0.0" [[package]] category = "dev" description = "Python Git Library" name = "gitpython" optional = false -python-versions = ">=3.4" -version = "3.1.1" +python-versions = ">=3.0, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.0.5" [package.dependencies] -gitdb = ">=4.0.1,<5" +gitdb2 = ">=2.0.0" [[package]] category = "main" @@ -194,7 +171,7 @@ description = "Internationalized Domain Names in Applications (IDNA)" name = "idna" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.9" +version = "2.8" [[package]] category = "main" @@ -215,12 +192,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "4.3.21" -[package.extras] -pipfile = ["pipreqs", "requirementslib"] -pyproject = ["toml"] -requirements = ["pipreqs", "pip-api"] -xdg_home = ["appdirs (>=1.4.0)"] - [[package]] category = "dev" description = "A fast and thorough lazy object proxy." @@ -255,7 +226,7 @@ description = "multidict implementation" name = "multidict" optional = false python-versions = ">=3.5" -version = "4.7.5" +version = "4.7.1" [[package]] category = "main" @@ -282,7 +253,7 @@ description = "Python Build Reasonableness" name = "pbr" optional = false python-versions = "*" -version = "5.4.5" +version = "5.4.4" [[package]] category = "dev" @@ -304,15 +275,7 @@ description = "Python driver for MongoDB " name = "pymongo" optional = true python-versions = "*" -version = "3.10.1" - -[package.extras] -encryption = ["pymongocrypt (<2.0.0)"] -gssapi = ["pykerberos"] -snappy = ["python-snappy"] -srv = ["dnspython (>=1.16.0,<1.17.0)"] -tls = ["ipaddress"] -zstd = ["zstandard"] +version = "3.10.0" [[package]] category = "main" @@ -331,34 +294,31 @@ description = "Add .env support to your django/flask apps in development and dep name = "python-dotenv" optional = false python-versions = "*" -version = "0.10.5" - -[package.extras] -cli = ["click (>=5.0)"] +version = "0.10.3" [[package]] category = "dev" description = "YAML parser and emitter for Python" name = "pyyaml" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "5.3.1" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "5.2" [[package]] category = "main" description = "Python 2 and 3 compatibility utilities" name = "six" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.14.0" +python-versions = ">=2.6, !=3.0.*, !=3.1.*" +version = "1.13.0" [[package]] category = "dev" description = "A pure Python implementation of a sliding window memory map manager" -name = "smmap" +name = "smmap2" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.0.2" +version = "2.0.5" [[package]] category = "dev" @@ -366,7 +326,7 @@ description = "Manage dynamic plugins for Python applications" name = "stevedore" optional = false python-versions = "*" -version = "1.32.0" +version = "1.31.0" [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" @@ -387,7 +347,7 @@ marker = "implementation_name == \"cpython\" and python_version < \"3.8\"" name = "typed-ast" optional = false python-versions = "*" -version = "1.4.1" +version = "1.4.0" [[package]] category = "main" @@ -425,347 +385,48 @@ version = "1.4.2" idna = ">=2.0" multidict = ">=4.0" -[extras] -mongodb = ["motor"] - [metadata] -content-hash = "793f86eb19d73f473f00883384ec965876c3930f41f94a171d2d1bc38f66903b" +content-hash = "fbe9e329f33e482854cff5bf05b006de9830c2d46bf3874e2ee4f8a8da0b1797" python-versions = "^3.7" -[metadata.files] -aiohttp = [ - {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_10_x86_64.whl", hash = "sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5"}, - {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed"}, - {file = "aiohttp-3.5.4-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303"}, - {file = "aiohttp-3.5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10"}, - {file = "aiohttp-3.5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa"}, - {file = "aiohttp-3.5.4-cp35-cp35m-win32.whl", hash = "sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4"}, - {file = "aiohttp-3.5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72"}, - {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5"}, - {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12"}, - {file = "aiohttp-3.5.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6"}, - {file = "aiohttp-3.5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6"}, - {file = "aiohttp-3.5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d"}, - {file = "aiohttp-3.5.4-cp36-cp36m-win32.whl", hash = "sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1"}, - {file = "aiohttp-3.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d"}, - {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300"}, - {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390"}, - {file = "aiohttp-3.5.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366"}, - {file = "aiohttp-3.5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889"}, - {file = "aiohttp-3.5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55"}, - {file = "aiohttp-3.5.4-cp37-cp37m-win32.whl", hash = "sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc"}, - {file = "aiohttp-3.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939"}, - {file = "aiohttp-3.5.4.tar.gz", hash = "sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf"}, -] -appdirs = [ - {file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"}, - {file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"}, -] -astroid = [ - {file = "astroid-2.3.3-py3-none-any.whl", hash = "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"}, - {file = "astroid-2.3.3.tar.gz", hash = "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a"}, -] -async-timeout = [ - {file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"}, - {file = "async_timeout-3.0.1-py3-none-any.whl", hash = "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"}, -] -attrs = [ - {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, - {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, -] -bandit = [ - {file = "bandit-1.6.2-py2.py3-none-any.whl", hash = "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952"}, - {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"}, -] -black = [ - {file = "black-19.3b0-py36-none-any.whl", hash = "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf"}, - {file = "black-19.3b0.tar.gz", hash = "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"}, -] -chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, -] -click = [ - {file = "click-7.1.1-py2.py3-none-any.whl", hash = "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"}, - {file = "click-7.1.1.tar.gz", hash = "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc"}, -] -colorama = [ - {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, - {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, -] -"discord.py" = [ - {file = "discord.py-1.2.5-py3-none-any.whl", hash = "sha256:7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d"}, -] -dnspython = [ - {file = "dnspython-1.16.0-py2.py3-none-any.whl", hash = "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"}, - {file = "dnspython-1.16.0.zip", hash = "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01"}, -] -emoji = [ - {file = "emoji-0.5.4.tar.gz", hash = "sha256:60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"}, -] -futures = [ - {file = "futures-3.1.1-py2-none-any.whl", hash = "sha256:c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"}, - {file = "futures-3.1.1-py3-none-any.whl", hash = "sha256:3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b"}, - {file = "futures-3.1.1.tar.gz", hash = "sha256:51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd"}, -] -gitdb = [ - {file = "gitdb-4.0.4-py3-none-any.whl", hash = "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a"}, - {file = "gitdb-4.0.4.tar.gz", hash = "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5"}, -] -gitpython = [ - {file = "GitPython-3.1.1-py3-none-any.whl", hash = "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d"}, - {file = "GitPython-3.1.1.tar.gz", hash = "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74"}, -] -idna = [ - {file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"}, - {file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"}, -] -isodate = [ - {file = "isodate-0.6.0-py2.py3-none-any.whl", hash = "sha256:aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"}, - {file = "isodate-0.6.0.tar.gz", hash = "sha256:2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8"}, -] -isort = [ - {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"}, - {file = "isort-4.3.21.tar.gz", hash = "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1"}, -] -lazy-object-proxy = [ - {file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27m-macosx_10_13_x86_64.whl", hash = "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win32.whl", hash = "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a"}, - {file = "lazy_object_proxy-1.4.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d"}, - {file = "lazy_object_proxy-1.4.3-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a"}, - {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win32.whl", hash = "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e"}, - {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win_amd64.whl", hash = "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357"}, - {file = "lazy_object_proxy-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50"}, - {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db"}, - {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449"}, - {file = "lazy_object_proxy-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156"}, - {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531"}, - {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142"}, - {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea"}, - {file = "lazy_object_proxy-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62"}, - {file = "lazy_object_proxy-1.4.3-cp38-cp38-win32.whl", hash = "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd"}, - {file = "lazy_object_proxy-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239"}, -] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] -motor = [ - {file = "motor-2.1.0-py2-none-any.whl", hash = "sha256:599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909"}, - {file = "motor-2.1.0-py3-none-any.whl", hash = "sha256:97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"}, - {file = "motor-2.1.0.tar.gz", hash = "sha256:756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4"}, -] -multidict = [ - {file = "multidict-4.7.5-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:fc3b4adc2ee8474cb3cd2a155305d5f8eda0a9c91320f83e55748e1fcb68f8e3"}, - {file = "multidict-4.7.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:42f56542166040b4474c0c608ed051732033cd821126493cf25b6c276df7dd35"}, - {file = "multidict-4.7.5-cp35-cp35m-win32.whl", hash = "sha256:7774e9f6c9af3f12f296131453f7b81dabb7ebdb948483362f5afcaac8a826f1"}, - {file = "multidict-4.7.5-cp35-cp35m-win_amd64.whl", hash = "sha256:c2c37185fb0af79d5c117b8d2764f4321eeb12ba8c141a95d0aa8c2c1d0a11dd"}, - {file = "multidict-4.7.5-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:e439c9a10a95cb32abd708bb8be83b2134fa93790a4fb0535ca36db3dda94d20"}, - {file = "multidict-4.7.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:85cb26c38c96f76b7ff38b86c9d560dea10cf3459bb5f4caf72fc1bb932c7136"}, - {file = "multidict-4.7.5-cp36-cp36m-win32.whl", hash = "sha256:620b37c3fea181dab09267cd5a84b0f23fa043beb8bc50d8474dd9694de1fa6e"}, - {file = "multidict-4.7.5-cp36-cp36m-win_amd64.whl", hash = "sha256:6e6fef114741c4d7ca46da8449038ec8b1e880bbe68674c01ceeb1ac8a648e78"}, - {file = "multidict-4.7.5-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a326f4240123a2ac66bb163eeba99578e9d63a8654a59f4688a79198f9aa10f8"}, - {file = "multidict-4.7.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dc561313279f9d05a3d0ffa89cd15ae477528ea37aa9795c4654588a3287a9ab"}, - {file = "multidict-4.7.5-cp37-cp37m-win32.whl", hash = "sha256:4b7df040fb5fe826d689204f9b544af469593fb3ff3a069a6ad3409f742f5928"}, - {file = "multidict-4.7.5-cp37-cp37m-win_amd64.whl", hash = "sha256:317f96bc0950d249e96d8d29ab556d01dd38888fbe68324f46fd834b430169f1"}, - {file = "multidict-4.7.5-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:b51249fdd2923739cd3efc95a3d6c363b67bbf779208e9f37fd5e68540d1a4d4"}, - {file = "multidict-4.7.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ae402f43604e3b2bc41e8ea8b8526c7fa7139ed76b0d64fc48e28125925275b2"}, - {file = "multidict-4.7.5-cp38-cp38-win32.whl", hash = "sha256:bb519becc46275c594410c6c28a8a0adc66fe24fef154a9addea54c1adb006f5"}, - {file = "multidict-4.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:544fae9261232a97102e27a926019100a9db75bec7b37feedd74b3aa82f29969"}, - {file = "multidict-4.7.5.tar.gz", hash = "sha256:aee283c49601fa4c13adc64c09c978838a7e812f85377ae130a24d7198c0331e"}, -] -natural = [ - {file = "natural-0.2.0.tar.gz", hash = "sha256:18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"}, -] -parsedatetime = [ - {file = "parsedatetime-2.5-py2-none-any.whl", hash = "sha256:3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1"}, - {file = "parsedatetime-2.5.tar.gz", hash = "sha256:d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667"}, -] -pbr = [ - {file = "pbr-5.4.5-py2.py3-none-any.whl", hash = "sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"}, - {file = "pbr-5.4.5.tar.gz", hash = "sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c"}, -] -pylint = [ - {file = "pylint-2.4.4-py3-none-any.whl", hash = "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"}, - {file = "pylint-2.4.4.tar.gz", hash = "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd"}, -] -pymongo = [ - {file = "pymongo-3.10.1-cp27-cp27m-macosx_10_14_intel.whl", hash = "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee"}, - {file = "pymongo-3.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed"}, - {file = "pymongo-3.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6"}, - {file = "pymongo-3.10.1-cp27-cp27m-win32.whl", hash = "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5"}, - {file = "pymongo-3.10.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe"}, - {file = "pymongo-3.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc"}, - {file = "pymongo-3.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764"}, - {file = "pymongo-3.10.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372"}, - {file = "pymongo-3.10.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32"}, - {file = "pymongo-3.10.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc"}, - {file = "pymongo-3.10.1-cp34-cp34m-win32.whl", hash = "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a"}, - {file = "pymongo-3.10.1-cp34-cp34m-win_amd64.whl", hash = "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae"}, - {file = "pymongo-3.10.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_ppc64le.whl", hash = "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_s390x.whl", hash = "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf"}, - {file = "pymongo-3.10.1-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d"}, - {file = "pymongo-3.10.1-cp35-cp35m-win32.whl", hash = "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57"}, - {file = "pymongo-3.10.1-cp35-cp35m-win_amd64.whl", hash = "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70"}, - {file = "pymongo-3.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464"}, - {file = "pymongo-3.10.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73"}, - {file = "pymongo-3.10.1-cp36-cp36m-win32.whl", hash = "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33"}, - {file = "pymongo-3.10.1-cp36-cp36m-win_amd64.whl", hash = "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6"}, - {file = "pymongo-3.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11"}, - {file = "pymongo-3.10.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951"}, - {file = "pymongo-3.10.1-cp37-cp37m-win32.whl", hash = "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39"}, - {file = "pymongo-3.10.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b"}, - {file = "pymongo-3.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82"}, - {file = "pymongo-3.10.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be"}, - {file = "pymongo-3.10.1-cp38-cp38-win32.whl", hash = "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f"}, - {file = "pymongo-3.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac"}, - {file = "pymongo-3.10.1-py2.7-macosx-10.14-intel.egg", hash = "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a"}, - {file = "pymongo-3.10.1-py2.7-win-amd64.egg", hash = "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012"}, - {file = "pymongo-3.10.1-py2.7-win32.egg", hash = "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a"}, - {file = "pymongo-3.10.1.tar.gz", hash = "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa"}, -] -python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, -] -python-dotenv = [ - {file = "python-dotenv-0.10.5.tar.gz", hash = "sha256:f254bfd0c970d64ccbb6c9ebef3667ab301a71473569c991253a481f1c98dddc"}, - {file = "python_dotenv-0.10.5-py2.py3-none-any.whl", hash = "sha256:440c7c23d53b7d352f9c94d6f70860242c2f071cf5c029dd661ccb22d64ae42b"}, -] -pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, -] -six = [ - {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, - {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, -] -smmap = [ - {file = "smmap-3.0.2-py2.py3-none-any.whl", hash = "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1"}, - {file = "smmap-3.0.2.tar.gz", hash = "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911"}, -] -stevedore = [ - {file = "stevedore-1.32.0-py2.py3-none-any.whl", hash = "sha256:a4e7dc759fb0f2e3e2f7d8ffe2358c19d45b9b8297f393ef1256858d82f69c9b"}, - {file = "stevedore-1.32.0.tar.gz", hash = "sha256:18afaf1d623af5950cc0f7e75e70f917784c73b652a34a12d90b309451b5500b"}, -] -toml = [ - {file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"}, - {file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"}, - {file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"}, -] -typed-ast = [ - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, - {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, - {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, - {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, - {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, - {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, - {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, -] -uvloop = [ - {file = "uvloop-0.14.0-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd"}, - {file = "uvloop-0.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726"}, - {file = "uvloop-0.14.0-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7"}, - {file = "uvloop-0.14.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"}, - {file = "uvloop-0.14.0-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891"}, - {file = "uvloop-0.14.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95"}, - {file = "uvloop-0.14.0-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5"}, - {file = "uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09"}, - {file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"}, -] -websockets = [ - {file = "websockets-6.0-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d"}, - {file = "websockets-6.0-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484"}, - {file = "websockets-6.0-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e"}, - {file = "websockets-6.0-cp34-cp34m-win32.whl", hash = "sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"}, - {file = "websockets-6.0-cp34-cp34m-win_amd64.whl", hash = "sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96"}, - {file = "websockets-6.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538"}, - {file = "websockets-6.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0"}, - {file = "websockets-6.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1"}, - {file = "websockets-6.0-cp35-cp35m-win32.whl", hash = "sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d"}, - {file = "websockets-6.0-cp35-cp35m-win_amd64.whl", hash = "sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6"}, - {file = "websockets-6.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf"}, - {file = "websockets-6.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d"}, - {file = "websockets-6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb"}, - {file = "websockets-6.0-cp36-cp36m-win32.whl", hash = "sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c"}, - {file = "websockets-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff"}, - {file = "websockets-6.0-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908"}, - {file = "websockets-6.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559"}, - {file = "websockets-6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4"}, - {file = "websockets-6.0-cp37-cp37m-win32.whl", hash = "sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136"}, - {file = "websockets-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584"}, - {file = "websockets-6.0.tar.gz", hash = "sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c"}, -] -wrapt = [ - {file = "wrapt-1.11.2.tar.gz", hash = "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"}, -] -yarl = [ - {file = "yarl-1.4.2-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b"}, - {file = "yarl-1.4.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1"}, - {file = "yarl-1.4.2-cp35-cp35m-win32.whl", hash = "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080"}, - {file = "yarl-1.4.2-cp35-cp35m-win_amd64.whl", hash = "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a"}, - {file = "yarl-1.4.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f"}, - {file = "yarl-1.4.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea"}, - {file = "yarl-1.4.2-cp36-cp36m-win32.whl", hash = "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb"}, - {file = "yarl-1.4.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70"}, - {file = "yarl-1.4.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d"}, - {file = "yarl-1.4.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce"}, - {file = "yarl-1.4.2-cp37-cp37m-win32.whl", hash = "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"}, - {file = "yarl-1.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce"}, - {file = "yarl-1.4.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b"}, - {file = "yarl-1.4.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae"}, - {file = "yarl-1.4.2-cp38-cp38-win32.whl", hash = "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462"}, - {file = "yarl-1.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6"}, - {file = "yarl-1.4.2.tar.gz", hash = "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b"}, -] +[metadata.hashes] +aiohttp = ["00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55", "0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed", "09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10", "199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5", "296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1", "368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939", "40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390", "629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa", "6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc", "87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5", "9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d", "9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf", "9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6", "a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72", "a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12", "a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366", "acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4", "b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300", "c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d", "cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303", "d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6", "e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889"] +appdirs = ["9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", "d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"] +astroid = ["71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", "840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"] +async-timeout = ["0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"] +attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] +bandit = ["336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952", "41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"] +black = ["09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", "68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"] +chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] +click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] +colorama = ["7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", "e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"] +"discord.py" = ["7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d"] +dnspython = ["36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", "f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"] +emoji = ["60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"] +futures = ["3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b", "51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd", "c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"] +gitdb2 = ["1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350", "96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b"] +gitpython = ["9c2398ffc3dcb3c40b27324b316f08a4f93ad646d5a6328cafbb871aa79f5e42", "c155c6a2653593ccb300462f6ef533583a913e17857cfef8fc617c246b6dc245"] +idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] +isodate = ["2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", "aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"] +isort = ["54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", "6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"] +lazy-object-proxy = ["0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", "194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", "1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", "4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", "48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", "5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", "59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", "8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", "9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", "9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", "97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", "9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", "a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", "a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", "ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", "cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", "d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", "d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", "eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", "efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"] +mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] +motor = ["599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", "756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", "97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"] +multidict = ["09c19f642e055550c9319d5123221b7e07fc79bda58122aa93910e52f2ab2f29", "0c1a5d5f7aa7189f7b83c4411c2af8f1d38d69c4360d5de3eea129c65d8d7ce2", "12f22980e7ed0972a969520fb1e55682c9fca89a68b21b49ec43132e680be812", "258660e9d6b52de1a75097944e12718d3aa59adc611b703361e3577d69167aaf", "3374a23e707848f27b3438500db0c69eca82929337656fce556bd70031fbda74", "503b7fce0054c73aa631cc910a470052df33d599f3401f3b77e54d31182525d5", "6ce55f2c45ffc90239aab625bb1b4864eef33f73ea88487ef968291fbf09fb3f", "725496dde5730f4ad0a627e1a58e2620c1bde0ad1c8080aae15d583eb23344ce", "a3721078beff247d0cd4fb19d915c2c25f90907cf8d6cd49d0413a24915577c6", "ba566518550f81daca649eded8b5c7dd09210a854637c82351410aa15c49324a", "c42362750a51a15dc905cb891658f822ee5021bfbea898c03aa1ed833e2248a5", "cf14aaf2ab067ca10bca0b14d5cbd751dd249e65d371734bc0e47ddd8fafc175", "cf24e15986762f0e75a622eb19cfe39a042e952b8afba3e7408835b9af2be4fb", "d7b6da08538302c5245cd3103f333655ba7f274915f1f5121c4f4b5fbdb3febe", "e27e13b9ff0a914a6b8fb7e4947d4ac6be8e4f61ede17edffabd088817df9e26", "e53b205f8afd76fc6c942ef39e8ee7c519c775d336291d32874082a87802c67c", "ec804fc5f68695d91c24d716020278fcffd50890492690a7e1fef2e741f7172c"] +natural = ["18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"] +parsedatetime = ["3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1", "d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667"] +pbr = ["139d2625547dbfa5fb0b81daebb39601c478c21956dc57e2e07b74450a8c506b", "61aa52a0f18b71c5cc58232d2cf8f8d09cd67fcad60b742a60124cb8d6951488"] +pylint = ["3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", "886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"] +pymongo = ["0369136c6e79c5edc16aa5de2b48a1b1c1fe5e6f7fc5915a2deaa98bd6e9dad5", "08364e1bea1507c516b18b826ec790cb90433aec2f235033ec5eecfd1011633b", "0af1d2bc8cc9503bf92ec3669a77ec3a6d7938193b583fb867b7e9696eed52e8", "0cfd1aeeb8c0a634646ab3ebeb4ce6828b94b2e33553a69ff7e6c07c250bf201", "15bbd2b5397f7d22498e2f2769fd698a8a247b9cc1a630ee8dabf647fb333480", "1b4a13dff15641e58620524db15d7a323d60572b2b187261c5cb58c36d74778d", "22fbdb908257f9aaaa372a7684f3e094a05ca52eb84f8f381c8b1827c49556fd", "264272fd1c95fc48002ad85d5e41270831777b4180f2500943e45e12b2a3ab43", "3372e98eebbfd05ebf020388003f8a4438bed41e0fef1ef696d2c13633c416c8", "339d24ecdc42745d2dc09b26fda8151988e806ca81134a7bd10513c4031d91e1", "38281855fc3961ba5510fbb503b8d16cc1fcb326e9f7ba0dd096ed4eb72a7084", "4acdd2e16392472bfd49ca49038845c95e5254b5af862b55f7f2cc79aa258886", "4e0c006bc6e98e861b678432e05bf64ba3eb889b6ab7e7bf1ebaecf9f1ba0e58", "4e4284bcbe4b7be1b37f9641509085b715c478e7fbf8f820358362b5dd359379", "4e5e94a5f9823f0bd0c56012a57650bc6772636c29d83d253260c26b908fcfd9", "4e61f30800a40f1770b2ec56bbf5dc0f0e3f7e9250eb05fa4feb9ccb7bbe39ca", "53577cf57ba9d93b58ab41d45250277828ff83c5286dde14f855e4b17ec19976", "681cb31e8631882804a6cc3c8cc8f54a74ff3a82261a78e50f20c5eec05ac855", "6dfc2710f43dd1d66991a0f160d196356732ccc8aa9dbc6875aeba78388fa142", "72218201b13d8169be5736417987e9a0a3b10d4349e40e4db7a6a5ac670c7ef2", "7247fbcdbf7ab574eb70743461b3cfc14d9cfae3f27a9afb6ce14d87f67dd0b5", "72651f4b4adf50201891580506c8cca465d94d38f26ed92abfc56440662c723c", "87b3aaf12ad6a9b5570b12d2a4b8802757cb3588a903aafd3c25f07f9caf07e3", "87c28b7b37617c5a01eb396487f7d3b61a453e1fa0475a175ab87712d6f5d52f", "88efe627b628f36ef53f09abb218d4630f83d8ebde7028689439559475c43dae", "89bfbca22266f12df7fb80092b7c876734751d02b93789580b68957ad4a8bf56", "908a3caf348a672b28b8a06fe7b4a27c2fdcf7f873df671e4027d48bcd7f971f", "9128e7bea85f3a3041306fa14a7aa82a24b47881918500e1b8396dd1c933b5a6", "9737d6d688a15b8d5c0bfa909638b79261e195be817b9f1be79c722bbb23cd76", "98a8305da158f46e99e7e51db49a2f8b5fcdd7683ea7083988ccb9c4450507a6", "99285cd44c756f0900cbdb5fe75f567c0a76a273b7e0467f23cb76f47e60aac0", "9ed568f8026ffeb00ce31e5351e0d09d704cc19a29549ba4da0ac145d2a26fdf", "a006162035032021dfd00a879643dc06863dac275f9210d843278566c719eebc", "a03cb336bc8d25a11ff33b94967478a9775b0d2b23b39e952d9cc6cb93b75d69", "a863ceb67be163060d1099b7e89b6dd83d6dd50077c7ceae31ac844c4c2baff9", "b82628eaf0a16c1f50e1c205fd1dd406d7874037dd84643da89e91b5043b5e82", "bc6446a41fb7eeaf2c808bab961b9bac81db0f5de69eab74eebe1b8b072399f7", "c42d290ed54096355838421cf9d2a56e150cb533304d2439ef1adf612a986eaf", "c43879fe427ea6aa6e84dae9fbdc5aa14428a4cfe613fe0fee2cc004bf3f307c", "c566cbdd1863ba3ccf838656a1403c3c81fdb57cbe3fdd3515be7c9616763d33", "c5b7a0d7e6ca986de32b269b6dbbd5162c1a776ece72936f55decb4d1b197ee9", "ca109fe9f74da4930590bb589eb8fdf80e5d19f5cd9f337815cac9309bbd0a76", "d0260ba68f9bafd8775b2988b5aeace6e69a37593ec256e23e150c808160c05c", "d12d86e771fc3072a0e6bdbf4e417c63fec85ee47cb052ba7ad239403bf5e154", "d2ce33501149b373118fcfec88a292a87ef0b333fb30c7c6aac72fe64700bdf6", "d582ea8496e2a0e124e927a67dca55c8833f0dbfbc2c84aaf0e5949a2dd30c51", "d68b9ab0a900582a345fb279675b0ad4fac07d6a8c2678f12910d55083b7240d", "dbf1fa571db6006907aeaf6473580aaa76041f4f3cd1ff8a0039fd0f40b83f6d", "e032437a7d2b89dab880c79379d88059cee8019da0ff475d924c4ccab52db88f", "e0f5798f3ad60695465a093e3d002f609c41fef3dcb97fcefae355d24d3274cf", "e756355704a2cf91a7f4a649aa0bbf3bbd263018b9ed08f60198c262f4ee24b6", "e824b4b87bd88cbeb25c8babeadbbaaaf06f02bbb95a93462b7c6193a064974e", "ea1171470b52487152ed8bf27713cc2480dc8b0cd58e282a1bff742541efbfb8", "fa19aef44d5ed8f798a8136ff981aedfa508edac3b1bed481eca5dde5f14fd3d", "faf83d20c041637cb277e5fdb59abc217c40ab3202dd87cc95d6fbd9ce5ffd9b", "fceb6ae5a149a42766efb8344b0df6cfb21b55c55f360170abaddb11d43af0f1"] +python-dateutil = ["73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"] +python-dotenv = ["debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", "f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544"] +pyyaml = ["0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc", "2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803", "35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc", "38a4f0d114101c58c0f3a88aeaa44d63efd588845c5a2df5290b73db8f246d15", "483eb6a33b671408c8529106df3707270bfacb2447bf8ad856a4b4f57f6e3075", "4b6be5edb9f6bb73680f5bf4ee08ff25416d1400fbd4535fe0069b2994da07cd", "7f38e35c00e160db592091751d385cd7b3046d6d51f578b29943225178257b31", "8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f", "c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c", "e4c015484ff0ff197564917b4b4246ca03f411b9bd7f16e02a2f586eb48b6d04", "ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4"] +six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] +smmap2 = ["0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde", "29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a"] +stevedore = ["01d9f4beecf0fbd070ddb18e5efb10567801ba7ef3ddab0074f54e3cd4e91730", "e0739f9739a681c7a1fda76a102b65295e96a144ccdb552f2ae03c5f0abe8a14"] +toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"] +typed-ast = ["1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", "48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", "7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", "838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", "fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"] +uvloop = ["08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", "123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", "4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", "4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", "afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", "b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", "bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", "e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"] +websockets = ["0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136", "2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6", "5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1", "5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538", "669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4", "695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908", "6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0", "79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d", "7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c", "82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d", "8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c", "91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb", "952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf", "99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e", "9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96", "a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584", "cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484", "e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d", "e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559", "ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff", "f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"] +wrapt = ["565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"] +yarl = ["0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", "0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", "2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", "25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", "26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", "308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", "3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", "58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", "5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", "6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", "944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", "a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", "a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", "c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", "c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", "d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", "e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"] diff --git a/pyproject.toml b/pyproject.toml index a114573201..9c7122c417 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 99 -target-version = ['py37'] +target-version = ['py36'] include = '\.pyi?$' exclude = ''' ( @@ -21,8 +21,8 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.4.1' -description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." +version = '3.5.0-dev0' +description = 'Modmail is similar to Reddits Modmail both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way.' license = 'AGPL-3.0-only' authors = [ 'kyb3r ', @@ -54,5 +54,3 @@ black = {version = "=19.3b0", allows-prereleases = true} pylint = "^2.4" bandit = "^1.6" -[tool.poetry.extras] -mongodb = ["motor"] diff --git a/runtime.txt b/runtime.txt index 6919bf9ede..aefcfbece7 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.6 +python-3.7.5 diff --git a/translation_files.py b/translation_files.py new file mode 100644 index 0000000000..7d50c53417 --- /dev/null +++ b/translation_files.py @@ -0,0 +1,117 @@ +import csv +import glob +import re +import string + +from discord.ext import commands + +from core import translations +from cogs.modmail import Modmail +from cogs.plugins import Plugins +from cogs.utility import Utility + + +data = [('Identifier', 'English', 'Context')] +all_identifiers = [] +identifiers = {} + + +class FormatError(Exception): + def __init__(self, reason, string): + super().__init__(f'Unable to parse {reason}: {string}') + + +for filename in glob.glob('**/*.py') + glob.glob('*.py'): + if filename == 'translation_files.py': + continue + with open(filename, encoding='utf8') as f: + filedata = f.read() + regex_matches = re.findall(r'(?:^|[^A-z])_\(.+?(?:\'|\")\)+?', filedata, flags=re.DOTALL | re.MULTILINE) + + for i in regex_matches: + if "f'" in i or 'f"' in i: + print(FormatError('f-string', i)) + identifier = '' + read = False + ignore_inverted = False + newline = False + counter = 0 + mode = None + for n in range(len(i)): + triggered = False + x = i[n] + + if x in ("'", '"') and not ignore_inverted: + if not mode: + mode = x + if mode == x: + read = not read + triggered = True + + if x == '\n': + newline = True + + if read and not triggered: + newline = False + identifier += x + + if newline and x not in string.whitespace: + counter += 1 + if counter > 1: + break + else: + counter = 0 + + if x == '\\': + ignore_inverted = True + elif ignore_inverted: + ignore_inverted = False + + all_identifiers.append(identifier) + + filedata_lines = filedata.splitlines() + fullline = list(filter((lambda x: x.find(i.splitlines()[0]) != -1), filedata_lines))[0] + count = 0 + for nline, line in enumerate(filedata_lines): + if line == fullline: + count += 1 + if count == all_identifiers.count(identifier): + linenum = nline + 1 + break + + if identifier in identifiers.keys(): + if filename not in data[identifiers[identifier]][2]: + data[identifiers[identifier]][2] += f' {filename}/L{linenum}' + elif str(linenum) not in data[identifiers[identifier]][2]: + split_space = data[identifiers[identifier]][2].split(' ') + for nx, x in enumerate(split_space): + if filename in x: + split_space[nx] += f'/L{linenum}' + break + data[identifiers[identifier]][2] = (' ').join(split_space) + else: + data.append([identifier, identifier, f'File: {filename}/L{linenum}']) + identifiers[identifier] = len(data) - 1 + + print(filename) + +translations.init() +done = set() +bot = commands.Bot(command_prefix=None) +cogs = [Modmail(bot), Plugins(bot), Utility(bot)] +for i in cogs: + if i.description: + data.append([i.description, i.description, f'Cog: {i.__cog_name__}']) + + for cmd in i.walk_commands(): + if cmd not in done: + if cmd.short_doc: + print(cmd) + data.append([cmd.short_doc, cmd.short_doc, f'Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}']) + data.append([cmd.help, cmd.help, f'Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}']) + + done.add(cmd) + + +with open('languages/en.csv', 'w+') as f: + csv.writer(f, dialect='unix').writerows(data) From d74f8c82945c04f80336ec4752ed5e8628756c1b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 3 Jul 2020 18:24:15 +0800 Subject: [PATCH 050/705] black? --- bot.py | 4 +- cogs/modmail.py | 151 ++++++++++++++++++----------- cogs/plugins.py | 75 +++++++++------ cogs/utility.py | 221 +++++++++++++++++++++++++++---------------- core/translations.py | 6 +- translation_files.py | 50 ++++++---- 6 files changed, 317 insertions(+), 190 deletions(-) diff --git a/bot.py b/bot.py index ddbeec2d31..a379567b4d 100644 --- a/bot.py +++ b/bot.py @@ -549,7 +549,9 @@ def check_account_age(self, author: discord.Member) -> bool: logger.debug("Blocked due to account age, user %s.", author.name) if str(author.id) not in self.blocked_users: - new_reason = _("System Message: New Account. Required to wait for {time}.").format(time=delta) + new_reason = _("System Message: New Account. Required to wait for {time}.").format( + time=delta + ) self.blocked_users[str(author.id)] = new_reason return False diff --git a/cogs/modmail.py b/cogs/modmail.py index 7f5b2fe15b..76a28b3c9c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -41,12 +41,18 @@ async def setup(self, ctx): if ctx.guild != self.bot.modmail_guild: return await ctx.send( - _("You can only setup in the Modmail guild: {guild_name}.".format(guild_name=self.bot.modmail_guild)) + _( + "You can only setup in the Modmail guild: {guild_name}.".format( + guild_name=self.bot.modmail_guild + ) + ) ) if self.bot.main_category is not None: logger.debug("Can't re-setup server, main_category is found.") - return await ctx.send(_("{guild_name} is already set up.").format(guild_name=self.bot.modmail_guild)) + return await ctx.send( + _("{guild_name} is already set up.").format(guild_name=self.bot.modmail_guild) + ) if self.bot.modmail_guild is None: embed = discord.Embed( @@ -89,21 +95,27 @@ async def setup(self, ctx): embed = discord.Embed( title=_("Friendly Reminder"), - description=_("You may use the `{prefix}config set log_channel_id " - "` command to set up a custom log channel, then you can delete this default " - "{log_channel} log channel.").format(prefix=self.bot.prefix, log_channel=log_channel.mention), + description=_( + "You may use the `{prefix}config set log_channel_id " + "` command to set up a custom log channel, then you can delete this default " + "{log_channel} log channel." + ).format(prefix=self.bot.prefix, log_channel=log_channel.mention), color=self.bot.main_color, ) embed.add_field( name=_("Thanks for using the bot!"), - value=_("If you like what you see, consider giving the " - "[repo a star](https://github.com/kyb3r/modmail) :star: or if you are " - "feeling generous, check us out on [Patreon](https://patreon.com/kyber)!"), + value=_( + "If you like what you see, consider giving the " + "[repo a star](https://github.com/kyb3r/modmail) :star: or if you are " + "feeling generous, check us out on [Patreon](https://patreon.com/kyber)!" + ), ) embed.set_footer( - text=_('Type "{prefix}help" for a complete list of commands.').format(prefix=self.bot.prefix) + text=_('Type "{prefix}help" for a complete list of commands.').format( + prefix=self.bot.prefix + ) ) await log_channel.send(embed=embed) @@ -112,12 +124,14 @@ async def setup(self, ctx): await self.bot.config.update() await ctx.send( - _("**Successfully set up server.**\n" - "Consider setting permission levels " - "to give access to roles or users the ability to use Modmail.\n\n" - "Type:\n- `{prefix}permissions` and `{prefix}permissions add` " - "for more info on setting permissions.\n" - "- `{prefix}config help` for a list of available customizations.").format(prefix=self.bot.prefix) + _( + "**Successfully set up server.**\n" + "Consider setting permission levels " + "to give access to roles or users the ability to use Modmail.\n\n" + "Type:\n- `{prefix}permissions` and `{prefix}permissions add` " + "for more info on setting permissions.\n" + "- `{prefix}config help` for a list of available customizations." + ).format(prefix=self.bot.prefix) ) if not self.bot.config["command_permissions"] and not self.bot.config["level_permissions"]: @@ -224,7 +238,9 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("An alias with the same name already exists: `{name}`.").format(name=name), + description=_("An alias with the same name already exists: `{name}`.").format( + name=name + ), ) return await ctx.send(embed=embed) @@ -323,16 +339,16 @@ async def send_scheduled_close_message(self, ctx, after, silent=False): embed = discord.Embed( title=_("Scheduled close"), - description=_("This thread will close {silent}in {time}.").format(silent=silent, time=human_delta), + description=_("This thread will close {silent}in {time}.").format( + silent=silent, time=human_delta + ), color=self.bot.error_color, ) if after.arg and not silent: embed.add_field(name=_("Message"), value=after.arg) - embed.set_footer( - text=_("Closing will be cancelled if a thread message is sent.") - ) + embed.set_footer(text=_("Closing will be cancelled if a thread message is sent.")) embed.timestamp = after.dt await ctx.send(embed=embed) @@ -430,15 +446,18 @@ async def notify( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} is already going to be mentioned.").format(mention=mention), + description=_("{mention} is already going to be mentioned.").format( + mention=mention + ), ) else: mentions.append(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=_("{mention} will be mentioned " - "on the next message received.").format(mention=mention), + description=_( + "{mention} will be mentioned " "on the next message received." + ).format(mention=mention), ) return await ctx.send(embed=embed) @@ -469,7 +488,9 @@ async def unnotify( if mention not in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} does not have a pending notification.").format(mention=mention), + description=_("{mention} does not have a pending notification.").format( + mention=mention + ), ) else: mentions.remove(mention) @@ -509,15 +530,18 @@ async def subscribe( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} is already subscribed to this thread.").format(mention=mention), + description=_("{mention} is already subscribed to this thread.").format( + mention=mention + ), ) else: mentions.append(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=_("{mention} will now be " - "notified of all messages received.").format(mention=mention), + description=_( + "{mention} will now be " "notified of all messages received." + ).format(mention=mention), ) return await ctx.send(embed=embed) @@ -548,14 +572,18 @@ async def unsubscribe( if mention not in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} is not already subscribed to this thread.").format(mention=mention), + description=_("{mention} is not already subscribed to this thread.").format( + mention=mention + ), ) else: mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=_("{mention} is now unsubscribed to this thread.").format(mention=mention), + description=_("{mention} is now unsubscribed to this thread.").format( + mention=mention + ), ) return await ctx.send(embed=embed) @@ -740,7 +768,9 @@ async def logs_responded(self, ctx, *, user: User = None): if not embeds: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} has not responded to any threads.").format(mention=getattr(user, 'mention', user.id)), + description=_("{mention} has not responded to any threads.").format( + mention=getattr(user, "mention", user.id) + ), ) return await ctx.send(embed=embed) @@ -896,8 +926,7 @@ async def contact( if user.bot: embed = discord.Embed( - color=self.bot.error_color, - description=_("Cannot start a thread with a bot."), + color=self.bot.error_color, description=_("Cannot start a thread with a bot."), ) return await ctx.send(embed=embed) @@ -905,8 +934,9 @@ async def contact( if exists: embed = discord.Embed( color=self.bot.error_color, - description=_("A thread for this user already " - "exists in {mention}.").format(mention=exists.channel.mention), + description=_("A thread for this user already " "exists in {mention}.").format( + mention=exists.channel.mention + ), ) await ctx.channel.send(embed=embed) @@ -917,8 +947,9 @@ async def contact( embed = discord.Embed( title=_("Created Thread"), - description=_("Thread started by {author_mention} " - "for {user_mention}.").format(author_mention=ctx.author.mention, user_mention=user.mention), + description=_("Thread started by {author_mention} " "for {user_mention}.").format( + author_mention=ctx.author.mention, user_mention=user.mention + ), color=self.bot.main_color, ) await thread.wait_until_ready() @@ -935,9 +966,7 @@ async def blocked(self, ctx): """Retrieve a list of blocked users.""" embeds = [ - discord.Embed( - title=_("Blocked Users"), color=self.bot.main_color, description="" - ) + discord.Embed(title=_("Blocked Users"), color=self.bot.main_color, description="") ] users = [] @@ -1015,8 +1044,10 @@ async def blocked_whitelist(self, ctx, *, user: User = None): reason = msg[16:].strip().rstrip(".") embed = discord.Embed( title="Success", - description=_("{mention} was previously blocked internally for " - '"{reason}". {mention} is now whitelisted.').format(mention=mention, reason=reason), + description=_( + "{mention} was previously blocked internally for " + '"{reason}". {mention} is now whitelisted.' + ).format(mention=mention, reason=reason), color=self.bot.main_color, ) else: @@ -1057,7 +1088,9 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi if str(user.id) in self.bot.blocked_whitelisted_users: embed = discord.Embed( title=_("Error"), - description=_("Cannot block {mention}, user is whitelisted.").format(mention=mention), + description=_("Cannot block {mention}, user is whitelisted.").format( + mention=mention + ), color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -1082,15 +1115,19 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi old_reason = msg.strip().rstrip(".") embed = discord.Embed( title=_("Success"), - description=_("{mention} was previously blocked {old_reason}.\n" - "{mention} is now blocked {reason}").format(mention=mention, old_reason=old_reason, reason=reason), + description=_( + "{mention} was previously blocked {old_reason}.\n" + "{mention} is now blocked {reason}" + ).format(mention=mention, old_reason=old_reason, reason=reason), color=self.bot.main_color, ) else: embed = discord.Embed( title=_("Success"), color=self.bot.main_color, - description=_("{mention} is now blocked {reason}").format(mention=mention, reason=reason), + description=_("{mention} is now blocked {reason}").format( + mention=mention, reason=reason + ), ) self.bot.blocked_users[str(user.id)] = reason await self.bot.config.update() @@ -1129,16 +1166,18 @@ async def unblock(self, ctx, *, user: User = None): reason = msg[16:].strip().rstrip(".") or "no reason" embed = discord.Embed( title="Success", - description=_("{mention} was previously blocked internally " - "{reason}.\n{mention} is no longer blocked.").format(mention=mention, reason=reason), + description=_( + "{mention} was previously blocked internally " + "{reason}.\n{mention} is no longer blocked." + ).format(mention=mention, reason=reason), color=self.bot.main_color, ) embed.set_footer( - text=_("However, if the original system block reason still applies, " - "{name} will be automatically blocked again. Use " - '"{self.bot.prefix}blocked whitelist {user.id}" to whitelist the user.').format( - name=name, prefix=self.bot.prefix, user_id=user.id - ) + text=_( + "However, if the original system block reason still applies, " + "{name} will be automatically blocked again. Use " + '"{self.bot.prefix}blocked whitelist {user.id}" to whitelist the user.' + ).format(name=name, prefix=self.bot.prefix, user_id=user.id) ) else: embed = discord.Embed( @@ -1355,7 +1394,9 @@ async def disable_new(self, ctx): else: embed = discord.Embed( title=_("Success"), - description=_("Modmail will not create **new** threads, but existing threads will now be functioning."), + description=_( + "Modmail will not create **new** threads, but existing threads will now be functioning." + ), color=self.bot.main_color, ) self.bot.config["dm_disabled"] = 1 @@ -1404,7 +1445,9 @@ async def isenable(self, ctx): elif self.bot.config["dm_disabled"] == 2: embed = discord.Embed( title=_("All DM Disabled"), - description=_("Modmail is not accepting any DM messages for new and existing threads."), + description=_( + "Modmail is not accepting any DM messages for new and existing threads." + ), color=self.bot.error_color, ) else: diff --git a/cogs/plugins.py b/cogs/plugins.py index 8868df3e77..4d335607e1 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -104,7 +104,7 @@ def __init__(self, bot): self.bot.loop.create_task(self.populate_registry()) - if getattr(self.bot, 'config', None) and self.bot.config.get("enable_plugins"): + if getattr(self.bot, "config", None) and self.bot.config.get("enable_plugins"): self.bot.loop.create_task(self.initial_load_plugins()) else: logger.info("Plugins not loaded since ENABLE_PLUGINS=false.") @@ -243,8 +243,10 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if required_version and self.bot.version < parse_version(required_version): embed = discord.Embed( - description=_("Your bot's version is too low. " - "This plugin requires version `{required_version}`.").format(required_version=required_version), + description=_( + "Your bot's version is too low. " + "This plugin requires version `{required_version}`." + ).format(required_version=required_version), color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -257,9 +259,11 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): plugin = Plugin.from_string(plugin_name) except InvalidPluginError: embed = discord.Embed( - description=_("Invalid plugin name, double check the plugin name " - "or use one of the following formats: " - "username/repo/plugin, username/repo/plugin@branch."), + description=_( + "Invalid plugin name, double check the plugin name " + "or use one of the following formats: " + "username/repo/plugin, username/repo/plugin@branch." + ), color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -292,8 +296,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): if str(plugin) in self.bot.config["plugins"]: embed = discord.Embed( - description=_("This plugin is already installed."), - color=self.bot.error_color, + description=_("This plugin is already installed."), color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -306,7 +309,9 @@ async def plugins_add(self, ctx, *, plugin_name: str): return await ctx.send(embed=embed) embed = discord.Embed( - description=_("Starting to download plugin from {plugin_link}...").format(plugin_link=plugin.link), + description=_("Starting to download plugin from {plugin_link}...").format( + plugin_link=plugin.link + ), color=self.bot.main_color, ) msg = await ctx.send(embed=embed) @@ -342,18 +347,25 @@ async def plugins_add(self, ctx, *, plugin_name: str): else: embed = discord.Embed( - description=_("Successfully installed plugin.\n" - "*Friendly reminder, plugins have absolute control over your bot. " - "Please only install plugins from developers you trust.*"), + description=_( + "Successfully installed plugin.\n" + "*Friendly reminder, plugins have absolute control over your bot. " + "Please only install plugins from developers you trust.*" + ), color=self.bot.main_color, ) else: embed = discord.Embed( - description=_("Successfully installed plugin.\n" - "*Friendly reminder, plugins have absolute control over your bot. " - "Please only install plugins from developers you trust.*") + "\n\n" + - _("This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, " - "to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot."), + description=_( + "Successfully installed plugin.\n" + "*Friendly reminder, plugins have absolute control over your bot. " + "Please only install plugins from developers you trust.*" + ) + + "\n\n" + + _( + "This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, " + "to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot." + ), color=self.bot.main_color, ) return await msg.edit(embed=embed) @@ -399,8 +411,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): pass # dir not empty embed = discord.Embed( - description=_("The plugin is successfully uninstalled."), - color=self.bot.main_color, + description=_("The plugin is successfully uninstalled."), color=self.bot.main_color, ) await ctx.send(embed=embed) @@ -426,7 +437,9 @@ async def update_plugin(self, ctx, plugin_name): await self.load_plugin(plugin) logger.debug("Updated %s.", plugin_name) embed = discord.Embed( - description=_("Successfully updated {plugin_name}.").format(plugin_name=plugin.name), + description=_("Successfully updated {plugin_name}.").format( + plugin_name=plugin.name + ), color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -459,8 +472,10 @@ async def plugins_loaded(self, ctx): if not self.bot.config.get("enable_plugins"): embed = discord.Embed( - description=_("No plugins are loaded due to `ENABLE_PLUGINS=false`, " - "to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot."), + description=_( + "No plugins are loaded due to `ENABLE_PLUGINS=false`, " + "to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot." + ), color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -531,15 +546,16 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N if not index and plugin_name is not None: embed = discord.Embed( color=self.bot.error_color, - description=_('Could not find a plugin with name "{plugin_name}" within the registry.').format(plugin_name=plugin_name), + description=_( + 'Could not find a plugin with name "{plugin_name}" within the registry.' + ).format(plugin_name=plugin_name), ) matches = get_close_matches(plugin_name, self.registry.keys()) if matches: embed.add_field( - name=_("Perhaps you meant:"), - value="\n".join(f"`{m}`" for m in matches), + name=_("Perhaps you meant:"), value="\n".join(f"`{m}`" for m in matches), ) return await ctx.send(embed=embed) @@ -559,8 +575,7 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N ) embed.add_field( - name=_("Installation"), - value=f"```{self.bot.prefix}plugins add {plugin_name}```", + name=_("Installation"), value=f"```{self.bot.prefix}plugins add {plugin_name}```", ) embed.set_author( @@ -579,8 +594,10 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N required_version = details.get("bot_version", False) if required_version and self.bot.version < parse_version(required_version): embed.set_footer( - text=_("Your bot is unable to install this plugin, " - "minimum required version is v{required_version}.").format(required_version=required_version) + text=_( + "Your bot is unable to install this plugin, " + "minimum required version is v{required_version}." + ).format(required_version=required_version) ) else: embed.set_footer(text=_("Your bot is able to install this plugin.")) diff --git a/cogs/utility.py b/cogs/utility.py index 2704e57f1b..9974deb803 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -75,8 +75,9 @@ async def format_cog_help(self, cog, *, no_cog=False): embed.set_author(name=name + continued, icon_url=bot.user.avatar_url) embed.set_footer( - text=_('Type "{prefix}{command} command" ' - "for more info on a specific command.").format(prefix=prefix, command=self.command_attrs["name"]) + text=_( + 'Type "{prefix}{command} command" ' "for more info on a specific command." + ).format(prefix=prefix, command=self.command_attrs["name"]) ) embeds.append(embed) return embeds @@ -154,8 +155,9 @@ async def send_group_help(self, group): embed.add_field(name=_("Sub Command(s)"), value=format_[:1024], inline=False) embed.set_footer( - text=_('Type "{prefix}{command} command" ' - "for more info on a command.").format(prefix=self.clean_prefix, command=self.command_attrs["name"]) + text=_('Type "{prefix}{command} command" ' "for more info on a command.").format( + prefix=self.clean_prefix, command=self.command_attrs["name"] + ) ) await self.get_destination().send(embed=embed) @@ -165,7 +167,8 @@ async def send_error_message(self, error): val = self.context.bot.snippets.get(command) if val is not None: embed = discord.Embed( - title=_("{command} is a snippet.").format(command=command), color=self.context.bot.main_color + title=_("{command} is a snippet.").format(command=command), + color=self.context.bot.main_color, ) embed.add_field(name=f"`{command}` will send:", value=val) return await self.get_destination().send(embed=embed) @@ -178,8 +181,10 @@ async def send_error_message(self, error): embed = discord.Embed( title=_("Error"), color=self.context.bot.error_color, - description=_("Alias `{command}` is invalid, this alias will now be deleted." - "This alias will now be deleted.").format(command=command), + description=_( + "Alias `{command}` is invalid, this alias will now be deleted." + "This alias will now be deleted." + ).format(command=command), ) embed.add_field(name=f"{command}` used to be:", value=val) self.context.bot.aliases.pop(command) @@ -187,21 +192,27 @@ async def send_error_message(self, error): else: if len(values) == 1: embed = discord.Embed( - title=_("{command} is an alias.").format(command=command), color=self.context.bot.main_color + title=_("{command} is an alias.").format(command=command), + color=self.context.bot.main_color, + ) + embed.add_field( + name=_("`{command}` points to:").format(command=command), value=values[0] ) - embed.add_field(name=_("`{command}` points to:").format(command=command), value=values[0]) else: embed = discord.Embed( title=_("{command} is an alias.").format(command=command), color=self.context.bot.main_color, - description=_("**`{command}` points to the following steps:**").format(command=command), + description=_("**`{command}` points to the following steps:**").format( + command=command + ), ) for i, val in enumerate(values, start=1): embed.add_field(name=_("Step") + f" {i}:", value=val) embed.set_footer( - text=_('Type "{prefix}{command} alias" ' - "for more details on aliases.").format(prefix=self.clean_prefix, command=self.command_attrs["name"]) + text=_('Type "{prefix}{command} alias" ' "for more details on aliases.").format( + prefix=self.clean_prefix, command=self.command_attrs["name"] + ) ) return await self.get_destination().send(embed=embed) @@ -224,8 +235,9 @@ async def send_error_message(self, error): else: embed.title = _("Cannot find command or category") embed.set_footer( - text=_('Type "{prefix}{command}" ' - "for a list of all available commands.").format(prefix=self.clean_prefix, command=self.command_attrs["name"]) + text=_('Type "{prefix}{command}" ' "for a list of all available commands.").format( + prefix=self.clean_prefix, command=self.command_attrs["name"] + ) ) await self.get_destination().send(embed=embed) @@ -263,7 +275,9 @@ async def changelog(self, ctx, version: str.lower = ""): return await ctx.send( embed=discord.Embed( color=self.bot.error_color, - description=_("The specified version `{version}` could not be found.").format(version=version), + description=_("The specified version `{version}` could not be found.").format( + version=version + ), ) ) @@ -279,7 +293,9 @@ async def changelog(self, ctx, version: str.lower = ""): finally: logger.warning("Failed to display changelog.", exc_info=True) await ctx.send( - _("View the changelog here: {url}").format(url=f'{changelog.latest_version.changelog_url}#v{version[::2]}') + _("View the changelog here: {url}").format( + url=f"{changelog.latest_version.changelog_url}#v{version[::2]}" + ) ) @commands.command(aliases=["info"]) @@ -295,9 +311,11 @@ async def about(self, ctx): ) embed.set_thumbnail(url=self.bot.user.avatar_url) - desc = _("This is an open source Discord bot that serves as a means for " - "members to easily communicate with server administrators in " - "an organised manner.") + desc = _( + "This is an open source Discord bot that serves as a means for " + "members to easily communicate with server administrators in " + "an organised manner." + ) embed.description = desc embed.add_field(name=_("Uptime"), value=self.bot.uptime) @@ -312,7 +330,9 @@ async def about(self, ctx): stable = next( filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions) ) - footer = _("You are on the prerelease version • the latest version is v{version}.").format(version=stable.version) + footer = _( + "You are on the prerelease version • the latest version is v{version}." + ).format(version=stable.version) elif self.bot.version < parse_version(latest.version): footer = _("A newer version is available v{version}.").format(version=latest.version) else: @@ -320,16 +340,20 @@ async def about(self, ctx): embed.add_field( name=_("Want Modmail in Your Server?"), - value=_("Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " - "and join our [Discord server](https://discord.gg/F34cRU8/)!"), + value=_( + "Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " + "and join our [Discord server](https://discord.gg/F34cRU8/)!" + ), inline=False, ) embed.add_field( name=_("Support the Developers"), - value=_("This bot is completely free for everyone. We rely on kind individuals " - "like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) " - "to keep this bot free forever!"), + value=_( + "This bot is completely free for everyone. We rely on kind individuals " + "like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) " + "to keep this bot free forever!" + ), inline=False, ) @@ -654,14 +678,14 @@ async def mention(self, ctx, *, mention: str = None): if mention is None: embed = discord.Embed( - title=_("Current mention:"), - color=self.bot.main_color, - description=str(current), + title=_("Current mention:"), color=self.bot.main_color, description=str(current), ) else: embed = discord.Embed( title=_("Changed mention!"), - description=_('On thread creation the bot now says "{mention}".').format(mention=mention), + description=_('On thread creation the bot now says "{mention}".').format( + mention=mention + ), color=self.bot.main_color, ) self.bot.config["mention"] = mention @@ -745,7 +769,9 @@ async def config_set(self, ctx, key: str.lower, *, value: str): embed = discord.Embed( title=_("Success"), color=self.bot.main_color, - description=_("Set `{key}` to `{value}`.").format(key=key, value=self.bot.config[key]), + description=_("Set `{key}` to `{value}`.").format( + key=key, value=self.bot.config[key] + ), ) except InvalidConfigError as exc: embed = exc.embed @@ -798,9 +824,7 @@ async def config_get(self, ctx, *, key: str.lower = None): if key in keys: desc = _("`{key}` is set to `{value}`").format(key=key, value=self.bot.config[key]) embed = discord.Embed(color=self.bot.main_color, description=desc) - embed.set_author( - name=_("Config variable"), icon_url=self.bot.user.avatar_url - ) + embed.set_author(name=_("Config variable"), icon_url=self.bot.user.avatar_url) else: embed = discord.Embed( @@ -809,18 +833,17 @@ async def config_get(self, ctx, *, key: str.lower = None): description=_("`{key}` is an invalid key.").format(key=key), ) embed.set_footer( - text=_('Type "{prefix}config options" for a list of config variables.').format(prefix=self.bot.prefix) + text=_('Type "{prefix}config options" for a list of config variables.').format( + prefix=self.bot.prefix + ) ) else: embed = discord.Embed( color=self.bot.main_color, - description=_("Here is a list of currently " - "set configuration variable(s)."), - ) - embed.set_author( - name=_("Current config(s):"), icon_url=self.bot.user.avatar_url + description=_("Here is a list of currently " "set configuration variable(s)."), ) + embed.set_author(name=_("Current config(s):"), icon_url=self.bot.user.avatar_url) embed.set_author(name="Current config(s):", icon_url=self.bot.user.avatar_url) config = self.bot.config.filter_default(self.bot.config) @@ -872,13 +895,13 @@ def fmt(val): if current_key == key: index = i embed = discord.Embed( - title=_("Configuration description on {current_key}:").format(current_key=current_key), + title=_("Configuration description on {current_key}:").format( + current_key=current_key + ), color=self.bot.main_color, ) embed.add_field(name="Default:", value=fmt(info["default"]), inline=False) - embed.add_field( - name=_("Information:"), value=fmt(info["description"]), inline=False - ) + embed.add_field(name=_("Information:"), value=fmt(info["description"]), inline=False) if info["examples"]: example_text = "" for example in info["examples"]: @@ -936,8 +959,10 @@ async def alias(self, ctx, *, name: str.lower = None): embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("Alias `{name}` is invalid, it used to be `{value}`. " - "This alias will now be deleted.").format(name=name, value=escape_markdown(val)), + description=_( + "Alias `{name}` is invalid, it used to be `{value}`. " + "This alias will now be deleted." + ).format(name=name, value=escape_markdown(val)), ) embed.add_field(name=f"{name}` used to be:", value=utils.truncate(val, 1024)) self.bot.aliases.pop(name) @@ -946,7 +971,9 @@ async def alias(self, ctx, *, name: str.lower = None): if len(values) == 1: embed = discord.Embed( - title=_("Alias") + f' - "{name}":', description=values[0], color=self.bot.main_color + title=_("Alias") + f' - "{name}":', + description=values[0], + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -967,7 +994,9 @@ async def alias(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description=_("You dont have any aliases at the moment."), ) - embed.set_footer(text=_("Do {prefix}help alias for more commands.").format(prefix=self.bot.prefix)) + embed.set_footer( + text=_("Do {prefix}help alias for more commands.").format(prefix=self.bot.prefix) + ) embed.set_author(name=_("Aliases"), icon_url=ctx.guild.icon_url) return await ctx.send(embed=embed) @@ -1024,7 +1053,10 @@ async def make_alias(self, name, value, action): embed = discord.Embed(title=_("{action} alias").format(action), color=self.bot.main_color) if not multiple_alias: - embed.add_field(name=_("`{name}` points to:").format(name=name), value=utils.truncate(values[0], 1024)) + embed.add_field( + name=_("`{name}` points to:").format(name=name), + value=utils.truncate(values[0], 1024), + ) else: embed.description = _("`{name}` now points to the following steps:").format(name=name) @@ -1041,15 +1073,15 @@ async def make_alias(self, name, value, action): embed = discord.Embed(title="Error", color=self.bot.error_color) if multiple_alias: - embed.description = ( - _("The command you are attempting to point " - "to does not exist: `{command}`.").format(command=linked_command) - ) + embed.description = _( + "The command you are attempting to point " + "to does not exist: `{command}`." + ).format(command=linked_command) else: - embed.description = ( - _("The command you are attempting to point " - "to on step {number} does not exist: `{command}`.").format(number=i, command=linked_command) - ) + embed.description = _( + "The command you are attempting to point " + "to on step {number} does not exist: `{command}`." + ).format(number=i, command=linked_command) return embed else: @@ -1082,21 +1114,27 @@ async def alias_add(self, ctx, name: str.lower, *, value): embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("A command with the same name already exists: `{name}`.").format(name=name), + description=_("A command with the same name already exists: `{name}`.").format( + name=name + ), ) elif name in self.bot.aliases: embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("Another alias with the same name already exists: `{name}`.").format(name=name), + description=_("Another alias with the same name already exists: `{name}`.").format( + name=name + ), ) elif name in self.bot.snippets: embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("A snippet with the same name already exists: `{name}`.").format(name=name), + description=_("A snippet with the same name already exists: `{name}`.").format( + name=name + ), ) elif len(name) > 120: @@ -1228,7 +1266,9 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("The referenced level does not exist: `{level}`.").format(level=level_name), + description=_("The referenced level does not exist: `{level}`.").format( + level=level_name + ), ) else: logger.info( @@ -1242,8 +1282,9 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name embed = discord.Embed( title=_("Success"), color=self.bot.main_color, - description=_("Successfully set command permission level for " - "`{command}` to `{level}`.").format(command=command.qualified_name, level=level.name), + description=_( + "Successfully set command permission level for " "`{command}` to `{level}`." + ).format(command=command.qualified_name, level=level.name), ) return await ctx.send(embed=embed) @@ -1288,7 +1329,9 @@ async def permissions_add( embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("The referenced {type} does not exist: `{name}`.").format(type=type_, name=name), + description=_("The referenced {type} does not exist: `{name}`.").format( + type=type_, name=name + ), ) return await ctx.send(embed=embed) @@ -1364,8 +1407,10 @@ async def permissions_remove( embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("The command permission level was never overridden: `{name}`, " - "current permission level is {perm_name}.").format(name=name, perm_name=perm.name), + description=_( + "The command permission level was never overridden: `{name}`, " + "current permission level is {perm_name}." + ).format(name=name, perm_name=perm.name), ) else: logger.info("Restored command permission level for `%s`.", name) @@ -1375,7 +1420,9 @@ async def permissions_remove( embed = discord.Embed( title=_("Success"), color=self.bot.main_color, - description=_("Command permission level for `{name}` was successfully restored to {perm_name}.").format(name=name, perm_name=perm.name), + description=_( + "Command permission level for `{name}` was successfully restored to {perm_name}." + ).format(name=name, perm_name=perm.name), ) return await ctx.send(embed=embed) @@ -1389,7 +1436,9 @@ async def permissions_remove( embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("The referenced level does not exist: `{name}`.").format(name=name), + description=_("The referenced level does not exist: `{name}`.").format( + name=name + ), ) return await ctx.send(embed=embed) name = level.name @@ -1525,12 +1574,16 @@ async def permissions_get( embeds = [ discord.Embed( - title=_("{mention} has permission with the following commands:").format(mention=mention), + title=_("{mention} has permission with the following commands:").format( + mention=mention + ), description=desc_cmd, color=self.bot.main_color, ), discord.Embed( - title=_("{mention} has permission with the following permission levels:").format(mention=mention), + title=_( + "{mention} has permission with the following permission levels:" + ).format(mention=mention), description=desc_level, color=self.bot.main_color, ), @@ -1556,7 +1609,9 @@ async def permissions_get( embeds.append( discord.Embed( title=_("Permission Overrides"), - description=_("You don't have any command level overrides at the moment."), + description=_( + "You don't have any command level overrides at the moment." + ), color=self.bot.error_color, ) ) @@ -1585,14 +1640,18 @@ async def permissions_get( embed = discord.Embed( title=_("Error"), color=self.bot.error_color, - description=_("The command permission level was never overridden: `{name}`, " - "current permission level is {perm_name}.").format(name=name, perm_name=perm.name), + description=_( + "The command permission level was never overridden: `{name}`, " + "current permission level is {perm_name}." + ).format(name=name, perm_name=perm.name), ) else: embed = discord.Embed( title=_("Success"), color=self.bot.main_color, - description=_('Permission override for command "{name}" is "{perm_name}".').format(name=name, perm_name=perm.name), + description=_( + 'Permission override for command "{name}" is "{perm_name}".' + ).format(name=name, perm_name=perm.name), ) return await ctx.send(embed=embed) @@ -1674,12 +1733,12 @@ async def oauth_whitelist(self, ctx, target: Union[discord.Role, utils.User]): target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role(target.id) if removed: - embed.description = ( - _("Un-whitelisted {target_mention} to view logs.").format(target_mention=target.mention) + embed.description = _("Un-whitelisted {target_mention} to view logs.").format( + target_mention=target.mention ) else: - embed.description = ( - _("Whitelisted {target_mention} to view logs.").format(target_mention=target.mention) + embed.description = _("Whitelisted {target_mention} to view logs.").format( + target_mention=target.mention ) await ctx.send(embed=embed) @@ -1704,12 +1763,8 @@ async def oauth_show(self, ctx): embed = discord.Embed(color=self.bot.main_color) embed.title = _("Oauth Whitelist") - embed.add_field( - name=_("Users"), value=" ".join(u.mention for u in users) or _("None") - ) - embed.add_field( - name="Roles", value=" ".join(r.mention for r in roles) or "None" - ) + embed.add_field(name=_("Users"), value=" ".join(u.mention for u in users) or _("None")) + embed.add_field(name="Roles", value=" ".join(r.mention for r in roles) or "None") await ctx.send(embed=embed) diff --git a/core/translations.py b/core/translations.py index 218b5f91ae..98a3327386 100644 --- a/core/translations.py +++ b/core/translations.py @@ -5,13 +5,13 @@ class Translator: def __init__(self): - self.language = os.getenv('language', 'en') + self.language = os.getenv("language", "en") self.texts = {} self.generate_texts() def generate_texts(self): - with open(f'languages/{self.language}.csv', encoding='utf8') as f: - reader = csv.reader(f, dialect='unix') + with open(f"languages/{self.language}.csv", encoding="utf8") as f: + reader = csv.reader(f, dialect="unix") for n, row in enumerate(reader): if n != 0: diff --git a/translation_files.py b/translation_files.py index 7d50c53417..07c6979f63 100644 --- a/translation_files.py +++ b/translation_files.py @@ -11,27 +11,29 @@ from cogs.utility import Utility -data = [('Identifier', 'English', 'Context')] +data = [("Identifier", "English", "Context")] all_identifiers = [] identifiers = {} class FormatError(Exception): def __init__(self, reason, string): - super().__init__(f'Unable to parse {reason}: {string}') + super().__init__(f"Unable to parse {reason}: {string}") -for filename in glob.glob('**/*.py') + glob.glob('*.py'): - if filename == 'translation_files.py': +for filename in glob.glob("**/*.py") + glob.glob("*.py"): + if filename == "translation_files.py": continue - with open(filename, encoding='utf8') as f: + with open(filename, encoding="utf8") as f: filedata = f.read() - regex_matches = re.findall(r'(?:^|[^A-z])_\(.+?(?:\'|\")\)+?', filedata, flags=re.DOTALL | re.MULTILINE) + regex_matches = re.findall( + r"(?:^|[^A-z])_\(.+?(?:\'|\")\)+?", filedata, flags=re.DOTALL | re.MULTILINE + ) for i in regex_matches: if "f'" in i or 'f"' in i: - print(FormatError('f-string', i)) - identifier = '' + print(FormatError("f-string", i)) + identifier = "" read = False ignore_inverted = False newline = False @@ -48,7 +50,7 @@ def __init__(self, reason, string): read = not read triggered = True - if x == '\n': + if x == "\n": newline = True if read and not triggered: @@ -62,7 +64,7 @@ def __init__(self, reason, string): else: counter = 0 - if x == '\\': + if x == "\\": ignore_inverted = True elif ignore_inverted: ignore_inverted = False @@ -81,16 +83,16 @@ def __init__(self, reason, string): if identifier in identifiers.keys(): if filename not in data[identifiers[identifier]][2]: - data[identifiers[identifier]][2] += f' {filename}/L{linenum}' + data[identifiers[identifier]][2] += f" {filename}/L{linenum}" elif str(linenum) not in data[identifiers[identifier]][2]: - split_space = data[identifiers[identifier]][2].split(' ') + split_space = data[identifiers[identifier]][2].split(" ") for nx, x in enumerate(split_space): if filename in x: - split_space[nx] += f'/L{linenum}' + split_space[nx] += f"/L{linenum}" break - data[identifiers[identifier]][2] = (' ').join(split_space) + data[identifiers[identifier]][2] = (" ").join(split_space) else: - data.append([identifier, identifier, f'File: {filename}/L{linenum}']) + data.append([identifier, identifier, f"File: {filename}/L{linenum}"]) identifiers[identifier] = len(data) - 1 print(filename) @@ -101,17 +103,25 @@ def __init__(self, reason, string): cogs = [Modmail(bot), Plugins(bot), Utility(bot)] for i in cogs: if i.description: - data.append([i.description, i.description, f'Cog: {i.__cog_name__}']) + data.append([i.description, i.description, f"Cog: {i.__cog_name__}"]) for cmd in i.walk_commands(): if cmd not in done: if cmd.short_doc: print(cmd) - data.append([cmd.short_doc, cmd.short_doc, f'Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}']) - data.append([cmd.help, cmd.help, f'Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}']) + data.append( + [ + cmd.short_doc, + cmd.short_doc, + f"Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}", + ] + ) + data.append( + [cmd.help, cmd.help, f"Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}"] + ) done.add(cmd) -with open('languages/en.csv', 'w+') as f: - csv.writer(f, dialect='unix').writerows(data) +with open("languages/en.csv", "w+") as f: + csv.writer(f, dialect="unix").writerows(data) From a27f8bcf988f0d0cc3f7474bce32cb68af4394a8 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Wed, 8 Jul 2020 23:30:30 -0700 Subject: [PATCH 051/705] dpy 1.3.4 --- Pipfile | 2 +- Pipfile.lock | 49 ++++++++++++++++++++++---------------------- requirements.min.txt | 4 ++-- runtime.txt | 2 +- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Pipfile b/Pipfile index 16bbac8e49..7a51fffd39 100644 --- a/Pipfile +++ b/Pipfile @@ -21,7 +21,7 @@ parsedatetime = "==2.6" aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -"discord.py" = "==1.3.3" +"discord.py" = "==1.3.4" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 9a650f4af4..57570d4062 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "bfb85b7c7862e17e905d739f0fb63248d3bf446035f32e3afac619f6d2c5a0ba" + "sha256": "2d28437167e3e207b978644be0e6cacbd6b46faa445da13b6f27b6fe630aac28" }, "pipfile-spec": 6, "requires": { @@ -59,10 +59,10 @@ }, "certifi": { "hashes": [ - "sha256:5ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1", - "sha256:9cd41137dc19af6a5e03b630eefe7d1f458d964d406342dd3edf625839b944cc" + "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", + "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" ], - "version": "==2020.4.5.2" + "version": "==2020.6.20" }, "chardet": { "hashes": [ @@ -81,17 +81,18 @@ }, "discord.py": { "hashes": [ - "sha256:406871b06d86c3dc49fba63238519f28628dac946fef8a0e22988ff58ec05580", - "sha256:ad00e34c72d2faa8db2157b651d05f3c415d7d05078e7e41dc9e8dc240051beb" + "sha256:1b546a32c0cd83d949392a71e5b06e30e19d1067246e3826d32ae9b8b3d06c1e", + "sha256:8ef58d6fc1e66903bc00ae79c4c09a38aa71043e88a83da4d2e8b9b1c9f9b9e2" ], "index": "pypi", - "version": "==1.3.3" + "version": "==1.3.4" }, "distlib": { "hashes": [ - "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21" + "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb", + "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1" ], - "version": "==0.3.0" + "version": "==0.3.1" }, "dnspython": { "hashes": [ @@ -117,19 +118,19 @@ }, "idna": { "hashes": [ - "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", - "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa" + "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", + "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.9" + "version": "==2.10" }, "importlib-metadata": { "hashes": [ - "sha256:0505dd08068cfec00f53a74a0ad927676d7757da81b7436a6eefe4c7cf75c545", - "sha256:15ec6c0fd909e893e3a08b3a7c76ecb149122fb14b7efe1199ddd4c7c57ea958" + "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83", + "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070" ], "markers": "python_version < '3.8'", - "version": "==1.6.1" + "version": "==1.7.0" }, "isodate": { "hashes": [ @@ -265,11 +266,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", - "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" + "sha256:8c10c99a1b25d9a68058a1ad6f90381a62ba68230ca93966882a4dbc3bc9c33d", + "sha256:c10863aee750ad720f4f43436565e4c1698798d763b63234fb5021b6c616e423" ], "index": "pypi", - "version": "==0.13.0" + "version": "==0.14.0" }, "six": { "hashes": [ @@ -297,11 +298,11 @@ }, "virtualenv": { "hashes": [ - "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf", - "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70" + "sha256:c11a475400e98450403c0364eb3a2d25d42f71cf1493da64390487b666de4324", + "sha256:e10cc66f40cbda459720dfe1d334c4dc15add0d80f09108224f171006a97a172" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.0.21" + "version": "==20.0.26" }, "virtualenv-clone": { "hashes": [ @@ -559,11 +560,11 @@ }, "stevedore": { "hashes": [ - "sha256:001e90cd704be6470d46cc9076434e2d0d566c1379187e7013eb296d3a6032d9", - "sha256:471c920412265cc809540ae6fb01f3f02aba89c79bbc7091372f4745a50f9691" + "sha256:609912b87df5ad338ff8e44d13eaad4f4170a65b79ae9cb0aa5632598994a1b7", + "sha256:c4724f8d7b8f6be42130663855d01a9c2414d6046055b5a65ab58a0e38637688" ], "markers": "python_version >= '3.6'", - "version": "==2.0.0" + "version": "==2.0.1" }, "toml": { "hashes": [ diff --git a/requirements.min.txt b/requirements.min.txt index e3ba980fc1..28550f1e50 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -6,7 +6,7 @@ aiohttp==3.6.2 async-timeout==3.0.1 attrs==19.3.0 chardet==3.0.4 -discord.py==1.3.3 +discord.py==1.3.4 dnspython==1.16.0 emoji==0.5.4 future==0.18.2 @@ -18,7 +18,7 @@ natural==0.2.0 parsedatetime==2.6 pymongo==3.10.1 python-dateutil==2.8.1 -python-dotenv==0.13.0 +python-dotenv==0.14.0 six==1.15.0 websockets==8.1 yarl==1.4.2 diff --git a/runtime.txt b/runtime.txt index 257b314f5f..05802392e0 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.6 \ No newline at end of file +python-3.7.7 \ No newline at end of file From 86f959c443e3d679d9a03707771aca0b1a180696 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Wed, 8 Jul 2020 23:38:30 -0700 Subject: [PATCH 052/705] Use py 3.7.8 --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 05802392e0..423adc28cf 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.7 \ No newline at end of file +python-3.7.8 \ No newline at end of file From 53a5176a58d22ef96e529019b0313902bd129730 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Wed, 8 Jul 2020 23:59:55 -0700 Subject: [PATCH 053/705] Freeze into requirements.txt --- pyproject.toml | 6 +++--- requirements.txt | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 requirements.txt diff --git a/pyproject.toml b/pyproject.toml index 54f4efb4e7..b8547d752b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,9 +36,9 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "=1.3.3" -uvloop = {version=">=0.12.0", sys_platform = "!= 'win32'"} -python-dotenv = "^0.10.3" +"discord.py" = "=1.3.4" +uvloop = {version = ">=0.12.0", sys_platform = "!= 'win32'"} +python-dotenv = ">=0.10.3" parsedatetime = "^2.6" dnspython = "^1.16" isodate = "^0.6.0" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..4df684c56d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,37 @@ +aiohttp==3.6.2 +appdirs==1.4.4 +async-timeout==3.0.1 +attrs==19.3.0 +certifi==2020.6.20 +chardet==3.0.4 +colorama==0.4.3 +dadjokes==1.3 +discord.py==1.3.4 +distlib==0.3.1 +dnspython==1.16.0 +emoji==0.5.4 +filelock==3.0.12 +idna==2.10 +importlib-metadata==1.7.0 +isodate==0.6.0 +motor==2.1.0 +multidict==4.7.6 +natural==0.2.0 +parsedatetime==2.6 +pipenv==2020.6.2 +pymongo==3.10.1 +python-box==4.2.3 +python-dateutil==2.8.1 +python-dotenv==0.14.0 +requests==2.24.0 +ruamel.yaml==0.16.10 +ruamel.yaml.clib==0.2.0 +six==1.15.0 +toml==0.10.1 +urllib3==1.25.9 +uvloop==0.14.0 +virtualenv==20.0.26 +virtualenv-clone==0.5.4 +websockets==8.1 +yarl==1.4.2 +zipp==3.1.0 From e849892a0112c040b820242277332a30b8ab1e3f Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jul 2020 00:01:52 -0700 Subject: [PATCH 054/705] Dont use pipenv in procfile --- Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 5ae4640def..29cff6d9d1 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -worker: pipenv run bot +worker: python bot.py From 494abba75bdfc2298ed2e8d70a79d2a60ba078a6 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jul 2020 00:04:14 -0700 Subject: [PATCH 055/705] Done --- requirements.txt | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 4df684c56d..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,37 +0,0 @@ -aiohttp==3.6.2 -appdirs==1.4.4 -async-timeout==3.0.1 -attrs==19.3.0 -certifi==2020.6.20 -chardet==3.0.4 -colorama==0.4.3 -dadjokes==1.3 -discord.py==1.3.4 -distlib==0.3.1 -dnspython==1.16.0 -emoji==0.5.4 -filelock==3.0.12 -idna==2.10 -importlib-metadata==1.7.0 -isodate==0.6.0 -motor==2.1.0 -multidict==4.7.6 -natural==0.2.0 -parsedatetime==2.6 -pipenv==2020.6.2 -pymongo==3.10.1 -python-box==4.2.3 -python-dateutil==2.8.1 -python-dotenv==0.14.0 -requests==2.24.0 -ruamel.yaml==0.16.10 -ruamel.yaml.clib==0.2.0 -six==1.15.0 -toml==0.10.1 -urllib3==1.25.9 -uvloop==0.14.0 -virtualenv==20.0.26 -virtualenv-clone==0.5.4 -websockets==8.1 -yarl==1.4.2 -zipp==3.1.0 From 178ea9c0ac56a345cf1ddea48e3bcc1524f83136 Mon Sep 17 00:00:00 2001 From: Taaku18 <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jul 2020 00:12:53 -0700 Subject: [PATCH 056/705] Dump 3.5.0 --- CHANGELOG.md | 7 +++++-- bot.py | 7 ++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0956794786..9d3d127944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.5.0dev5 +# v3.5.0 + +Fixed discord.py issue. ### Added @@ -23,7 +25,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Deleting channel manually will now close the thread. - Deleting messages will no longer cause the bot to produce warnings. - Plugins will automatically be removed when it fails to load. -- Moved all database-related activities to clients.py under MongoDBClient, with possible future hook for additional database support. +- Moved all database-related activities to clients.py under MongoDBClient, with possible future hook for additional database support. +- `bot.db` is deprecated in favour of `bot.api.db` and will be removed in the future. - Deprecated `bot.plugin_db.get_partition` in favour of `bot.api.get_plugin_partition` (not final). - Deprecated `MONGO_URI` config var (but will keep support in the future) in favour of `CONNECTION_URI` and `DATABASE_TYPE`. Right now there is one supported database - "mongodb", which is the default. diff --git a/bot.py b/bot.py index bba04ff50d..9e48c0f342 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.5.0-dev5" +__version__ = "3.5.0" import asyncio @@ -148,6 +148,11 @@ def api(self) -> ApiClient: raise RuntimeError return self._api + @property + def db(self): + # deprecated + return self.api.db + async def get_prefix(self, message=None): return [self.prefix, f"<@{self.user.id}> ", f"<@!{self.user.id}> "] From 846dfbd0ca44c66165ea33cf83bb96bc2ef0ae2b Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Thu, 9 Jul 2020 06:24:58 -0700 Subject: [PATCH 057/705] Eval was disabled by default by accident, reverted --- core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config.py b/core/config.py index f945557718..4f54c2b29c 100644 --- a/core/config.py +++ b/core/config.py @@ -113,7 +113,7 @@ class ConfigManager: # bot "token": None, "enable_plugins": True, - "enable_eval": False, + "enable_eval": True, # github access token for private repositories "github_token": None, # Logging From 8db53571d66d72e7c3a4c5481afb9ed1f5b74b6d Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 10 Jul 2020 00:09:45 +0200 Subject: [PATCH 058/705] run this when you use pm2 on your vps --- modmail.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 modmail.sh diff --git a/modmail.sh b/modmail.sh new file mode 100644 index 0000000000..2dbc7218ff --- /dev/null +++ b/modmail.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +pipenv run python3 bot.py \ No newline at end of file From 1b75995913db9aa9349facf1607c19381b16f8f2 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 10 Jul 2020 00:10:05 +0200 Subject: [PATCH 059/705] Update .env.example --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index b3554bf9c9..14bdf060bf 100644 --- a/.env.example +++ b/.env.example @@ -2,4 +2,4 @@ TOKEN=MyBotToken LOG_URL=https://logviewername.herokuapp.com/ GUILD_ID=1234567890 OWNERS=Owner1ID,Owner2ID,Owner3ID -MONGO_URI=mongodb+srv://mongodburi +CONNECTION_URI=mongodb+srv://mongodburi From cc4ba8b788277ca1d7c40afb52d88ec9907a4311 Mon Sep 17 00:00:00 2001 From: kuro <46526001+WebKide@users.noreply.github.com> Date: Thu, 23 Jul 2020 20:57:45 +0100 Subject: [PATCH 060/705] added translate :wave: this command conflicts with Translator... --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index b15bb374dc..b36f89feec 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -222,5 +222,14 @@ "title": "Slow Mode", "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" + }, + "translate": { + "repository": "WebKide/modmail-plugins", + "branch": "master", + "description": "(∩`-´)⊃━☆゚.*・。゚ translate text from one language to another (defaults to English)\n\nGet full list of available languages at: https://github.com/WebKide/modmail-plugins/blob/master/translate/langs.json\n\nThis command conflicts with Translator-plugin", + "bot_version": "3.5.0", + "title": "Translate", + "icon_url": "https://i.imgur.com/yeHFKgl.png", + "thumbnail_url": "https://i.imgur.com/yeHFKgl.png" } } From 7100d9755a78372444ce050770bfa5a5a63404dd Mon Sep 17 00:00:00 2001 From: codeinteger6 <44692189+codeinteger6@users.noreply.github.com> Date: Thu, 6 Aug 2020 19:16:55 +0600 Subject: [PATCH 061/705] Add publish plugin to registry (#2835) Update registry.json --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index b15bb374dc..6e9ada2150 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -222,5 +222,14 @@ "title": "Slow Mode", "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" + }, + "publish": { + "repository": "codeinteger6/modmail-plugins", + "branch": "master", + "description": "Publish messages sent in announcement channels.", + "bot_version": "3.5.0", + "title": "Publish", + "icon_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png", + "thumbnail_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png" } } From c836787ad3494f2ac7290123bb617f53331fcf95 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 7 Aug 2020 03:06:24 +0200 Subject: [PATCH 062/705] Update README.md (#2837) and Add music plugin --- README.md | 2 +- cogs/modmail.py | 4 ++-- plugins/registry.json | 13 +++++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4b36c5a3d2..76c2a4f107 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
diff --git a/cogs/modmail.py b/cogs/modmail.py index 5c4de73e26..9ec5d5604f 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -540,7 +540,7 @@ async def unsubscribe( if mention not in mentions: embed = discord.Embed( color=self.bot.error_color, - description=f"{mention} is not already subscribed to this thread.", + description=f"{mention} is not subscribed to this thread.", ) else: mentions.remove(mention) @@ -1355,7 +1355,7 @@ async def isenable(self, ctx): else: embed = discord.Embed( title="Enabled", - description="Modmail is accepting all DM messages.", + description="Modmail now is accepting all DM messages.", color=self.bot.main_color, ) diff --git a/plugins/registry.json b/plugins/registry.json index 6e9ada2150..5a12d84191 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -7,8 +7,17 @@ "title": "Profanity Filter Plugin", "icon_url": "https://i.imgur.com/951szZ3.jpg", "thumbnail_url": "https://i.imgur.com/951szZ3.jpg" - }, - "dragory-migrate": { + }, + "music": { + "repository": "lorenzo132/modmail-plugins", + "branch": "master", + "description": "Play your favourite music on your bot! Note: Only works on VPS follow this guide: https://gist.github.com/lorenzo132/5ef328e5dfcfaec19cb81dc7a63eaffa", + "bot_version": "2.20.1", + "title": "Music", + "icon_url": "https://i.imgur.com/R2olclk.png", + "thumbnail_url": "https://i.imgur.com/xuoQjPu.gif" + }, + "dragory-migrate": { "repository": "kyb3r/modmail-plugins", "branch": "master", "description": "Migrate your logs from Dragory's modmail bot to this one with a simple command. Added at the request of users.", From c954dbab43c8b923a1f4a4b221f8217bd25e8114 Mon Sep 17 00:00:00 2001 From: Stephen <48072084+StephenDaDev@users.noreply.github.com> Date: Sun, 9 Aug 2020 13:18:42 -0400 Subject: [PATCH 063/705] Remove stale GitHub workflow --- .github/workflows/stale.yml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index d0811bfd30..0000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: "Close Stale Issues" - -on: - schedule: - - cron: "0 0 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is stale because it has been open for 100 days with no activity. Remove stale label or comment or this will be closed in 5 days. Please do not un-stale this issue unless it carries significant contribution.' - days-before-stale: 100 - days-before-close: 5 - exempt-issue-label: 'priority: high,approved,security,bug' From a61f431e546ede1e5be20644a4aee01817a4e372 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 21 Aug 2020 23:23:56 +0800 Subject: [PATCH 064/705] Deps --- Pipfile | 4 +- Pipfile.lock | 374 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 225 insertions(+), 153 deletions(-) diff --git a/Pipfile b/Pipfile index 7a51fffd39..0872abf3e2 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ bandit = "==1.6.2" colorama = ">=0.4.0" python-dateutil = ">=2.7.0" emoji = ">=0.2" -uvloop = {version=">=0.12.0", sys_platform = "!= 'win32'"} +uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} motor = ">=2.0.0" natural = "==0.2.0" isodate = ">=0.6.0" @@ -22,6 +22,8 @@ aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" "discord.py" = "==1.3.4" +pynacl = "*" +cffi = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 57570d4062..807d74cb97 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2d28437167e3e207b978644be0e6cacbd6b46faa445da13b6f27b6fe630aac28" + "sha256": "397b06fdc5c4560667c7d3b2b8323ffd6ac3961fc561a470ccf99d8a5c234ffb" }, "pipfile-spec": 6, "requires": { @@ -46,16 +46,14 @@ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], - "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a", + "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==19.3.0" + "version": "==20.1.0" }, "certifi": { "hashes": [ @@ -64,6 +62,40 @@ ], "version": "==2020.6.20" }, + "cffi": { + "hashes": [ + "sha256:0da50dcbccd7cb7e6c741ab7912b2eff48e85af217d72b57f80ebc616257125e", + "sha256:12a453e03124069b6896107ee133ae3ab04c624bb10683e1ed1c1663df17c13c", + "sha256:15419020b0e812b40d96ec9d369b2bc8109cc3295eac6e013d3261343580cc7e", + "sha256:15a5f59a4808f82d8ec7364cbace851df591c2d43bc76bcbe5c4543a7ddd1bf1", + "sha256:23e44937d7695c27c66a54d793dd4b45889a81b35c0751ba91040fe825ec59c4", + "sha256:29c4688ace466a365b85a51dcc5e3c853c1d283f293dfcc12f7a77e498f160d2", + "sha256:57214fa5430399dffd54f4be37b56fe22cedb2b98862550d43cc085fb698dc2c", + "sha256:577791f948d34d569acb2d1add5831731c59d5a0c50a6d9f629ae1cefd9ca4a0", + "sha256:6539314d84c4d36f28d73adc1b45e9f4ee2a89cdc7e5d2b0a6dbacba31906798", + "sha256:65867d63f0fd1b500fa343d7798fa64e9e681b594e0a07dc934c13e76ee28fb1", + "sha256:672b539db20fef6b03d6f7a14b5825d57c98e4026401fce838849f8de73fe4d4", + "sha256:6843db0343e12e3f52cc58430ad559d850a53684f5b352540ca3f1bc56df0731", + "sha256:7057613efefd36cacabbdbcef010e0a9c20a88fc07eb3e616019ea1692fa5df4", + "sha256:76ada88d62eb24de7051c5157a1a78fd853cca9b91c0713c2e973e4196271d0c", + "sha256:837398c2ec00228679513802e3744d1e8e3cb1204aa6ad408b6aff081e99a487", + "sha256:8662aabfeab00cea149a3d1c2999b0731e70c6b5bac596d95d13f643e76d3d4e", + "sha256:95e9094162fa712f18b4f60896e34b621df99147c2cee216cfa8f022294e8e9f", + "sha256:99cc66b33c418cd579c0f03b77b94263c305c389cb0c6972dac420f24b3bf123", + "sha256:9b219511d8b64d3fa14261963933be34028ea0e57455baf6781fe399c2c3206c", + "sha256:ae8f34d50af2c2154035984b8b5fc5d9ed63f32fe615646ab435b05b132ca91b", + "sha256:b9aa9d8818c2e917fa2c105ad538e222a5bce59777133840b93134022a7ce650", + "sha256:bf44a9a0141a082e89c90e8d785b212a872db793a0080c20f6ae6e2a0ebf82ad", + "sha256:c0b48b98d79cf795b0916c57bebbc6d16bb43b9fc9b8c9f57f4cf05881904c75", + "sha256:da9d3c506f43e220336433dffe643fbfa40096d408cb9b7f2477892f369d5f82", + "sha256:e4082d832e36e7f9b2278bc774886ca8207346b99f278e54c9de4834f17232f7", + "sha256:e4b9b7af398c32e408c00eb4e0d33ced2f9121fd9fb978e6c1b57edd014a7d15", + "sha256:e613514a82539fc48291d01933951a13ae93b6b444a88782480be32245ed4afa", + "sha256:f5033952def24172e60493b68717792e3aebb387a8d186c43c020d9363ee7281" + ], + "index": "pypi", + "version": "==1.14.2" + }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", @@ -104,10 +136,10 @@ }, "emoji": { "hashes": [ - "sha256:60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174" + "sha256:e42da4f8d648f8ef10691bc246f682a1ec6b18373abfd9be10ec0b398823bd11" ], "index": "pypi", - "version": "==0.5.4" + "version": "==0.6.0" }, "filelock": { "hashes": [ @@ -121,7 +153,6 @@ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, "importlib-metadata": { @@ -142,12 +173,10 @@ }, "motor": { "hashes": [ - "sha256:599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", - "sha256:756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", - "sha256:97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a" + "sha256:659ad13c2e2dca19807fbb6d2bb62e4c60f99bb0d43110a6abb8fdd12b644a64" ], "index": "pypi", - "version": "==2.1.0" + "version": "==2.2.0" }, "multidict": { "hashes": [ @@ -169,7 +198,6 @@ "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" ], - "markers": "python_version >= '3.5'", "version": "==4.7.6" }, "natural": { @@ -189,72 +217,98 @@ }, "pipenv": { "hashes": [ - "sha256:7dd49a7345fa5da7843907bab42a996dece474e45dd309dbd7619739dc60478b", - "sha256:cc289dc78feaa14def4e1723b0b4d85ff628c8e5f740eeeb68197b90dafa8dff" + "sha256:448ac3a36443db633d52a2359cac15ecbc4f429eab4ddd420697602b721d1c5a", + "sha256:eff0e10eadb330f612edfa5051d3d8e775e9e0e918c3c50361da703bd0daa035" ], "index": "pypi", - "version": "==2020.6.2" + "version": "==2020.8.13" + }, + "pycparser": { + "hashes": [ + "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", + "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" + ], + "version": "==2.20" }, "pymongo": { "hashes": [ - "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", - "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", - "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", - "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", - "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", - "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", - "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", - "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", - "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", - "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", - "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", - "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", - "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", - "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", - "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", - "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", - "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", - "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", - "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", - "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", - "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", - "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", - "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", - "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", - "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", - "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", - "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", - "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", - "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", - "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", - "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", - "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", - "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", - "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", - "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", - "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", - "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", - "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", - "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", - "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", - "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", - "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", - "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", - "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", - "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", - "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", - "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", - "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", - "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", - "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", - "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", - "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", - "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", - "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", - "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", - "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606" - ], - "version": "==3.10.1" + "sha256:03dc64a9aa7a5d405aea5c56db95835f6a2fa31b3502c5af1760e0e99210be30", + "sha256:05fcc6f9c60e6efe5219fbb5a30258adb3d3e5cbd317068f3d73c09727f2abb6", + "sha256:076a7f2f7c251635cf6116ac8e45eefac77758ee5a77ab7bd2f63999e957613b", + "sha256:137e6fa718c7eff270dbd2fc4b90d94b1a69c9e9eb3f3de9e850a7fd33c822dc", + "sha256:1f865b1d1c191d785106f54df9abdc7d2f45a946b45fd1ea0a641b4f982a2a77", + "sha256:213c445fe7e654621c6309e874627c35354b46ef3ee807f5a1927dc4b30e1a67", + "sha256:25e617daf47d8dfd4e152c880cd0741cbdb48e51f54b8de9ddbfe74ecd87dd16", + "sha256:3d9bb1ba935a90ec4809a8031efd988bdb13cdba05d9e9a3e9bf151bf759ecde", + "sha256:40696a9a53faa7d85aaa6fd7bef1cae08f7882640bad08c350fb59dee7ad069b", + "sha256:421aa1b92c291c429668bd8d8d8ec2bd00f183483a756928e3afbf2b6f941f00", + "sha256:4437300eb3a5e9cc1a73b07d22c77302f872f339caca97e9bf8cf45eca8fa0d2", + "sha256:455f4deb00158d5ec8b1d3092df6abb681b225774ab8a59b3510293b4c8530e3", + "sha256:475a34a0745c456ceffaec4ce86b7e0983478f1b6140890dff7b161e7bcd895b", + "sha256:4797c0080f41eba90404335e5ded3aa66731d303293a675ff097ce4ea3025bb9", + "sha256:4ae23fbbe9eadf61279a26eba866bbf161a6f7e2ffad14a42cf20e9cb8e94166", + "sha256:4b32744901ee9990aa8cd488ec85634f443526def1e5190a407dc107148249d7", + "sha256:50127b13b38e8e586d5e97d342689405edbd74ad0bd891d97ee126a8c7b6e45f", + "sha256:50531caa7b4be1c4ed5e2d5793a4e51cc9bd62a919a6fd3299ef7c902e206eab", + "sha256:68220b81850de8e966d4667d5c325a96c6ac0d6adb3d18935d6e3d325d441f48", + "sha256:689142dc0c150e9cb7c012d84cac2c346d40beb891323afb6caf18ec4caafae0", + "sha256:6a15e2bee5c4188369a87ed6f02de804651152634a46cca91966a11c8abd2550", + "sha256:7122ffe597b531fb065d3314e704a6fe152b81820ca5f38543e70ffcc95ecfd4", + "sha256:7307024b18266b302f4265da84bb1effb5d18999ef35b30d17592959568d5c0a", + "sha256:7a4a6f5b818988a3917ec4baa91d1143242bdfece8d38305020463955961266a", + "sha256:83c5a3ecd96a9f3f11cfe6dfcbcec7323265340eb24cc996acaecea129865a3a", + "sha256:890b0f1e18dbd898aeb0ab9eae1ab159c6bcbe87f0abb065b0044581d8614062", + "sha256:8deda1f7b4c03242f2a8037706d9584e703f3d8c74d6d9cac5833db36fe16c42", + "sha256:8ea13d0348b4c96b437d944d7068d59ed4a6c98aaa6c40d8537a2981313f1c66", + "sha256:91e96bf85b7c07c827d339a386e8a3cf2e90ef098c42595227f729922d0851df", + "sha256:96782ebb3c9e91e174c333208b272ea144ed2a684413afb1038e3b3342230d72", + "sha256:9755c726aa6788f076114dfdc03b92b03ff8860316cca00902cce88bcdb5fedd", + "sha256:9dbab90c348c512e03f146e93a5e2610acec76df391043ecd46b6b775d5397e6", + "sha256:9ee0eef254e340cc11c379f797af3977992a7f2c176f1a658740c94bf677e13c", + "sha256:9fc17fdac8f1973850d42e51e8ba6149d93b1993ed6768a24f352f926dd3d587", + "sha256:a2787319dc69854acdfd6452e6a8ba8f929aeb20843c7f090e04159fc18e6245", + "sha256:b7c522292407fa04d8195032493aac937e253ad9ae524aab43b9d9d242571f03", + "sha256:bd312794f51e37dcf77f013d40650fe4fbb211dd55ef2863839c37480bd44369", + "sha256:c0d660a186e36c526366edf8a64391874fe53cf8b7039224137aee0163c046df", + "sha256:c4869141e20769b65d2d72686e7a7eb141ce9f3168106bed3e7dcced54eb2422", + "sha256:cc4057f692ac35bbe82a0a908d42ce3a281c9e913290fac37d7fa3bd01307dfb", + "sha256:cccf1e7806f12300e3a3b48f219e111000c2538483e85c869c35c1ae591e6ce9", + "sha256:ce208f80f398522e49d9db789065c8ad2cd37b21bd6b23d30053474b7416af11", + "sha256:d0565481dc196986c484a7fb13214fc6402201f7fb55c65fd215b3324962fe6c", + "sha256:d1b3366329c45a474b3bbc9b9c95d4c686e03f35da7fd12bc144626d1f2a7c04", + "sha256:d226e0d4b9192d95079a9a29c04dd81816b1ce8903b8c174a39224fe978547cb", + "sha256:d38b35f6eef4237b1d0d8e845fc1546dad85c55eba447e28c211da8c7ef9697c", + "sha256:d64c98277ea80e4484f1332ab107e8dfd173a7dcf1bdbf10a9cccc97aaab145f", + "sha256:d9de8427a5601799784eb0e7fa1b031aa64086ce04de29df775a8ca37eedac41", + "sha256:e6a15cf8f887d9f578dd49c6fb3a99d53e1d922fdd67a245a67488d77bf56eb2", + "sha256:e8c446882cbb3774cd78c738c9f58220606b702b7c1655f1423357dc51674054", + "sha256:e8d188ee39bd0ffe76603da887706e4e7b471f613625899ddf1e27867dc6a0d3", + "sha256:ef76535776c0708a85258f6dc51d36a2df12633c735f6d197ed7dfcaa7449b99", + "sha256:f6efca006a81e1197b925a7d7b16b8f61980697bb6746587aad8842865233218" + ], + "version": "==3.11.0" + }, + "pynacl": { + "hashes": [ + "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4", + "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4", + "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574", + "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d", + "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25", + "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f", + "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505", + "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122", + "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7", + "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420", + "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f", + "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96", + "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6", + "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514", + "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff", + "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80" + ], + "index": "pypi", + "version": "==1.4.0" }, "python-dateutil": { "hashes": [ @@ -277,9 +331,17 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, + "typing-extensions": { + "hashes": [ + "sha256:6e95524d8a547a91e08f404ae485bbb71962de46967e1b71a0cb89af24e761c5", + "sha256:79ee589a3caca649a9bfd2a8de4709837400dfa00b6cc81962a1e6a1815969ae", + "sha256:f8d2bd89d25bc39dabe7d23df520442fa1d8969b82544370e03d88b5a591c392" + ], + "markers": "python_version < '3.8'", + "version": "==3.7.4.2" + }, "uvloop": { "hashes": [ "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", @@ -298,18 +360,16 @@ }, "virtualenv": { "hashes": [ - "sha256:c11a475400e98450403c0364eb3a2d25d42f71cf1493da64390487b666de4324", - "sha256:e10cc66f40cbda459720dfe1d334c4dc15add0d80f09108224f171006a97a172" + "sha256:43add625c53c596d38f971a465553f6318decc39d98512bc100fa1b1e839c8dc", + "sha256:e0305af10299a7fb0d69393d8f04cb2965dda9351140d11ac8db4e5e3970451b" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.0.26" + "version": "==20.0.31" }, "virtualenv-clone": { "hashes": [ "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.5.4" }, "websockets": { @@ -337,38 +397,35 @@ "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" ], - "markers": "python_full_version >= '3.6.1'", "version": "==8.1" }, "yarl": { "hashes": [ - "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", - "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", - "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", - "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", - "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", - "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", - "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", - "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", - "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", - "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", - "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", - "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", - "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", - "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", - "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", - "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", - "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2" - ], - "markers": "python_version >= '3.5'", - "version": "==1.4.2" + "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", + "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593", + "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2", + "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8", + "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d", + "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692", + "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02", + "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a", + "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8", + "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6", + "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511", + "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e", + "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a", + "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb", + "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f", + "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", + "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" + ], + "version": "==1.5.1" }, "zipp": { "hashes": [ "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" ], - "markers": "python_version >= '3.6'", "version": "==3.1.0" } }, @@ -385,16 +442,14 @@ "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" ], - "markers": "python_version >= '3.5'", "version": "==2.4.2" }, "attrs": { "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a", + "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==19.3.0" + "version": "==20.1.0" }, "bandit": { "hashes": [ @@ -417,32 +472,44 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, + "colorama": { + "hashes": [ + "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", + "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1" + ], + "index": "pypi", + "version": "==0.4.3" + }, "gitdb": { "hashes": [ "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], - "markers": "python_version >= '3.4'", "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a", - "sha256:ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac" + "sha256:2db287d71a284e22e5c2846042d0602465c7434d910406990d5b74df4afb0858", + "sha256:fa3b92da728a457dd75d62bb5f3eb2816d99a7fe6c67398e260637a40e3fafb5" + ], + "version": "==3.1.7" + }, + "importlib-metadata": { + "hashes": [ + "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83", + "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070" ], - "markers": "python_version >= '3.4'", - "version": "==3.1.3" + "markers": "python_version < '3.8'", + "version": "==1.7.0" }, "isort": { "hashes": [ - "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", - "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + "sha256:60a1b97e33f61243d12647aaaa3e6cc6778f5eb9f42997650f1cc975b6008750", + "sha256:d488ba1c5a2db721669cc180180d5acf84ebdc5af7827f7aaeaa75f73cf0e2b8" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.3.21" + "version": "==5.4.2" }, "lazy-object-proxy": { "hashes": [ @@ -468,7 +535,6 @@ "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.3" }, "mccabe": { @@ -494,11 +560,11 @@ }, "pylint": { "hashes": [ - "sha256:7dd78437f2d8d019717dbf287772d0b2dbdfd13fc016aa7faa08d67bccc46adc", - "sha256:d0ece7d223fe422088b0e8f13fa0a1e8eb745ebffcb8ed53d3e95394b6101a1c" + "sha256:bb4a908c9dadbc3aac18860550e870f58e1a02c9f2c204fdf5693d73be061210", + "sha256:bfe68f020f8a0fece830a22dd4d5dddb4ecc6137db04face4c3420a46a52239f" ], "index": "pypi", - "version": "==2.5.3" + "version": "==2.6.0" }, "pyyaml": { "hashes": [ @@ -518,36 +584,35 @@ }, "regex": { "hashes": [ - "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a", - "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938", - "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29", - "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae", - "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387", - "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a", - "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf", - "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610", - "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9", - "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5", - "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3", - "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89", - "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded", - "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754", - "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f", - "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868", - "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd", - "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910", - "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3", - "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac", - "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c" - ], - "version": "==2020.6.8" + "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204", + "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162", + "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f", + "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb", + "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6", + "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7", + "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88", + "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99", + "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644", + "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a", + "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840", + "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067", + "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd", + "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4", + "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e", + "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89", + "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e", + "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc", + "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf", + "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341", + "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7" + ], + "version": "==2020.7.14" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "smmap": { @@ -555,16 +620,14 @@ "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.0.4" }, "stevedore": { "hashes": [ - "sha256:609912b87df5ad338ff8e44d13eaad4f4170a65b79ae9cb0aa5632598994a1b7", - "sha256:c4724f8d7b8f6be42130663855d01a9c2414d6046055b5a65ab58a0e38637688" + "sha256:38791aa5bed922b0a844513c5f9ed37774b68edc609e5ab8ab8d8fe0ce4315e5", + "sha256:c8f4f0ebbc394e52ddf49de8bcc3cf8ad2b4425ebac494106bbc5e3661ac7633" ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" + "version": "==3.2.0" }, "toml": { "hashes": [ @@ -597,7 +660,7 @@ "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" ], - "markers": "python_version < '3.8' and implementation_name == 'cpython'", + "markers": "implementation_name == 'cpython' and python_version < '3.8'", "version": "==1.4.1" }, "wrapt": { @@ -605,6 +668,13 @@ "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" ], "version": "==1.12.1" + }, + "zipp": { + "hashes": [ + "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", + "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" + ], + "version": "==3.1.0" } } } From 53ae48c69d7a4d65dc1e3777ef5b57859346b1bf Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 21 Aug 2020 23:25:59 +0800 Subject: [PATCH 065/705] Deps --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 423adc28cf..050dcb9387 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.8 \ No newline at end of file +python-3.7.9 \ No newline at end of file From e88c5755b1b614658924bb557c345a955d17c7d0 Mon Sep 17 00:00:00 2001 From: Vincysuper07 <52707876+Vincysuper07@users.noreply.github.com> Date: Sun, 30 Aug 2020 09:01:40 +0200 Subject: [PATCH 066/705] Add a "no command description" in the help command. --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index bd04bd6a09..b5be17fe6d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -47,7 +47,7 @@ async def format_cog_help(self, cog, *, no_cog=False): else: format_ = f"`[{perm_level}] {prefix + cmd.qualified_name}` " - format_ += f"- {cmd.short_doc}\n" + format_ += f"- {cmd.short_doc}\n" if not cmd.short_doc=="" else "- No description." if not format_.strip(): continue if len(format_) + len(formats[-1]) >= 1024: From 84adf5474c715466b6b7f2ef486f20e7c6465318 Mon Sep 17 00:00:00 2001 From: Vincysuper07 <52707876+Vincysuper07@users.noreply.github.com> Date: Sun, 30 Aug 2020 09:08:02 +0200 Subject: [PATCH 067/705] Reformatting... --- cogs/utility.py | 202 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 150 insertions(+), 52 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index b5be17fe6d..d2d78fb9ed 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -47,7 +47,11 @@ async def format_cog_help(self, cog, *, no_cog=False): else: format_ = f"`[{perm_level}] {prefix + cmd.qualified_name}` " - format_ += f"- {cmd.short_doc}\n" if not cmd.short_doc=="" else "- No description." + format_ += ( + f"- {cmd.short_doc}\n" + if not cmd.short_doc == "" + else "- No description." + ) if not format_.strip(): continue if len(format_) + len(formats[-1]) >= 1024: @@ -67,7 +71,11 @@ async def format_cog_help(self, cog, *, no_cog=False): embed.add_field(name="Commands", value=format_ or "No commands.") continued = " (Continued)" if embeds else "" - name = cog.qualified_name + " - Help" if not no_cog else "Miscellaneous Commands" + name = ( + cog.qualified_name + " - Help" + if not no_cog + else "Miscellaneous Commands" + ) embed.set_author(name=name + continued, icon_url=bot.user.avatar_url) embed.set_footer( @@ -88,7 +96,11 @@ async def send_bot_help(self, mapping): bot = self.context.bot # always come first - default_cogs = [bot.get_cog("Modmail"), bot.get_cog("Utility"), bot.get_cog("Plugins")] + default_cogs = [ + bot.get_cog("Modmail"), + bot.get_cog("Utility"), + bot.get_cog("Plugins"), + ] default_cogs.extend(c for c in cogs if c not in default_cogs) @@ -97,12 +109,16 @@ async def send_bot_help(self, mapping): if no_cog_commands: embeds.extend(await self.format_cog_help(no_cog_commands, no_cog=True)) - session = EmbedPaginatorSession(self.context, *embeds, destination=self.get_destination()) + session = EmbedPaginatorSession( + self.context, *embeds, destination=self.get_destination() + ) return await session.run() async def send_cog_help(self, cog): embeds = await self.format_cog_help(cog) - session = EmbedPaginatorSession(self.context, *embeds, destination=self.get_destination()) + session = EmbedPaginatorSession( + self.context, *embeds, destination=self.get_destination() + ) return await session.run() async def _get_help_embed(self, topic): @@ -183,7 +199,8 @@ async def send_error_message(self, error): else: if len(values) == 1: embed = discord.Embed( - title=f"{command} is an alias.", color=self.context.bot.main_color + title=f"{command} is an alias.", + color=self.context.bot.main_color, ) embed.add_field(name=f"`{command}` points to:", value=values[0]) else: @@ -214,7 +231,9 @@ async def send_error_message(self, error): closest = get_close_matches(command, choices) if closest: - embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) + embed.add_field( + name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest) + ) else: embed.title = "Cannot find command or category" embed.set_footer( @@ -307,11 +326,12 @@ async def about(self, ctx): if self.bot.version.is_prerelease: stable = next( - filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions) - ) - footer = ( - f"You are on the prerelease version • the latest version is v{stable.version}." + filter( + lambda v: not parse_version(v.version).is_prerelease, + changelog.versions, + ) ) + footer = f"You are on the prerelease version • the latest version is v{stable.version}." elif self.bot.version < parse_version(latest.version): footer = f"A newer version is available v{latest.version}." else: @@ -366,7 +386,8 @@ async def debug(self, ctx): with open( os.path.join( - os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" + os.path.dirname(os.path.abspath(__file__)), + f"../temp/{log_file_name}.log", ), "r+", ) as f: @@ -421,14 +442,17 @@ async def debug_hastebin(self, ctx): with open( os.path.join( - os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" + os.path.dirname(os.path.abspath(__file__)), + f"../temp/{log_file_name}.log", ), "rb+", ) as f: logs = BytesIO(f.read().strip()) try: - async with self.bot.session.post(haste_url + "/documents", data=logs) as resp: + async with self.bot.session.post( + haste_url + "/documents", data=logs + ) as resp: data = await resp.json() try: key = data["key"] @@ -459,7 +483,8 @@ async def debug_clear(self, ctx): with open( os.path.join( - os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" + os.path.dirname(os.path.abspath(__file__)), + f"../temp/{log_file_name}.log", ), "w", ): @@ -522,7 +547,9 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): else: msg += f"{activity.name}." - embed = discord.Embed(title="Activity Changed", description=msg, color=self.bot.main_color) + embed = discord.Embed( + title="Activity Changed", description=msg, color=self.bot.main_color + ) return await ctx.send(embed=embed) @commands.command() @@ -559,10 +586,14 @@ async def status(self, ctx, *, status_type: str.lower): await self.bot.config.update() msg = f"Status set to: {status.value}." - embed = discord.Embed(title="Status Changed", description=msg, color=self.bot.main_color) + embed = discord.Embed( + title="Status Changed", description=msg, color=self.bot.main_color + ) return await ctx.send(embed=embed) - async def set_presence(self, *, status=None, activity_type=None, activity_message=None): + async def set_presence( + self, *, status=None, activity_type=None, activity_message=None + ): if status is None: status = self.bot.config.get("status") @@ -571,7 +602,9 @@ async def set_presence(self, *, status=None, activity_type=None, activity_messag activity_type = self.bot.config.get("activity_type") url = None - activity_message = (activity_message or self.bot.config["activity_message"]).strip() + activity_message = ( + activity_message or self.bot.config["activity_message"] + ).strip() if activity_type is not None and not activity_message: logger.warning( 'No activity message found whilst activity is provided, defaults to "Modmail".' @@ -587,7 +620,9 @@ async def set_presence(self, *, status=None, activity_type=None, activity_messag url = self.bot.config["twitch_url"] if activity_type is not None: - activity = discord.Activity(type=activity_type, name=activity_message, url=url) + activity = discord.Activity( + type=activity_type, name=activity_message, url=url + ) else: activity = None await self.bot.change_presence(activity=activity, status=status) @@ -649,7 +684,9 @@ async def mention(self, ctx, *, mention: str = None): if mention is None: embed = discord.Embed( - title="Current mention:", color=self.bot.main_color, description=str(current) + title="Current mention:", + color=self.bot.main_color, + description=str(current), ) else: embed = discord.Embed( @@ -744,7 +781,9 @@ async def config_set(self, ctx, key: str.lower, *, value: str): embed = exc.embed else: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." + title="Error", + color=self.bot.error_color, + description=f"{key} is an invalid key.", ) valid_keys = [f"`{k}`" for k in sorted(keys)] embed.add_field(name="Valid keys", value=", ".join(valid_keys)) @@ -766,7 +805,9 @@ async def config_remove(self, ctx, *, key: str.lower): ) else: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." + title="Error", + color=self.bot.error_color, + description=f"{key} is an invalid key.", ) valid_keys = [f"`{k}`" for k in sorted(keys)] embed.add_field(name="Valid keys", value=", ".join(valid_keys)) @@ -787,7 +828,9 @@ async def config_get(self, ctx, *, key: str.lower = None): if key in keys: desc = f"`{key}` is set to `{self.bot.config[key]}`" embed = discord.Embed(color=self.bot.main_color, description=desc) - embed.set_author(name="Config variable", icon_url=self.bot.user.avatar_url) + embed.set_author( + name="Config variable", icon_url=self.bot.user.avatar_url + ) else: embed = discord.Embed( @@ -804,7 +847,9 @@ async def config_get(self, ctx, *, key: str.lower = None): color=self.bot.main_color, description="Here is a list of currently set configuration variable(s).", ) - embed.set_author(name="Current config(s):", icon_url=self.bot.user.avatar_url) + embed.set_author( + name="Current config(s):", icon_url=self.bot.user.avatar_url + ) config = self.bot.config.filter_default(self.bot.config) for name, value in config.items(): @@ -832,7 +877,8 @@ async def config_help(self, ctx, key: str.lower = None): ) if closest: embed.add_field( - name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest) + name=f"Perhaps you meant:", + value="\n".join(f"`{x}`" for x in closest), ) return await ctx.send(embed=embed) @@ -855,10 +901,13 @@ def fmt(val): if current_key == key: index = i embed = discord.Embed( - title=f"Configuration description on {current_key}:", color=self.bot.main_color + title=f"Configuration description on {current_key}:", + color=self.bot.main_color, ) embed.add_field(name="Default:", value=fmt(info["default"]), inline=False) - embed.add_field(name="Information:", value=fmt(info["description"]), inline=False) + embed.add_field( + name="Information:", value=fmt(info["description"]), inline=False + ) if info["examples"]: example_text = "" for example in info["examples"]: @@ -907,7 +956,9 @@ async def alias(self, ctx, *, name: str.lower = None): if name is not None: val = self.bot.aliases.get(name) if val is None: - embed = utils.create_not_found_embed(name, self.bot.aliases.keys(), "Alias") + embed = utils.create_not_found_embed( + name, self.bot.aliases.keys(), "Alias" + ) return await ctx.send(embed=embed) values = utils.parse_alias(val) @@ -919,14 +970,18 @@ async def alias(self, ctx, *, name: str.lower = None): description=f"Alias `{name}` is invalid, this alias will now be deleted." "This alias will now be deleted.", ) - embed.add_field(name=f"{name}` used to be:", value=utils.truncate(val, 1024)) + embed.add_field( + name=f"{name}` used to be:", value=utils.truncate(val, 1024) + ) self.bot.aliases.pop(name) await self.bot.config.update() return await ctx.send(embed=embed) if len(values) == 1: embed = discord.Embed( - title=f'Alias - "{name}":', description=values[0], color=self.bot.main_color + title=f'Alias - "{name}":', + description=values[0], + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -944,9 +999,12 @@ async def alias(self, ctx, *, name: str.lower = None): if not self.bot.aliases: embed = discord.Embed( - color=self.bot.error_color, description="You dont have any aliases at the moment." + color=self.bot.error_color, + description="You dont have any aliases at the moment.", + ) + embed.set_footer( + text=f'Do "{self.bot.prefix}help alias" for more commands.' ) - embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') embed.set_author(name="Aliases", icon_url=ctx.guild.icon_url) return await ctx.send(embed=embed) @@ -974,7 +1032,9 @@ async def alias_raw(self, ctx, *, name: str.lower): val = utils.truncate(utils.escape_code_block(val), 2048 - 7) embed = discord.Embed( - title=f'Raw alias - "{name}":', description=f"```\n{val}```", color=self.bot.main_color + title=f'Raw alias - "{name}":', + description=f"```\n{val}```", + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -992,7 +1052,9 @@ async def make_alias(self, name, value, action): if len(values) > 25: embed = discord.Embed( - title="Error", description="Too many steps, max=25.", color=self.bot.error_color + title="Error", + description="Too many steps, max=25.", + color=self.bot.error_color, ) return embed @@ -1003,7 +1065,9 @@ async def make_alias(self, name, value, action): embed = discord.Embed(title=f"{action} alias", color=self.bot.main_color) if not multiple_alias: - embed.add_field(name=f"`{name}` points to:", value=utils.truncate(values[0], 1024)) + embed.add_field( + name=f"`{name}` points to:", value=utils.truncate(values[0], 1024) + ) else: embed.description = f"`{name}` now points to the following steps:" @@ -1176,7 +1240,9 @@ def _parse_level(name): @permissions.command(name="override") @checks.has_permissions(PermissionLevel.OWNER) - async def permissions_override(self, ctx, command_name: str.lower, *, level_name: str): + async def permissions_override( + self, ctx, command_name: str.lower, *, level_name: str + ): """ Change a permission level for a specific command. @@ -1215,7 +1281,9 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name command.qualified_name, level.name, ) - self.bot.config["override_command_level"][command.qualified_name] = level.name + self.bot.config["override_command_level"][ + command.qualified_name + ] = level.name await self.bot.config.update() embed = discord.Embed( @@ -1287,7 +1355,9 @@ async def permissions_add( key = self.bot.modmail_guild.get_member(value) if key is not None: logger.info("Granting %s access to Modmail category.", key.name) - await self.bot.main_category.set_permissions(key, read_messages=True) + await self.bot.main_category.set_permissions( + key, read_messages=True + ) embed = discord.Embed( title="Success", @@ -1384,13 +1454,21 @@ async def permissions_remove( self.bot.modmail_guild.default_role, read_messages=False ) elif isinstance(user_or_role, discord.Role): - logger.info("Denying %s access to Modmail category.", user_or_role.name) - await self.bot.main_category.set_permissions(user_or_role, overwrite=None) + logger.info( + "Denying %s access to Modmail category.", user_or_role.name + ) + await self.bot.main_category.set_permissions( + user_or_role, overwrite=None + ) else: member = self.bot.modmail_guild.get_member(value) if member is not None and member != self.bot.modmail_guild.me: - logger.info("Denying %s access to Modmail category.", member.name) - await self.bot.main_category.set_permissions(member, overwrite=None) + logger.info( + "Denying %s access to Modmail category.", member.name + ) + await self.bot.main_category.set_permissions( + member, overwrite=None + ) embed = discord.Embed( title="Success", @@ -1440,7 +1518,11 @@ def _get_perm(self, ctx, name, type_): @permissions.command(name="get", usage="[@user] or [command/level/override] [name]") @checks.has_permissions(PermissionLevel.OWNER) async def permissions_get( - self, ctx, user_or_role: Union[discord.Role, utils.User, str], *, name: str = None + self, + ctx, + user_or_role: Union[discord.Role, utils.User, str], + *, + name: str = None, ): """ View the currently-set permissions. @@ -1490,7 +1572,9 @@ async def permissions_get( if value in permissions: levels.append(level.name) - mention = getattr(user_or_role, "name", getattr(user_or_role, "id", user_or_role)) + mention = getattr( + user_or_role, "name", getattr(user_or_role, "id", user_or_role) + ) desc_cmd = ( ", ".join(map(lambda x: f"`{x}`", cmds)) if cmds @@ -1540,10 +1624,14 @@ async def permissions_get( ) ) else: - for items in zip_longest(*(iter(sorted(overrides.items())),) * 15): + for items in zip_longest( + *(iter(sorted(overrides.items())),) * 15 + ): description = "\n".join( ": ".join((f"`{name}`", level)) - for name, level in takewhile(lambda x: x is not None, items) + for name, level in takewhile( + lambda x: x is not None, items + ) ) embed = discord.Embed( color=self.bot.main_color, description=description @@ -1599,7 +1687,9 @@ async def permissions_get( return await ctx.send(embed=embed) if user_or_role == "command": - embeds.append(self._get_perm(ctx, command.qualified_name, "command")) + embeds.append( + self._get_perm(ctx, command.qualified_name, "command") + ) else: embeds.append(self._get_perm(ctx, level.name, "level")) else: @@ -1608,7 +1698,9 @@ async def permissions_get( for command in self.bot.walk_commands(): if command not in done: done.add(command) - embeds.append(self._get_perm(ctx, command.qualified_name, "command")) + embeds.append( + self._get_perm(ctx, command.qualified_name, "command") + ) else: for perm_level in PermissionLevel: embeds.append(self._get_perm(ctx, perm_level.name, "level")) @@ -1650,7 +1742,9 @@ async def oauth_whitelist(self, ctx, target: Union[discord.Role, utils.User]): embed.title = "Success" if not hasattr(target, "mention"): - target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role(target.id) + target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role( + target.id + ) embed.description = ( f"{'Un-w' if removed else 'W'}hitelisted {target.mention} to view logs." @@ -1678,8 +1772,12 @@ async def oauth_show(self, ctx): embed = discord.Embed(color=self.bot.main_color) embed.title = "Oauth Whitelist" - embed.add_field(name="Users", value=" ".join(u.mention for u in users) or "None") - embed.add_field(name="Roles", value=" ".join(r.mention for r in roles) or "None") + embed.add_field( + name="Users", value=" ".join(u.mention for u in users) or "None" + ) + embed.add_field( + name="Roles", value=" ".join(r.mention for r in roles) or "None" + ) await ctx.send(embed=embed) From ca02cb12b9fd9f81ccb1cc85e303eeccb7786426 Mon Sep 17 00:00:00 2001 From: Vincysuper07 <52707876+Vincysuper07@users.noreply.github.com> Date: Sun, 20 Sep 2020 09:09:45 +0200 Subject: [PATCH 068/705] Fix missing new line. --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index d2d78fb9ed..c4480985c3 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -50,7 +50,7 @@ async def format_cog_help(self, cog, *, no_cog=False): format_ += ( f"- {cmd.short_doc}\n" if not cmd.short_doc == "" - else "- No description." + else "- No description.\n" ) if not format_.strip(): continue From 9030155a1fa5dbe21ef68e1861a871f071b29e80 Mon Sep 17 00:00:00 2001 From: Forcellrus Date: Tue, 29 Sep 2020 12:21:13 +0200 Subject: [PATCH 069/705] Add MODMAIL_GUILD_ID variable in example This variable was missing from the env example file for quite some time now. --- .env.example | 1 + 1 file changed, 1 insertion(+) diff --git a/.env.example b/.env.example index 14bdf060bf..44c91c59c7 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ TOKEN=MyBotToken LOG_URL=https://logviewername.herokuapp.com/ GUILD_ID=1234567890 +MODMAIL_GUILD_ID=1234567890 OWNERS=Owner1ID,Owner2ID,Owner3ID CONNECTION_URI=mongodb+srv://mongodburi From b5fba82f8399f94945c61ad21396d08c892eedca Mon Sep 17 00:00:00 2001 From: Robin Mahieu <42642013+robinmahieu@users.noreply.github.com> Date: Sun, 4 Oct 2020 14:41:02 +0200 Subject: [PATCH 070/705] Remove plugins from Papier (#2858) --- plugins/registry.json | 45 ------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 5a12d84191..4a79456010 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -26,15 +26,6 @@ "icon_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png", "thumbnail_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png" }, - "autorole": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "Easily auto-assign a role to a user when they join your server.", - "bot_version": "2.20.1", - "title": "Autorole Plugin", - "icon_url": "https://i.imgur.com/67bEi82.png", - "thumbnail_url": "https://i.imgur.com/67bEi82.png" - }, "anti-steal-close": { "repository": "officialpiyush/modmail-plugins", "branch": "master", @@ -43,42 +34,6 @@ "icon_url": "https://i.imgur.com/LovxyV3.png", "thumbnail_url": "https://i.imgur.com/LovxyV3.png" }, - "embedder": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "Easily make embeds for a nicer presence.", - "bot_version": "2.20.1", - "title": "Embedder Plugin", - "icon_url": "https://i.imgur.com/l3uzJwD.png", - "thumbnail_url": "https://i.imgur.com/l3uzJwD.png" - }, - "leveling": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "A leveling system for your server: see who's active and who's not.", - "bot_version": "2.20.1", - "title": "Leveling Plugin", - "icon_url": "https://i.imgur.com/VuZ60QX.png", - "thumbnail_url": "https://i.imgur.com/VuZ60QX.png" - }, - "purger": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "Delete multiple messages at a time.", - "bot_version": "2.20.1", - "title": "Purger Plugin", - "icon_url": "https://i.imgur.com/HnC42jM.png", - "thumbnail_url": "https://i.imgur.com/HnC42jM.png" - }, - "supporters": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "Let your users know who is part of the support team.", - "bot_version": "2.20.1", - "title": "Supporters Plugin", - "icon_url": "https://i.imgur.com/1QXRutA.png", - "thumbnail_url": "https://i.imgur.com/1QXRutA.png" - }, "announcement": { "repository": "officialpiyush/modmail-plugins", "branch": "master", From 2a55dc674798c15b73cb0769f0c713b98a1529eb Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 11 Oct 2020 04:24:27 +0200 Subject: [PATCH 071/705] Remove lorenzo sponsor message per request remove sponsor server, still am a sponsor --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 76c2a4f107..40cbd7b1e4 100644 --- a/README.md +++ b/README.md @@ -166,10 +166,6 @@ Special thanks to our sponsors for supporting the project. - - - - Become a sponsor on [Patreon](https://patreon.com/kyber). ## Plugins From 50c440f104eb5b89373822ed2fbed35bbac7ac40 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Sun, 11 Oct 2020 13:55:48 +0800 Subject: [PATCH 072/705] Update bot.py --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 9e48c0f342..daa62d0516 100644 --- a/bot.py +++ b/bot.py @@ -1214,7 +1214,7 @@ async def post_metadata(self): else: data.update({"owner_name": info.owner.name, "owner_id": info.owner.id, "team": False}) - async with self.session.post("https://api.logviewer.tech/metadata", json=data): + async with self.session.post("https://api.modmail.dev/metadata", json=data): logger.debug("Uploading metadata to Modmail server.") async def before_post_metadata(self): From eb80fed05e7a7e6fc6c6e59693bbb1a8e416a8a2 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:06:52 +0800 Subject: [PATCH 073/705] Fix errors on windows selfhost --- bot.py | 10 +++++++--- cogs/plugins.py | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index 9e48c0f342..976c01744f 100644 --- a/bot.py +++ b/bot.py @@ -89,9 +89,13 @@ def uptime(self) -> str: def startup(self): logger.line() - logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬") - logger.info("││││ │ │││││├─┤││") - logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") + if os.name != 'nt': + logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬") + logger.info("││││ │ │││││├─┤││") + logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") + else: + logger.info("MODMAIL") + logger.info("MODMAIL") logger.info("v%s", __version__) logger.info("Authors: kyb3r, fourjr, Taaku18") logger.line() diff --git a/cogs/plugins.py b/cogs/plugins.py index df8259736c..6203edab67 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -199,7 +199,7 @@ async def load_plugin(self, plugin): venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env user_install = " --user" if not venv else "" proc = await asyncio.create_subprocess_shell( - f"{sys.executable} -m pip install --upgrade{user_install} -r {req_txt} -q -q", + f"\"{sys.executable}\" -m pip install --upgrade{user_install} -r {req_txt} -q -q --user", stderr=PIPE, stdout=PIPE, ) @@ -497,7 +497,7 @@ async def plugins_reset(self, ctx): logger.warning("Removing %s.", entry.name) embed = discord.Embed( - description=f"Successfully purged all plugins from the bot.", color=self.bot.main_color + description="Successfully purged all plugins from the bot.", color=self.bot.main_color ) return await ctx.send(embed=embed) From 6f05aa8129d634d1c4616230d5f21d24ddcd83eb Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:23:12 +0800 Subject: [PATCH 074/705] Add avatar to closed thread messages, resolve #2828 --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 960dafe0f7..ffe9c212df 100644 --- a/core/thread.py +++ b/core/thread.py @@ -361,7 +361,7 @@ async def _close( event = "Thread Closed as Scheduled" if scheduled else "Thread Closed" # embed.set_author(name=f"Event: {event}", url=log_url) - embed.set_footer(text=f"{event} by {_closer}") + embed.set_footer(text=f"{event} by {_closer}", icon_url=closer.avatar_url) embed.timestamp = datetime.utcnow() tasks = [self.bot.config.update()] From 17e287c8579322531a6e5f6d0564a1970890fcf6 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:27:15 +0800 Subject: [PATCH 075/705] Add nsfw indicator to log messages, resolve #2792 --- core/thread.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index ffe9c212df..b300e9fbbc 100644 --- a/core/thread.py +++ b/core/thread.py @@ -316,6 +316,7 @@ async def _close( { "open": False, "closed_at": str(datetime.utcnow()), + "nsfw": self.channel.nsfw, "close_message": message if not silent else None, "closer": { "id": str(closer.id), @@ -338,8 +339,13 @@ async def _close( sneak_peak = content.replace("\n", "") else: sneak_peak = "No content" + + if self.channel.nsfw: + _nsfw = 'NSFW-' + else: + _nsfw = '' - desc = f"[`{log_data['key']}`]({log_url}): " + desc = f"[`{_nsfw}{log_data['key']}`]({log_url}): " desc += truncate(sneak_peak, max=75 - 13) else: desc = "Could not resolve log url." From d70fd49a3fc668eb278764296b6aa53cfd6c8d07 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:34:04 +0800 Subject: [PATCH 076/705] Add thread_move_title config --- core/config.py | 1 + core/config_help.json | 14 ++++++++++++-- core/thread.py | 4 ++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/config.py b/core/config.py index 4f54c2b29c..f2bb54a5c8 100644 --- a/core/config.py +++ b/core/config.py @@ -57,6 +57,7 @@ class ConfigManager: "thread_close_title": "Thread Closed", "thread_close_response": "{closer.mention} has closed this Modmail thread.", "thread_self_close_response": "You have closed this Modmail thread.", + "thread_move_title": "Thread Moved", "thread_move_notify": False, "thread_move_response": "This thread has been moved.", "disabled_new_thread_title": "Not Delivered", diff --git a/core/config_help.json b/core/config_help.json index db9218d2b3..9778f49f8c 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -350,6 +350,16 @@ "See also: `thread_close_title`, `thread_close_footer`, `thread_close_response`." ] }, + "thread_move_title": { + "default": "Thread Moved", + "description": "The title of the message embed when a thread is moved.", + "examples": [ + "`{prefix}config set thread_move_title Thread transferred to another channel!" + ], + "notes": [ + "See also: `thread_move_notify`, `thread_move_response`." + ] + }, "thread_move_notify": { "default": "No", "description": "Notify the recipient if the thread was moved.", @@ -358,7 +368,7 @@ "`{prefix}config set thread_move_notify no`" ], "notes": [ - "See also: `thread_move_response`." + "See also: `thread_move_title`, `thread_move_response`." ] }, "thread_move_response": { @@ -369,7 +379,7 @@ ], "notes": [ "Only has an effect when `thread_move_notify` is on.", - "See also: `thread_move_notify`." + "See also: `thread_move_title`, `thread_move_notify`." ] }, "disabled_new_thread_title": { diff --git a/core/thread.py b/core/thread.py index b300e9fbbc..23ab81ad0d 100644 --- a/core/thread.py +++ b/core/thread.py @@ -341,9 +341,9 @@ async def _close( sneak_peak = "No content" if self.channel.nsfw: - _nsfw = 'NSFW-' + _nsfw = "NSFW-" else: - _nsfw = '' + _nsfw = "" desc = f"[`{_nsfw}{log_data['key']}`]({log_url}): " desc += truncate(sneak_peak, max=75 - 13) From 1aa7dfc1d42c6b16565186e96b1b372f40295fa9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:39:26 +0800 Subject: [PATCH 077/705] Add thread_move_title config --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 9ec5d5604f..a8551410e4 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -305,7 +305,7 @@ async def move(self, ctx, category: discord.CategoryChannel, *, specifics: str = if self.bot.config["thread_move_notify"] and not silent: embed = discord.Embed( - title="Thread Moved", + title=self.bot.config["thread_move_title"], description=self.bot.config["thread_move_response"], color=self.bot.main_color, ) From a3edc421f083c15878547310fcb910789c1db827 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:51:10 +0800 Subject: [PATCH 078/705] Allow mention command to accept ids/names, resolve #2796 --- cogs/utility.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index bd04bd6a09..deca773af1 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -638,7 +638,7 @@ async def ping(self, ctx): @commands.command() @checks.has_permissions(PermissionLevel.ADMINISTRATOR) - async def mention(self, ctx, *, mention: str = None): + async def mention(self, ctx, *mention: Union[discord.Role, discord.Member]): """ Change what the bot mentions at the start of each thread. @@ -647,11 +647,12 @@ async def mention(self, ctx, *, mention: str = None): # TODO: ability to disable mention. current = self.bot.config["mention"] - if mention is None: + if not mention: embed = discord.Embed( title="Current mention:", color=self.bot.main_color, description=str(current) ) else: + mention = " ".join(i.mention for i in mention) embed = discord.Embed( title="Changed mention!", description=f'On thread creation the bot now says "{mention}".', From 1f846fa4cb16082985c15240b5767fe47399bee7 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:51:19 +0800 Subject: [PATCH 079/705] Formatting --- cogs/plugins.py | 2 +- core/thread.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index 6203edab67..835aad49a9 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -199,7 +199,7 @@ async def load_plugin(self, plugin): venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env user_install = " --user" if not venv else "" proc = await asyncio.create_subprocess_shell( - f"\"{sys.executable}\" -m pip install --upgrade{user_install} -r {req_txt} -q -q --user", + f'"{sys.executable}" -m pip install --upgrade{user_install} -r {req_txt} -q -q --user', stderr=PIPE, stdout=PIPE, ) diff --git a/core/thread.py b/core/thread.py index 23ab81ad0d..9c388389e0 100644 --- a/core/thread.py +++ b/core/thread.py @@ -339,7 +339,7 @@ async def _close( sneak_peak = content.replace("\n", "") else: sneak_peak = "No content" - + if self.channel.nsfw: _nsfw = "NSFW-" else: From 732de02a3c321842eeb17fdc7c54fdcbc0d0fef0 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:07:20 +0800 Subject: [PATCH 080/705] Change move command to consume for category --- cogs/modmail.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index a8551410e4..b7489688cc 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -284,22 +284,43 @@ async def snippet_edit(self, ctx, name: str.lower, *, value): embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") await ctx.send(embed=embed) - @commands.command() + @commands.command(usage=' [options]') @checks.has_permissions(PermissionLevel.MODERATOR) @checks.thread_only() - async def move(self, ctx, category: discord.CategoryChannel, *, specifics: str = None): + async def move(self, ctx, *, arguments): """ Move a thread to another category. `category` may be a category ID, mention, or name. - `specifics` is a string which takes in arguments on how to perform the move. Ex: "silently" + `options` is a string which takes in arguments on how to perform the move. Ex: "silently" """ + split_args = arguments.strip('"').split(' ') + + # manually parse arguments, consumes as much of args as possible for category + for i in range(len(split_args)): + try: + if i == 0: + fmt = arguments + else: + fmt = ' '.join(split_args[:-i]) + + category = await commands.CategoryChannelConverter().convert(ctx, fmt) + except commands.BadArgument: + if i == len(split_args) - 1: + # last one + raise + pass + else: + break + + options = ' '.join(arguments.split(' ')[-i:]) + thread = ctx.thread silent = False - if specifics: + if options: silent_words = ["silent", "silently"] - silent = any(word in silent_words for word in specifics.split()) + silent = any(word in silent_words for word in options.split()) await thread.channel.edit(category=category, sync_permissions=True) From 8efb4ba95015092b2a02da56ae161099976aff96 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:09:12 +0800 Subject: [PATCH 081/705] Use --diff in CI, resolve #2816 --- .github/workflows/lints.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index c84c9af773..52a538bef7 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -31,4 +31,4 @@ jobs: continue-on-error: true - name: Black and flake8 run: | - black . --check + black . --diff From 72e9522ce74343e48a4d39f4747a126bcdebaabd Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:09:48 +0800 Subject: [PATCH 082/705] Formatting --- cogs/modmail.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index b7489688cc..44f0e9dcde 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -284,7 +284,7 @@ async def snippet_edit(self, ctx, name: str.lower, *, value): embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") await ctx.send(embed=embed) - @commands.command(usage=' [options]') + @commands.command(usage=" [options]") @checks.has_permissions(PermissionLevel.MODERATOR) @checks.thread_only() async def move(self, ctx, *, arguments): @@ -294,7 +294,7 @@ async def move(self, ctx, *, arguments): `category` may be a category ID, mention, or name. `options` is a string which takes in arguments on how to perform the move. Ex: "silently" """ - split_args = arguments.strip('"').split(' ') + split_args = arguments.strip('"').split(" ") # manually parse arguments, consumes as much of args as possible for category for i in range(len(split_args)): @@ -302,7 +302,7 @@ async def move(self, ctx, *, arguments): if i == 0: fmt = arguments else: - fmt = ' '.join(split_args[:-i]) + fmt = " ".join(split_args[:-i]) category = await commands.CategoryChannelConverter().convert(ctx, fmt) except commands.BadArgument: @@ -313,7 +313,7 @@ async def move(self, ctx, *, arguments): else: break - options = ' '.join(arguments.split(' ')[-i:]) + options = " ".join(arguments.split(" ")[-i:]) thread = ctx.thread silent = False From fa3efa186fbd0184e5a7eb17bb14cedb49bb2f4b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:10:32 +0800 Subject: [PATCH 083/705] Bump discord.py to 1.5.1, intent explicit support --- Pipfile | 6 +- Pipfile.lock | 341 ++++++++++++++++++++++--------------------- bot.py | 7 +- pyproject.toml | 2 +- requirements.min.txt | 2 +- runtime.txt | 2 +- 6 files changed, 181 insertions(+), 179 deletions(-) diff --git a/Pipfile b/Pipfile index 0872abf3e2..d468866095 100644 --- a/Pipfile +++ b/Pipfile @@ -7,6 +7,7 @@ verify_ssl = true black = "==19.10b0" pylint = "*" bandit = "==1.6.2" +flake8 = "*" [packages] colorama = ">=0.4.0" @@ -21,12 +22,9 @@ parsedatetime = "==2.6" aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -"discord.py" = "==1.3.4" +"discord.py" = "==1.5.1" pynacl = "*" cffi = "*" -[requires] -python_version = "3.7" - [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 807d74cb97..682d7252b5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,12 +1,10 @@ { "_meta": { "hash": { - "sha256": "397b06fdc5c4560667c7d3b2b8323ffd6ac3961fc561a470ccf99d8a5c234ffb" + "sha256": "0dba33486b4cc030061af10a203dbf804d4984f09da44200d4a0a97c6ed924ce" }, "pipfile-spec": 6, - "requires": { - "python_version": "3.7" - }, + "requires": {}, "sources": [ { "name": "pypi", @@ -18,21 +16,22 @@ "default": { "aiohttp": { "hashes": [ - "sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", - "sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", - "sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", - "sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", - "sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", - "sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", - "sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", - "sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", - "sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", - "sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", - "sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", - "sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965" + "sha256:1a4160579ffbc1b69e88cb6ca8bb0fbd4947dfcbf9fb1e2a4fc4c7a4a986c1fe", + "sha256:206c0ccfcea46e1bddc91162449c20c72f308aebdcef4977420ef329c8fcc599", + "sha256:2ad493de47a8f926386fa6d256832de3095ba285f325db917c7deae0b54a9fc8", + "sha256:319b490a5e2beaf06891f6711856ea10591cfe84fe9f3e71a721aa8f20a0872a", + "sha256:470e4c90da36b601676fe50c49a60d34eb8c6593780930b1aa4eea6f508dfa37", + "sha256:60f4caa3b7f7a477f66ccdd158e06901e1d235d572283906276e3803f6b098f5", + "sha256:66d64486172b032db19ea8522328b19cfb78a3e1e5b62ab6a0567f93f073dea0", + "sha256:687461cd974722110d1763b45c5db4d2cdee8d50f57b00c43c7590d1dd77fc5c", + "sha256:698cd7bc3c7d1b82bb728bae835724a486a8c376647aec336aa21a60113c3645", + "sha256:797456399ffeef73172945708810f3277f794965eb6ec9bd3a0c007c0476be98", + "sha256:a885432d3cabc1287bcf88ea94e1826d3aec57fd5da4a586afae4591b061d40d", + "sha256:c506853ba52e516b264b106321c424d03f3ddef2813246432fa9d1cefd361c81", + "sha256:fb83326d8295e8840e4ba774edf346e87eca78ba8a89c55d2690352842c15ba5" ], "index": "pypi", - "version": "==3.6.2" + "version": "==3.6.3" }, "appdirs": { "hashes": [ @@ -46,14 +45,16 @@ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], + "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { "hashes": [ - "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a", - "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff" + "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", + "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" ], - "version": "==20.1.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.2.0" }, "certifi": { "hashes": [ @@ -64,37 +65,45 @@ }, "cffi": { "hashes": [ - "sha256:0da50dcbccd7cb7e6c741ab7912b2eff48e85af217d72b57f80ebc616257125e", - "sha256:12a453e03124069b6896107ee133ae3ab04c624bb10683e1ed1c1663df17c13c", - "sha256:15419020b0e812b40d96ec9d369b2bc8109cc3295eac6e013d3261343580cc7e", - "sha256:15a5f59a4808f82d8ec7364cbace851df591c2d43bc76bcbe5c4543a7ddd1bf1", - "sha256:23e44937d7695c27c66a54d793dd4b45889a81b35c0751ba91040fe825ec59c4", - "sha256:29c4688ace466a365b85a51dcc5e3c853c1d283f293dfcc12f7a77e498f160d2", - "sha256:57214fa5430399dffd54f4be37b56fe22cedb2b98862550d43cc085fb698dc2c", - "sha256:577791f948d34d569acb2d1add5831731c59d5a0c50a6d9f629ae1cefd9ca4a0", - "sha256:6539314d84c4d36f28d73adc1b45e9f4ee2a89cdc7e5d2b0a6dbacba31906798", - "sha256:65867d63f0fd1b500fa343d7798fa64e9e681b594e0a07dc934c13e76ee28fb1", - "sha256:672b539db20fef6b03d6f7a14b5825d57c98e4026401fce838849f8de73fe4d4", - "sha256:6843db0343e12e3f52cc58430ad559d850a53684f5b352540ca3f1bc56df0731", - "sha256:7057613efefd36cacabbdbcef010e0a9c20a88fc07eb3e616019ea1692fa5df4", - "sha256:76ada88d62eb24de7051c5157a1a78fd853cca9b91c0713c2e973e4196271d0c", - "sha256:837398c2ec00228679513802e3744d1e8e3cb1204aa6ad408b6aff081e99a487", - "sha256:8662aabfeab00cea149a3d1c2999b0731e70c6b5bac596d95d13f643e76d3d4e", - "sha256:95e9094162fa712f18b4f60896e34b621df99147c2cee216cfa8f022294e8e9f", - "sha256:99cc66b33c418cd579c0f03b77b94263c305c389cb0c6972dac420f24b3bf123", - "sha256:9b219511d8b64d3fa14261963933be34028ea0e57455baf6781fe399c2c3206c", - "sha256:ae8f34d50af2c2154035984b8b5fc5d9ed63f32fe615646ab435b05b132ca91b", - "sha256:b9aa9d8818c2e917fa2c105ad538e222a5bce59777133840b93134022a7ce650", - "sha256:bf44a9a0141a082e89c90e8d785b212a872db793a0080c20f6ae6e2a0ebf82ad", - "sha256:c0b48b98d79cf795b0916c57bebbc6d16bb43b9fc9b8c9f57f4cf05881904c75", - "sha256:da9d3c506f43e220336433dffe643fbfa40096d408cb9b7f2477892f369d5f82", - "sha256:e4082d832e36e7f9b2278bc774886ca8207346b99f278e54c9de4834f17232f7", - "sha256:e4b9b7af398c32e408c00eb4e0d33ced2f9121fd9fb978e6c1b57edd014a7d15", - "sha256:e613514a82539fc48291d01933951a13ae93b6b444a88782480be32245ed4afa", - "sha256:f5033952def24172e60493b68717792e3aebb387a8d186c43c020d9363ee7281" + "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d", + "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b", + "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4", + "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f", + "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3", + "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579", + "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537", + "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e", + "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05", + "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171", + "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca", + "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522", + "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c", + "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc", + "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d", + "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808", + "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828", + "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869", + "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d", + "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9", + "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0", + "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc", + "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15", + "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c", + "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a", + "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3", + "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1", + "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768", + "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d", + "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b", + "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e", + "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d", + "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730", + "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394", + "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1", + "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591" ], "index": "pypi", - "version": "==1.14.2" + "version": "==1.14.3" }, "chardet": { "hashes": [ @@ -105,19 +114,19 @@ }, "colorama": { "hashes": [ - "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", - "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1" + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], "index": "pypi", - "version": "==0.4.3" + "version": "==0.4.4" }, "discord.py": { "hashes": [ - "sha256:1b546a32c0cd83d949392a71e5b06e30e19d1067246e3826d32ae9b8b3d06c1e", - "sha256:8ef58d6fc1e66903bc00ae79c4c09a38aa71043e88a83da4d2e8b9b1c9f9b9e2" + "sha256:2367359e31f6527f8a936751fc20b09d7495dd6a76b28c8fb13d4ca6c55b7563", + "sha256:def00dc50cf36d21346d71bc89f0cad8f18f9a3522978dc18c7796287d47de8b" ], "index": "pypi", - "version": "==1.3.4" + "version": "==1.5.1" }, "distlib": { "hashes": [ @@ -153,16 +162,9 @@ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, - "importlib-metadata": { - "hashes": [ - "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83", - "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070" - ], - "markers": "python_version < '3.8'", - "version": "==1.7.0" - }, "isodate": { "hashes": [ "sha256:2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", @@ -173,10 +175,11 @@ }, "motor": { "hashes": [ - "sha256:659ad13c2e2dca19807fbb6d2bb62e4c60f99bb0d43110a6abb8fdd12b644a64" + "sha256:428d94750123d19fcd0a89b8671ff9b4656f205217bad9f44161748c64c5fc80", + "sha256:f1692b760d834707e3477996ce8d407af8cd61c1a2abedbf81c22ef14675e61a" ], "index": "pypi", - "version": "==2.2.0" + "version": "==2.3.0" }, "multidict": { "hashes": [ @@ -198,6 +201,7 @@ "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" ], + "markers": "python_version >= '3.5'", "version": "==4.7.6" }, "natural": { @@ -228,6 +232,7 @@ "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.20" }, "pymongo": { @@ -250,6 +255,7 @@ "sha256:4b32744901ee9990aa8cd488ec85634f443526def1e5190a407dc107148249d7", "sha256:50127b13b38e8e586d5e97d342689405edbd74ad0bd891d97ee126a8c7b6e45f", "sha256:50531caa7b4be1c4ed5e2d5793a4e51cc9bd62a919a6fd3299ef7c902e206eab", + "sha256:63a5387e496a98170ffe638b435c0832c0f2011a6f4ff7a2880f17669fff8c03", "sha256:68220b81850de8e966d4667d5c325a96c6ac0d6adb3d18935d6e3d325d441f48", "sha256:689142dc0c150e9cb7c012d84cac2c346d40beb891323afb6caf18ec4caafae0", "sha256:6a15e2bee5c4188369a87ed6f02de804651152634a46cca91966a11c8abd2550", @@ -286,6 +292,7 @@ "sha256:ef76535776c0708a85258f6dc51d36a2df12633c735f6d197ed7dfcaa7449b99", "sha256:f6efca006a81e1197b925a7d7b16b8f61980697bb6746587aad8842865233218" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.11.0" }, "pynacl": { @@ -294,6 +301,7 @@ "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4", "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574", "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d", + "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634", "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25", "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f", "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505", @@ -302,6 +310,7 @@ "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420", "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f", "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96", + "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6", "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6", "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514", "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff", @@ -331,17 +340,9 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, - "typing-extensions": { - "hashes": [ - "sha256:6e95524d8a547a91e08f404ae485bbb71962de46967e1b71a0cb89af24e761c5", - "sha256:79ee589a3caca649a9bfd2a8de4709837400dfa00b6cc81962a1e6a1815969ae", - "sha256:f8d2bd89d25bc39dabe7d23df520442fa1d8969b82544370e03d88b5a591c392" - ], - "markers": "python_version < '3.8'", - "version": "==3.7.4.2" - }, "uvloop": { "hashes": [ "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", @@ -354,51 +355,25 @@ "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362" ], - "index": "pypi", "markers": "sys_platform != 'win32'", "version": "==0.14.0" }, "virtualenv": { "hashes": [ - "sha256:43add625c53c596d38f971a465553f6318decc39d98512bc100fa1b1e839c8dc", - "sha256:e0305af10299a7fb0d69393d8f04cb2965dda9351140d11ac8db4e5e3970451b" + "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2", + "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380" ], - "version": "==20.0.31" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.1.0" }, "virtualenv-clone": { "hashes": [ "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.5.4" }, - "websockets": { - "hashes": [ - "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", - "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", - "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", - "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", - "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", - "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", - "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", - "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", - "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", - "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", - "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", - "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", - "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", - "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", - "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", - "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", - "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", - "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", - "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", - "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", - "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", - "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" - ], - "version": "==8.1" - }, "yarl": { "hashes": [ "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", @@ -419,14 +394,8 @@ "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" ], + "markers": "python_version >= '3.5'", "version": "==1.5.1" - }, - "zipp": { - "hashes": [ - "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", - "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" - ], - "version": "==3.1.0" } }, "develop": { @@ -442,14 +411,16 @@ "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" ], + "markers": "python_version >= '3.5'", "version": "==2.4.2" }, "attrs": { "hashes": [ - "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a", - "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff" + "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", + "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" ], - "version": "==20.1.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.2.0" }, "bandit": { "hashes": [ @@ -472,44 +443,48 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "colorama": { "hashes": [ - "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", - "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1" + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], "index": "pypi", - "version": "==0.4.3" + "version": "==0.4.4" + }, + "flake8": { + "hashes": [ + "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839", + "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b" + ], + "index": "pypi", + "version": "==3.8.4" }, "gitdb": { "hashes": [ "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], + "markers": "python_version >= '3.4'", "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:2db287d71a284e22e5c2846042d0602465c7434d910406990d5b74df4afb0858", - "sha256:fa3b92da728a457dd75d62bb5f3eb2816d99a7fe6c67398e260637a40e3fafb5" + "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b", + "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8" ], - "version": "==3.1.7" - }, - "importlib-metadata": { - "hashes": [ - "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83", - "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070" - ], - "markers": "python_version < '3.8'", - "version": "==1.7.0" + "markers": "python_version >= '3.4'", + "version": "==3.1.11" }, "isort": { "hashes": [ - "sha256:60a1b97e33f61243d12647aaaa3e6cc6778f5eb9f42997650f1cc975b6008750", - "sha256:d488ba1c5a2db721669cc180180d5acf84ebdc5af7827f7aaeaa75f73cf0e2b8" + "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7", + "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58" ], - "version": "==5.4.2" + "markers": "python_version >= '3.6' and python_version < '4.0'", + "version": "==5.6.4" }, "lazy-object-proxy": { "hashes": [ @@ -535,6 +510,7 @@ "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.3" }, "mccabe": { @@ -553,10 +529,27 @@ }, "pbr": { "hashes": [ - "sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c", - "sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8" + "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9", + "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00" ], - "version": "==5.4.5" + "markers": "python_version >= '2.6'", + "version": "==5.5.1" + }, + "pycodestyle": { + "hashes": [ + "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", + "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.6.0" + }, + "pyflakes": { + "hashes": [ + "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", + "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.2.0" }, "pylint": { "hashes": [ @@ -584,35 +577,42 @@ }, "regex": { "hashes": [ - "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204", - "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162", - "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f", - "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb", - "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6", - "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7", - "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88", - "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99", - "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644", - "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a", - "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840", - "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067", - "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd", - "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4", - "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e", - "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89", - "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e", - "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc", - "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf", - "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341", - "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7" - ], - "version": "==2020.7.14" + "sha256:0cb23ed0e327c18fb7eac61ebbb3180ebafed5b9b86ca2e15438201e5903b5dd", + "sha256:1a065e7a6a1b4aa851a0efa1a2579eabc765246b8b3a5fd74000aaa3134b8b4e", + "sha256:1a511470db3aa97432ac8c1bf014fcc6c9fbfd0f4b1313024d342549cf86bcd6", + "sha256:1c447b0d108cddc69036b1b3910fac159f2b51fdeec7f13872e059b7bc932be1", + "sha256:2278453c6a76280b38855a263198961938108ea2333ee145c5168c36b8e2b376", + "sha256:240509721a663836b611fa13ca1843079fc52d0b91ef3f92d9bba8da12e768a0", + "sha256:4e21340c07090ddc8c16deebfd82eb9c9e1ec5e62f57bb86194a2595fd7b46e0", + "sha256:570e916a44a361d4e85f355aacd90e9113319c78ce3c2d098d2ddf9631b34505", + "sha256:59d5c6302d22c16d59611a9fd53556554010db1d47e9df5df37be05007bebe75", + "sha256:6a46eba253cedcbe8a6469f881f014f0a98819d99d341461630885139850e281", + "sha256:6f567df0601e9c7434958143aebea47a9c4b45434ea0ae0286a4ec19e9877169", + "sha256:781906e45ef1d10a0ed9ec8ab83a09b5e0d742de70e627b20d61ccb1b1d3964d", + "sha256:8469377a437dbc31e480993399fd1fd15fe26f382dc04c51c9cb73e42965cc06", + "sha256:8cd0d587aaac74194ad3e68029124c06245acaeddaae14cb45844e5c9bebeea4", + "sha256:97a023f97cddf00831ba04886d1596ef10f59b93df7f855856f037190936e868", + "sha256:a973d5a7a324e2a5230ad7c43f5e1383cac51ef4903bf274936a5634b724b531", + "sha256:af360e62a9790e0a96bc9ac845d87bfa0e4ee0ee68547ae8b5a9c1030517dbef", + "sha256:b706c70070eea03411b1761fff3a2675da28d042a1ab7d0863b3efe1faa125c9", + "sha256:bfd7a9fddd11d116a58b62ee6c502fd24cfe22a4792261f258f886aa41c2a899", + "sha256:c30d8766a055c22e39dd7e1a4f98f6266169f2de05db737efe509c2fb9c8a3c8", + "sha256:c53dc8ee3bb7b7e28ee9feb996a0c999137be6c1d3b02cb6b3c4cba4f9e5ed09", + "sha256:c95d514093b80e5309bdca5dd99e51bcf82c44043b57c34594d9d7556bd04d05", + "sha256:d43cf21df524283daa80ecad551c306b7f52881c8d0fe4e3e76a96b626b6d8d8", + "sha256:d62205f00f461fe8b24ade07499454a3b7adf3def1225e258b994e2215fd15c5", + "sha256:e289a857dca3b35d3615c3a6a438622e20d1bf0abcb82c57d866c8d0be3f44c4", + "sha256:e5f6aa56dda92472e9d6f7b1e6331f4e2d51a67caafff4d4c5121cadac03941e", + "sha256:f4b1c65ee86bfbf7d0c3dfd90592a9e3d6e9ecd36c367c884094c050d4c35d04" + ], + "version": "==2020.10.23" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "smmap": { @@ -620,14 +620,16 @@ "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.0.4" }, "stevedore": { "hashes": [ - "sha256:38791aa5bed922b0a844513c5f9ed37774b68edc609e5ab8ab8d8fe0ce4315e5", - "sha256:c8f4f0ebbc394e52ddf49de8bcc3cf8ad2b4425ebac494106bbc5e3661ac7633" + "sha256:5e1ab03eaae06ef6ce23859402de785f08d97780ed774948ef16c4652c41bc62", + "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0" ], - "version": "==3.2.0" + "markers": "python_version >= '3.6'", + "version": "==3.2.2" }, "toml": { "hashes": [ @@ -640,27 +642,35 @@ "hashes": [ "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", + "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d", "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", + "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c", "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", + "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d", "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", + "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c", "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", + "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395", "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", + "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072", + "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298", + "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91", "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", + "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f", "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" ], - "markers": "implementation_name == 'cpython' and python_version < '3.8'", "version": "==1.4.1" }, "wrapt": { @@ -668,13 +678,6 @@ "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" ], "version": "==1.12.1" - }, - "zipp": { - "hashes": [ - "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", - "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" - ], - "version": "==3.1.0" } } } diff --git a/bot.py b/bot.py index 976c01744f..10c4b940cb 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.5.0" +__version__ = "3.6.0" import asyncio @@ -53,7 +53,8 @@ class ModmailBot(commands.Bot): def __init__(self): - super().__init__(command_prefix=None) # implemented in `get_prefix` + intents = discord.Intents.all() + super().__init__(command_prefix=None, intents=intents) # implemented in `get_prefix` self._session = None self._api = None self.metadata_loop = None @@ -89,7 +90,7 @@ def uptime(self) -> str: def startup(self): logger.line() - if os.name != 'nt': + if os.name != "nt": logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬") logger.info("││││ │ │││││├─┤││") logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") diff --git a/pyproject.toml b/pyproject.toml index b8547d752b..3f598a4640 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "=1.3.4" +"discord.py" = "=1.5.1" uvloop = {version = ">=0.12.0", sys_platform = "!= 'win32'"} python-dotenv = ">=0.10.3" parsedatetime = "^2.6" diff --git a/requirements.min.txt b/requirements.min.txt index 28550f1e50..9fd4adf1a3 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -6,7 +6,7 @@ aiohttp==3.6.2 async-timeout==3.0.1 attrs==19.3.0 chardet==3.0.4 -discord.py==1.3.4 +discord.py==1.5.1 dnspython==1.16.0 emoji==0.5.4 future==0.18.2 diff --git a/runtime.txt b/runtime.txt index 050dcb9387..67068f10fe 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.9 \ No newline at end of file +python-3.9.0 \ No newline at end of file From e49e1709adfcf0829bc625773d6393e2a14a08f6 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:17:10 +0800 Subject: [PATCH 084/705] v3.6 changelog --- CHANGELOG.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d3d127944..17951f6a24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +# v3.6.0 + +### Added + +- Added `thread_move_title` to specify title of thread moved embed. +- Mark NSFW logs in log message. ([GH #2792](https://github.com/kyb3r/modmail/issues/2792)) +- Icon for moderator that closed the thread in log message. ([GH #2828](https://github.com/kyb3r/modmail/issues/2828)) +- Ability to set mentions via user/role ID ([GH #2796](https://github.com/kyb3r/modmail/issues/2796)) + +### Changed + +- `?move` now consumes rest in category name, which means `?move Long Category Name` works without quotes! + +### Internal + +- Bump discord.py version to 1.5.1 +- Explicitly state intents used for connection +- Use `--diff` for black CI instead of `--check` ([GH#2816](https://github.com/kyb3r/modmail/issues/2816)) # v3.5.0 @@ -14,7 +32,7 @@ Fixed discord.py issue. ### Added - A confirmation when you manually delete a thread message embed. -- Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. (GH #2803) +- Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. ([GH #2803](https://github.com/kyb3r/modmail/issues/2803)) - Added `?plugins reset` command to completely reset everything related to plugins. This will fix some problems caused by broken plugins in the file system. - Support private GitHub repos for plugins (thanks to @officialpiyush pr#2767) From 4a32c0a978f22c022945f3f7a82fef9d0f4ab07c Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:18:23 +0800 Subject: [PATCH 085/705] Remove piyush translator plugin --- plugins/registry.json | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 4a79456010..38b6f20efa 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -79,15 +79,6 @@ "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" }, - "translator": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "You can auto translate thread msgs using this plugin or translate text fromm any language to English!", - "bot_version": "2.20.1", - "title": "Translator Plugin", - "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", - "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" - }, "welcomer": { "repository": "fourjr/modmail-plugins", "branch": "master", From 2aa0f842e8a40181300ce165737eaaef2e247859 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:22:43 +0800 Subject: [PATCH 086/705] Black Styling --- cogs/utility.py | 202 +++++++++++++----------------------------------- 1 file changed, 52 insertions(+), 150 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 1f89a0447a..c9e124b04c 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -47,11 +47,7 @@ async def format_cog_help(self, cog, *, no_cog=False): else: format_ = f"`[{perm_level}] {prefix + cmd.qualified_name}` " - format_ += ( - f"- {cmd.short_doc}\n" - if not cmd.short_doc == "" - else "- No description.\n" - ) + format_ += f"- {cmd.short_doc}\n" if not cmd.short_doc == "" else "- No description.\n" if not format_.strip(): continue if len(format_) + len(formats[-1]) >= 1024: @@ -71,11 +67,7 @@ async def format_cog_help(self, cog, *, no_cog=False): embed.add_field(name="Commands", value=format_ or "No commands.") continued = " (Continued)" if embeds else "" - name = ( - cog.qualified_name + " - Help" - if not no_cog - else "Miscellaneous Commands" - ) + name = cog.qualified_name + " - Help" if not no_cog else "Miscellaneous Commands" embed.set_author(name=name + continued, icon_url=bot.user.avatar_url) embed.set_footer( @@ -96,11 +88,7 @@ async def send_bot_help(self, mapping): bot = self.context.bot # always come first - default_cogs = [ - bot.get_cog("Modmail"), - bot.get_cog("Utility"), - bot.get_cog("Plugins"), - ] + default_cogs = [bot.get_cog("Modmail"), bot.get_cog("Utility"), bot.get_cog("Plugins")] default_cogs.extend(c for c in cogs if c not in default_cogs) @@ -109,16 +97,12 @@ async def send_bot_help(self, mapping): if no_cog_commands: embeds.extend(await self.format_cog_help(no_cog_commands, no_cog=True)) - session = EmbedPaginatorSession( - self.context, *embeds, destination=self.get_destination() - ) + session = EmbedPaginatorSession(self.context, *embeds, destination=self.get_destination()) return await session.run() async def send_cog_help(self, cog): embeds = await self.format_cog_help(cog) - session = EmbedPaginatorSession( - self.context, *embeds, destination=self.get_destination() - ) + session = EmbedPaginatorSession(self.context, *embeds, destination=self.get_destination()) return await session.run() async def _get_help_embed(self, topic): @@ -199,8 +183,7 @@ async def send_error_message(self, error): else: if len(values) == 1: embed = discord.Embed( - title=f"{command} is an alias.", - color=self.context.bot.main_color, + title=f"{command} is an alias.", color=self.context.bot.main_color ) embed.add_field(name=f"`{command}` points to:", value=values[0]) else: @@ -231,9 +214,7 @@ async def send_error_message(self, error): closest = get_close_matches(command, choices) if closest: - embed.add_field( - name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest) - ) + embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) else: embed.title = "Cannot find command or category" embed.set_footer( @@ -326,12 +307,11 @@ async def about(self, ctx): if self.bot.version.is_prerelease: stable = next( - filter( - lambda v: not parse_version(v.version).is_prerelease, - changelog.versions, - ) + filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions) + ) + footer = ( + f"You are on the prerelease version • the latest version is v{stable.version}." ) - footer = f"You are on the prerelease version • the latest version is v{stable.version}." elif self.bot.version < parse_version(latest.version): footer = f"A newer version is available v{latest.version}." else: @@ -386,8 +366,7 @@ async def debug(self, ctx): with open( os.path.join( - os.path.dirname(os.path.abspath(__file__)), - f"../temp/{log_file_name}.log", + os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" ), "r+", ) as f: @@ -442,17 +421,14 @@ async def debug_hastebin(self, ctx): with open( os.path.join( - os.path.dirname(os.path.abspath(__file__)), - f"../temp/{log_file_name}.log", + os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" ), "rb+", ) as f: logs = BytesIO(f.read().strip()) try: - async with self.bot.session.post( - haste_url + "/documents", data=logs - ) as resp: + async with self.bot.session.post(haste_url + "/documents", data=logs) as resp: data = await resp.json() try: key = data["key"] @@ -483,8 +459,7 @@ async def debug_clear(self, ctx): with open( os.path.join( - os.path.dirname(os.path.abspath(__file__)), - f"../temp/{log_file_name}.log", + os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" ), "w", ): @@ -547,9 +522,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): else: msg += f"{activity.name}." - embed = discord.Embed( - title="Activity Changed", description=msg, color=self.bot.main_color - ) + embed = discord.Embed(title="Activity Changed", description=msg, color=self.bot.main_color) return await ctx.send(embed=embed) @commands.command() @@ -586,14 +559,10 @@ async def status(self, ctx, *, status_type: str.lower): await self.bot.config.update() msg = f"Status set to: {status.value}." - embed = discord.Embed( - title="Status Changed", description=msg, color=self.bot.main_color - ) + embed = discord.Embed(title="Status Changed", description=msg, color=self.bot.main_color) return await ctx.send(embed=embed) - async def set_presence( - self, *, status=None, activity_type=None, activity_message=None - ): + async def set_presence(self, *, status=None, activity_type=None, activity_message=None): if status is None: status = self.bot.config.get("status") @@ -602,9 +571,7 @@ async def set_presence( activity_type = self.bot.config.get("activity_type") url = None - activity_message = ( - activity_message or self.bot.config["activity_message"] - ).strip() + activity_message = (activity_message or self.bot.config["activity_message"]).strip() if activity_type is not None and not activity_message: logger.warning( 'No activity message found whilst activity is provided, defaults to "Modmail".' @@ -620,9 +587,7 @@ async def set_presence( url = self.bot.config["twitch_url"] if activity_type is not None: - activity = discord.Activity( - type=activity_type, name=activity_message, url=url - ) + activity = discord.Activity(type=activity_type, name=activity_message, url=url) else: activity = None await self.bot.change_presence(activity=activity, status=status) @@ -684,9 +649,7 @@ async def mention(self, ctx, *mention: Union[discord.Role, discord.Member]): if not mention: embed = discord.Embed( - title="Current mention:", - color=self.bot.main_color, - description=str(current), + title="Current mention:", color=self.bot.main_color, description=str(current) ) else: mention = " ".join(i.mention for i in mention) @@ -782,9 +745,7 @@ async def config_set(self, ctx, key: str.lower, *, value: str): embed = exc.embed else: embed = discord.Embed( - title="Error", - color=self.bot.error_color, - description=f"{key} is an invalid key.", + title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." ) valid_keys = [f"`{k}`" for k in sorted(keys)] embed.add_field(name="Valid keys", value=", ".join(valid_keys)) @@ -806,9 +767,7 @@ async def config_remove(self, ctx, *, key: str.lower): ) else: embed = discord.Embed( - title="Error", - color=self.bot.error_color, - description=f"{key} is an invalid key.", + title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." ) valid_keys = [f"`{k}`" for k in sorted(keys)] embed.add_field(name="Valid keys", value=", ".join(valid_keys)) @@ -829,9 +788,7 @@ async def config_get(self, ctx, *, key: str.lower = None): if key in keys: desc = f"`{key}` is set to `{self.bot.config[key]}`" embed = discord.Embed(color=self.bot.main_color, description=desc) - embed.set_author( - name="Config variable", icon_url=self.bot.user.avatar_url - ) + embed.set_author(name="Config variable", icon_url=self.bot.user.avatar_url) else: embed = discord.Embed( @@ -848,9 +805,7 @@ async def config_get(self, ctx, *, key: str.lower = None): color=self.bot.main_color, description="Here is a list of currently set configuration variable(s).", ) - embed.set_author( - name="Current config(s):", icon_url=self.bot.user.avatar_url - ) + embed.set_author(name="Current config(s):", icon_url=self.bot.user.avatar_url) config = self.bot.config.filter_default(self.bot.config) for name, value in config.items(): @@ -878,8 +833,7 @@ async def config_help(self, ctx, key: str.lower = None): ) if closest: embed.add_field( - name=f"Perhaps you meant:", - value="\n".join(f"`{x}`" for x in closest), + name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest) ) return await ctx.send(embed=embed) @@ -902,13 +856,10 @@ def fmt(val): if current_key == key: index = i embed = discord.Embed( - title=f"Configuration description on {current_key}:", - color=self.bot.main_color, + title=f"Configuration description on {current_key}:", color=self.bot.main_color ) embed.add_field(name="Default:", value=fmt(info["default"]), inline=False) - embed.add_field( - name="Information:", value=fmt(info["description"]), inline=False - ) + embed.add_field(name="Information:", value=fmt(info["description"]), inline=False) if info["examples"]: example_text = "" for example in info["examples"]: @@ -957,9 +908,7 @@ async def alias(self, ctx, *, name: str.lower = None): if name is not None: val = self.bot.aliases.get(name) if val is None: - embed = utils.create_not_found_embed( - name, self.bot.aliases.keys(), "Alias" - ) + embed = utils.create_not_found_embed(name, self.bot.aliases.keys(), "Alias") return await ctx.send(embed=embed) values = utils.parse_alias(val) @@ -971,18 +920,14 @@ async def alias(self, ctx, *, name: str.lower = None): description=f"Alias `{name}` is invalid, this alias will now be deleted." "This alias will now be deleted.", ) - embed.add_field( - name=f"{name}` used to be:", value=utils.truncate(val, 1024) - ) + embed.add_field(name=f"{name}` used to be:", value=utils.truncate(val, 1024)) self.bot.aliases.pop(name) await self.bot.config.update() return await ctx.send(embed=embed) if len(values) == 1: embed = discord.Embed( - title=f'Alias - "{name}":', - description=values[0], - color=self.bot.main_color, + title=f'Alias - "{name}":', description=values[0], color=self.bot.main_color ) return await ctx.send(embed=embed) @@ -1000,12 +945,9 @@ async def alias(self, ctx, *, name: str.lower = None): if not self.bot.aliases: embed = discord.Embed( - color=self.bot.error_color, - description="You dont have any aliases at the moment.", - ) - embed.set_footer( - text=f'Do "{self.bot.prefix}help alias" for more commands.' + color=self.bot.error_color, description="You dont have any aliases at the moment." ) + embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') embed.set_author(name="Aliases", icon_url=ctx.guild.icon_url) return await ctx.send(embed=embed) @@ -1033,9 +975,7 @@ async def alias_raw(self, ctx, *, name: str.lower): val = utils.truncate(utils.escape_code_block(val), 2048 - 7) embed = discord.Embed( - title=f'Raw alias - "{name}":', - description=f"```\n{val}```", - color=self.bot.main_color, + title=f'Raw alias - "{name}":', description=f"```\n{val}```", color=self.bot.main_color ) return await ctx.send(embed=embed) @@ -1053,9 +993,7 @@ async def make_alias(self, name, value, action): if len(values) > 25: embed = discord.Embed( - title="Error", - description="Too many steps, max=25.", - color=self.bot.error_color, + title="Error", description="Too many steps, max=25.", color=self.bot.error_color ) return embed @@ -1066,9 +1004,7 @@ async def make_alias(self, name, value, action): embed = discord.Embed(title=f"{action} alias", color=self.bot.main_color) if not multiple_alias: - embed.add_field( - name=f"`{name}` points to:", value=utils.truncate(values[0], 1024) - ) + embed.add_field(name=f"`{name}` points to:", value=utils.truncate(values[0], 1024)) else: embed.description = f"`{name}` now points to the following steps:" @@ -1241,9 +1177,7 @@ def _parse_level(name): @permissions.command(name="override") @checks.has_permissions(PermissionLevel.OWNER) - async def permissions_override( - self, ctx, command_name: str.lower, *, level_name: str - ): + async def permissions_override(self, ctx, command_name: str.lower, *, level_name: str): """ Change a permission level for a specific command. @@ -1282,9 +1216,7 @@ async def permissions_override( command.qualified_name, level.name, ) - self.bot.config["override_command_level"][ - command.qualified_name - ] = level.name + self.bot.config["override_command_level"][command.qualified_name] = level.name await self.bot.config.update() embed = discord.Embed( @@ -1356,9 +1288,7 @@ async def permissions_add( key = self.bot.modmail_guild.get_member(value) if key is not None: logger.info("Granting %s access to Modmail category.", key.name) - await self.bot.main_category.set_permissions( - key, read_messages=True - ) + await self.bot.main_category.set_permissions(key, read_messages=True) embed = discord.Embed( title="Success", @@ -1455,21 +1385,13 @@ async def permissions_remove( self.bot.modmail_guild.default_role, read_messages=False ) elif isinstance(user_or_role, discord.Role): - logger.info( - "Denying %s access to Modmail category.", user_or_role.name - ) - await self.bot.main_category.set_permissions( - user_or_role, overwrite=None - ) + logger.info("Denying %s access to Modmail category.", user_or_role.name) + await self.bot.main_category.set_permissions(user_or_role, overwrite=None) else: member = self.bot.modmail_guild.get_member(value) if member is not None and member != self.bot.modmail_guild.me: - logger.info( - "Denying %s access to Modmail category.", member.name - ) - await self.bot.main_category.set_permissions( - member, overwrite=None - ) + logger.info("Denying %s access to Modmail category.", member.name) + await self.bot.main_category.set_permissions(member, overwrite=None) embed = discord.Embed( title="Success", @@ -1519,11 +1441,7 @@ def _get_perm(self, ctx, name, type_): @permissions.command(name="get", usage="[@user] or [command/level/override] [name]") @checks.has_permissions(PermissionLevel.OWNER) async def permissions_get( - self, - ctx, - user_or_role: Union[discord.Role, utils.User, str], - *, - name: str = None, + self, ctx, user_or_role: Union[discord.Role, utils.User, str], *, name: str = None ): """ View the currently-set permissions. @@ -1573,9 +1491,7 @@ async def permissions_get( if value in permissions: levels.append(level.name) - mention = getattr( - user_or_role, "name", getattr(user_or_role, "id", user_or_role) - ) + mention = getattr(user_or_role, "name", getattr(user_or_role, "id", user_or_role)) desc_cmd = ( ", ".join(map(lambda x: f"`{x}`", cmds)) if cmds @@ -1625,14 +1541,10 @@ async def permissions_get( ) ) else: - for items in zip_longest( - *(iter(sorted(overrides.items())),) * 15 - ): + for items in zip_longest(*(iter(sorted(overrides.items())),) * 15): description = "\n".join( ": ".join((f"`{name}`", level)) - for name, level in takewhile( - lambda x: x is not None, items - ) + for name, level in takewhile(lambda x: x is not None, items) ) embed = discord.Embed( color=self.bot.main_color, description=description @@ -1688,9 +1600,7 @@ async def permissions_get( return await ctx.send(embed=embed) if user_or_role == "command": - embeds.append( - self._get_perm(ctx, command.qualified_name, "command") - ) + embeds.append(self._get_perm(ctx, command.qualified_name, "command")) else: embeds.append(self._get_perm(ctx, level.name, "level")) else: @@ -1699,9 +1609,7 @@ async def permissions_get( for command in self.bot.walk_commands(): if command not in done: done.add(command) - embeds.append( - self._get_perm(ctx, command.qualified_name, "command") - ) + embeds.append(self._get_perm(ctx, command.qualified_name, "command")) else: for perm_level in PermissionLevel: embeds.append(self._get_perm(ctx, perm_level.name, "level")) @@ -1743,9 +1651,7 @@ async def oauth_whitelist(self, ctx, target: Union[discord.Role, utils.User]): embed.title = "Success" if not hasattr(target, "mention"): - target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role( - target.id - ) + target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role(target.id) embed.description = ( f"{'Un-w' if removed else 'W'}hitelisted {target.mention} to view logs." @@ -1773,12 +1679,8 @@ async def oauth_show(self, ctx): embed = discord.Embed(color=self.bot.main_color) embed.title = "Oauth Whitelist" - embed.add_field( - name="Users", value=" ".join(u.mention for u in users) or "None" - ) - embed.add_field( - name="Roles", value=" ".join(r.mention for r in roles) or "None" - ) + embed.add_field(name="Users", value=" ".join(u.mention for u in users) or "None") + embed.add_field(name="Roles", value=" ".join(r.mention for r in roles) or "None") await ctx.send(embed=embed) From 2d3d690a645f822a9fd379f616a7ddcee86e574b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:23:49 +0800 Subject: [PATCH 087/705] add PR#2845 in changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17951f6a24..3763968747 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,11 +13,12 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `thread_move_title` to specify title of thread moved embed. - Mark NSFW logs in log message. ([GH #2792](https://github.com/kyb3r/modmail/issues/2792)) - Icon for moderator that closed the thread in log message. ([GH #2828](https://github.com/kyb3r/modmail/issues/2828)) -- Ability to set mentions via user/role ID ([GH #2796](https://github.com/kyb3r/modmail/issues/2796)) +- Ability to set mentions via user/role ID. ([GH #2796](https://github.com/kyb3r/modmail/issues/2796)) ### Changed - `?move` now consumes rest in category name, which means `?move Long Category Name` works without quotes! +- `?help` shows "No command description" if no description provided. ([PR #2845](https://github.com/kyb3r/modmail/pull/2845)) ### Internal From 3d6c657ec7aeae29a2a51f4e1ec9e6daf8ccd266 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:28:02 +0800 Subject: [PATCH 088/705] Add to app.json --- app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app.json b/app.json index b6a833b1ef..cd5f25825c 100644 --- a/app.json +++ b/app.json @@ -11,6 +11,10 @@ "description": "The id for the server you are hosting this bot for.", "required": true }, + "MODMAIL_GUILD_ID": { + "description": "The ID of the discord server where the threads channels should be created (receiving server). Default to GUILD_ID.", + "required": false + }, "OWNERS": { "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", "required": true From 7f4f3eda393792d4918398ecc9a920a229b4867d Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sat, 10 Oct 2020 21:14:46 +0200 Subject: [PATCH 089/705] Update SPONSORS.json Remove sponsor server, still am sponsor --- SPONSORS.json | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/SPONSORS.json b/SPONSORS.json index d30134e015..ceed37be23 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -26,42 +26,5 @@ } ] } - }, - { - "embed": { - "title": "Hey there!", - "description": "Nice to see you here! You can support us by subscribing on youtube -> [Youtube](https://www.youtube.com/user/RoomieOfficial) <- and also join our [Discord](https://discord.gg/zaeVCaV)!", - "url": "https://discord.gg/zaeVCaV", - "color": 13003681, - "footer": { - "icon_url": "https://imgur.com/Mrc9pLd.gif", - "text": "everyone is a clown" - }, - "thumbnail": { - "url": "https://imgur.com/Mrc9pLd.gif" - }, - "image": { - "url": "https://imgur.com/ZUFiL6b.gif" - }, - "author": { - "name": "Roomieofficial", - "url": "https://discord.gg/zaeVCaV", - "icon_url": "https://imgur.com/6hBkt7Z.png" - }, - "fields": [ - { - "name": "What is all this about 🤔", - "value": "We are mainly focused on everything that has anything to do with music or singing! " - }, - { - "name": "Youtube 🙄", - "value": "U will get great content if you follow our [Youtube](https://www.youtube.com/user/RoomieOfficial) with weekly uploads." - }, - { - "name": "Discord 😁", - "value": "Make sure to join our [Discord](https://discord.gg/zaeVCaV) We have weekly events, 24/7 chats and more!" - } - ] - } } ] From 7da970c17666b26149fbda4586fa5a79ec8b2c99 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:31:02 +0800 Subject: [PATCH 090/705] lorenzo132: add mediaonly plugin --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 335cd25458..00a637875c 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -25,6 +25,15 @@ "title": "Dragory Logs Migration", "icon_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png", "thumbnail_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png" + }, + "media-only": { + "repository": "lorenzo132/modmail-plugins", + "branch": "master", + "description": "Make a channel mediaonly, only the following mediatypes will be accepted `.png` / `.gif` / `.jpg` / `.mp4`/ `.jpeg`", + "bot_version": "2.20.1", + "title": "Media-only", + "icon_url": "https://i.imgur.com/ussAoIi.png", + "thumbnail_url": "https://i.imgur.com/ussAoIi.png" }, "anti-steal-close": { "repository": "officialpiyush/modmail-plugins", From 2c5a72b899a474067f11e31bda0d41b4ec7a3dff Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:31:26 +0800 Subject: [PATCH 091/705] Formatting --- plugins/registry.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 00a637875c..5c343ebcff 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -7,8 +7,8 @@ "title": "Profanity Filter Plugin", "icon_url": "https://i.imgur.com/951szZ3.jpg", "thumbnail_url": "https://i.imgur.com/951szZ3.jpg" - }, - "music": { + }, + "music": { "repository": "lorenzo132/modmail-plugins", "branch": "master", "description": "Play your favourite music on your bot! Note: Only works on VPS follow this guide: https://gist.github.com/lorenzo132/5ef328e5dfcfaec19cb81dc7a63eaffa", @@ -16,8 +16,8 @@ "title": "Music", "icon_url": "https://i.imgur.com/R2olclk.png", "thumbnail_url": "https://i.imgur.com/xuoQjPu.gif" - }, - "dragory-migrate": { + }, + "dragory-migrate": { "repository": "kyb3r/modmail-plugins", "branch": "master", "description": "Migrate your logs from Dragory's modmail bot to this one with a simple command. Added at the request of users.", @@ -25,8 +25,8 @@ "title": "Dragory Logs Migration", "icon_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png", "thumbnail_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png" - }, - "media-only": { + }, + "media-only": { "repository": "lorenzo132/modmail-plugins", "branch": "master", "description": "Make a channel mediaonly, only the following mediatypes will be accepted `.png` / `.gif` / `.jpg` / `.mp4`/ `.jpeg`", @@ -36,12 +36,12 @@ "thumbnail_url": "https://i.imgur.com/ussAoIi.png" }, "anti-steal-close": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Don't let anyone steal ya close.", - "title": "Anti Steal Close", - "icon_url": "https://i.imgur.com/LovxyV3.png", - "thumbnail_url": "https://i.imgur.com/LovxyV3.png" + "repository": "officialpiyush/modmail-plugins", + "branch": "master", + "description": "Don't let anyone steal ya close.", + "title": "Anti Steal Close", + "icon_url": "https://i.imgur.com/LovxyV3.png", + "thumbnail_url": "https://i.imgur.com/LovxyV3.png" }, "announcement": { "repository": "officialpiyush/modmail-plugins", @@ -114,7 +114,7 @@ "title": "Backup Database (backupdb)", "icon_url": "https://images.ionadev.ml/b/nKAlOC4.jpg", "thumbnail_url": "https://images.ionadev.ml/b/nKAlOC4.jpg" - }, + }, "colors": { "repository": "Taaku18/modmail-plugins", "branch": "master", @@ -124,7 +124,7 @@ "icon_url": "https://cdn1.iconfinder.com/data/icons/weather-19/32/rainbow-512.png", "thumbnail_url": "https://i.imgur.com/fSxnc9W.jpg" }, - "fun": { + "fun": { "repository": "TheKinG2149/modmail-plugins", "branch": "master", "description": "Some fun commands like 8ball, dadjokes", @@ -132,7 +132,7 @@ "title": "Fun", "icon_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png", "thumbnail_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png" - }, + }, "stats": { "repository": "KarateWumpus/modmail-plugins", "branch": "master", @@ -178,7 +178,7 @@ "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" }, - "slowmode": { + "slowmode": { "repository": "teen1/modmail-plugins", "branch": "master", "description": "Configure slow mode for your channels with Modmail!", @@ -187,7 +187,7 @@ "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" }, - "publish": { + "publish": { "repository": "codeinteger6/modmail-plugins", "branch": "master", "description": "Publish messages sent in announcement channels.", @@ -196,7 +196,7 @@ "icon_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png", "thumbnail_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png" }, - "translate": { + "translate": { "repository": "WebKide/modmail-plugins", "branch": "master", "description": "(∩`-´)⊃━☆゚.*・。゚ translate text from one language to another (defaults to English)\n\nGet full list of available languages at: https://github.com/WebKide/modmail-plugins/blob/master/translate/langs.json\n\nThis command conflicts with Translator-plugin", @@ -205,4 +205,4 @@ "icon_url": "https://i.imgur.com/yeHFKgl.png", "thumbnail_url": "https://i.imgur.com/yeHFKgl.png" } -} +} \ No newline at end of file From e57a519819d1e0d37716e1f267f839cd2344c22a Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:42:33 +0800 Subject: [PATCH 092/705] Finalise 3.6 changelog --- CHANGELOG.md | 3 +++ pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3763968747..4069bf5586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?move` now consumes rest in category name, which means `?move Long Category Name` works without quotes! - `?help` shows "No command description" if no description provided. ([PR #2845](https://github.com/kyb3r/modmail/pull/2845)) +### Fixed +- Unicode errors raised during windows selfhosting + ### Internal - Bump discord.py version to 1.5.1 diff --git a/pyproject.toml b/pyproject.toml index 3f598a4640..c1f32e7c2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.5.0' +version = '3.6.0' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From e3a2bbff2502dc112b8164d2c469c2a452e5dc0a Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 16:44:08 +0800 Subject: [PATCH 093/705] Fix startup printing --- bot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bot.py b/bot.py index 46cfa4b772..af0187f290 100644 --- a/bot.py +++ b/bot.py @@ -96,7 +96,6 @@ def startup(self): logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") else: logger.info("MODMAIL") - logger.info("MODMAIL") logger.info("v%s", __version__) logger.info("Authors: kyb3r, fourjr, Taaku18") logger.line() From 2d99efe3fe530f8cd9d669147fb1f26dd8e11501 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 17:02:09 +0800 Subject: [PATCH 094/705] Fix bug with help message --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index c9e124b04c..b0d96ea094 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -47,7 +47,7 @@ async def format_cog_help(self, cog, *, no_cog=False): else: format_ = f"`[{perm_level}] {prefix + cmd.qualified_name}` " - format_ += f"- {cmd.short_doc}\n" if not cmd.short_doc == "" else "- No description.\n" + format_ += f"- {cmd.short_doc}\n" if cmd.short_doc else "- *No description.*\n" if not format_.strip(): continue if len(format_) + len(formats[-1]) >= 1024: From 5d14ef13ea478f7517ae0d405e99582c62f00695 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 17:19:24 +0800 Subject: [PATCH 095/705] Update version number --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40cbd7b1e4..1a34338e8a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
From 1772910f4dfc3547db5d8add086bdf8b32ef86bb Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 17:27:06 +0800 Subject: [PATCH 096/705] 3.6.1 - error message if no priv. intents granted --- CHANGELOG.md | 8 ++++++++ bot.py | 2 ++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4069bf5586..beddd66a28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +# v3.6.1 + +### Added + +- Proper error message if privileged intents not explicitly granted to bot. + + # v3.6.0 ### Added @@ -29,6 +36,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Explicitly state intents used for connection - Use `--diff` for black CI instead of `--check` ([GH#2816](https://github.com/kyb3r/modmail/issues/2816)) + # v3.5.0 Fixed discord.py issue. diff --git a/bot.py b/bot.py index af0187f290..0755b859bd 100644 --- a/bot.py +++ b/bot.py @@ -167,6 +167,8 @@ def run(self, *args, **kwargs): pass except discord.LoginFailure: logger.critical("Invalid token") + except discord.PrivilegedIntentsRequired: + logger.critical('Privileged intents are not explicitly granted in the discord developers dashboard.') except Exception: logger.critical("Fatal exception", exc_info=True) finally: From 690078dba8c89c442e869de6271ec229bb1dffe7 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 17:28:15 +0800 Subject: [PATCH 097/705] 3.6.1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a34338e8a..b22bf75f79 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
From 9994cf6a88da045ab61198c5576dd4454b1bc205 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 18:15:35 +0800 Subject: [PATCH 098/705] Fix pyproject.toml --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c1f32e7c2e..0d47eb844a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" "discord.py" = "=1.5.1" -uvloop = {version = ">=0.12.0", sys_platform = "!= 'win32'"} +uvloop = {version = ">=0.12.0", markers = "sys_platform != 'win32'"} python-dotenv = ">=0.10.3" parsedatetime = "^2.6" dnspython = "^1.16" @@ -50,7 +50,7 @@ colorama = "^0.4.3" aiohttp = ">=3.6.0,<3.7.0" [tool.poetry.dev-dependencies] -black = {version = "=19.10b0", allows-prereleases = true} +black = {version = "=19.10b0", allow-prereleases = true} pylint = "^2.4" bandit = "^1.6" From 7808be033e570f71e1f0e39dffde6d7d1ae60ab9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 18:29:15 +0800 Subject: [PATCH 099/705] Fix issue with plugins and clean pipfile --- CHANGELOG.md | 7 +++++ Pipfile | 2 -- Pipfile.lock | 76 +------------------------------------------------ README.md | 2 +- bot.py | 6 ++-- cogs/plugins.py | 2 +- 6 files changed, 14 insertions(+), 81 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index beddd66a28..04779442b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +# v3.6.2 + +### Added + +- Proper error message if privileged intents not explicitly granted to bot. + + # v3.6.1 ### Added diff --git a/Pipfile b/Pipfile index d468866095..01485b1e63 100644 --- a/Pipfile +++ b/Pipfile @@ -23,8 +23,6 @@ aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" "discord.py" = "==1.5.1" -pynacl = "*" -cffi = "*" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 682d7252b5..005ce37f67 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0dba33486b4cc030061af10a203dbf804d4984f09da44200d4a0a97c6ed924ce" + "sha256": "0491618cb8bd6d70e4ab3337c23b72fc3b1d5f9ca0603d8be6b890b661039102" }, "pipfile-spec": 6, "requires": {}, @@ -63,48 +63,6 @@ ], "version": "==2020.6.20" }, - "cffi": { - "hashes": [ - "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d", - "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b", - "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4", - "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f", - "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3", - "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579", - "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537", - "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e", - "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05", - "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171", - "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca", - "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522", - "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c", - "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc", - "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d", - "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808", - "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828", - "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869", - "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d", - "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9", - "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0", - "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc", - "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15", - "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c", - "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a", - "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3", - "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1", - "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768", - "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d", - "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b", - "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e", - "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d", - "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730", - "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394", - "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1", - "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591" - ], - "index": "pypi", - "version": "==1.14.3" - }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", @@ -227,14 +185,6 @@ "index": "pypi", "version": "==2020.8.13" }, - "pycparser": { - "hashes": [ - "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", - "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.20" - }, "pymongo": { "hashes": [ "sha256:03dc64a9aa7a5d405aea5c56db95835f6a2fa31b3502c5af1760e0e99210be30", @@ -295,30 +245,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.11.0" }, - "pynacl": { - "hashes": [ - "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4", - "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4", - "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574", - "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d", - "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634", - "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25", - "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f", - "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505", - "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122", - "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7", - "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420", - "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f", - "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96", - "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6", - "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6", - "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514", - "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff", - "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80" - ], - "index": "pypi", - "version": "==1.4.0" - }, "python-dateutil": { "hashes": [ "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", diff --git a/README.md b/README.md index b22bf75f79..6173484788 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
diff --git a/bot.py b/bot.py index 0755b859bd..15ef85429e 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.6.0" +__version__ = "3.6.2" import asyncio @@ -168,7 +168,9 @@ def run(self, *args, **kwargs): except discord.LoginFailure: logger.critical("Invalid token") except discord.PrivilegedIntentsRequired: - logger.critical('Privileged intents are not explicitly granted in the discord developers dashboard.') + logger.critical( + "Privileged intents are not explicitly granted in the discord developers dashboard." + ) except Exception: logger.critical("Fatal exception", exc_info=True) finally: diff --git a/cogs/plugins.py b/cogs/plugins.py index 835aad49a9..3330d407ad 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -199,7 +199,7 @@ async def load_plugin(self, plugin): venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env user_install = " --user" if not venv else "" proc = await asyncio.create_subprocess_shell( - f'"{sys.executable}" -m pip install --upgrade{user_install} -r {req_txt} -q -q --user', + f'"{sys.executable}" -m pip install --upgrade{user_install} -r {req_txt} -q -q', stderr=PIPE, stdout=PIPE, ) From 8c5df2c5f2cd9968dd9609840eaa45a2de1ddb08 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 18:30:41 +0800 Subject: [PATCH 100/705] 3.6.2 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04779442b1..5248d772ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v3.6.2 -### Added +### Fixed -- Proper error message if privileged intents not explicitly granted to bot. +- Plugins downloading requirements in virtual environments # v3.6.1 From 714f5316d8e647af1c2862b635eedd000eeccf80 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 28 Oct 2020 22:26:41 +0800 Subject: [PATCH 101/705] Cleanup folder structures --- .../CODE_OF_CONDUCT.md | 0 CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 .lint.py | 17 - .pylintrc | 511 ------------------ app.json | 66 +-- core/clients.py | 4 +- 6 files changed, 35 insertions(+), 563 deletions(-) rename CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md (100%) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) delete mode 100644 .lint.py delete mode 100644 .pylintrc diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/.lint.py b/.lint.py deleted file mode 100644 index 9d29372fd8..0000000000 --- a/.lint.py +++ /dev/null @@ -1,17 +0,0 @@ -if __name__ == "__main__": - import sys - from os import listdir - from os.path import join - - from pylint.lint import Run - - THRESHOLD = 9.75 - - cogs = [join("cogs", c) for c in listdir("cogs") if c.endswith(".py")] - core = [join("core", c) for c in listdir("core") if c.endswith(".py")] - - results = Run(["bot.py", *cogs, *core], do_exit=False) - - score = results.linter.stats["global_note"] - if score <= THRESHOLD: - sys.exit(1) diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 21087a91f7..0000000000 --- a/.pylintrc +++ /dev/null @@ -1,511 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-whitelist= - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs=0 - -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# Specify a configuration file. -#rcfile= - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - metaclass-assignment, - missing-docstring, # No doc-string - no-name-in-module, # No name 'file' in module 'core' - fixme, - too-many-public-methods, - too-many-locals, - too-many-statements, - too-many-branches, - too-many-instance-attributes, - too-many-arguments, - too-few-public-methods, - too-many-lines, - line-too-long, - bad-continuation, - invalid-name, - logging-too-many-args - - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[REPORTS] - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit - - -[LOGGING] - -# Format style used to check logging format string. `old` means using % -# formatting, while `new` is for `{}` formatting. -logging-format-style=new - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package.. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - TODO, - BUG - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=99 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -#class-attribute-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. -#class-rgx= - -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. -function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - ex, - _, - id, - db, - f, - dt, - ch, - ts - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=yes - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -#inlinevar-rgx= - -# Naming style matching correct method names. -method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. -#method-rgx= - -# Naming style matching correct module names. -module-naming-style=snake_case - -# Regular expression matching correct module names. Overrides module-naming- -# style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -#variable-rgx= - - -[IMPORTS] - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled). -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled). -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls - - -[DESIGN] - -# Maximum number of arguments for function / method. -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in an if statement. -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=12 - -# Maximum number of locals for function / method body. -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception". -overgeneral-exceptions=BaseException diff --git a/app.json b/app.json index cd5f25825c..41697cf064 100644 --- a/app.json +++ b/app.json @@ -1,35 +1,35 @@ { - "name": "Modmail", - "description": "An easy to install Modmail bot for Discord - DM to contact mods!", - "repository": "https://github.com/kyb3r/modmail", - "env": { - "TOKEN": { - "description": "Your discord bot's token.", - "required": true - }, - "GUILD_ID": { - "description": "The id for the server you are hosting this bot for.", - "required": true - }, - "MODMAIL_GUILD_ID": { - "description": "The ID of the discord server where the threads channels should be created (receiving server). Default to GUILD_ID.", - "required": false - }, - "OWNERS": { - "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", - "required": true - }, - "CONNECTION_URI": { - "description": "The connection URI for your database.", - "required": true - }, - "DATABASE_TYPE": { - "description": "The type of your database. There is only one supported database at the moment - MongoDB (default).", - "required": false - }, - "LOG_URL": { - "description": "The url of the log viewer app for viewing self-hosted logs.", - "required": true + "name": "Modmail", + "description": "An easy to install Modmail bot for Discord - DM to contact mods!", + "repository": "https://github.com/kyb3r/modmail", + "env": { + "TOKEN": { + "description": "Your discord bot's token.", + "required": true + }, + "GUILD_ID": { + "description": "The id for the server you are hosting this bot for.", + "required": true + }, + "MODMAIL_GUILD_ID": { + "description": "The ID of the discord server where the threads channels should be created (receiving server). Default to GUILD_ID.", + "required": false + }, + "OWNERS": { + "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", + "required": true + }, + "CONNECTION_URI": { + "description": "The connection URI for your database.", + "required": true + }, + "DATABASE_TYPE": { + "description": "The type of your database. There is only one supported database at the moment - MongoDB (default).", + "required": false + }, + "LOG_URL": { + "description": "The url of the log viewer app for viewing self-hosted logs.", + "required": true + } } - } -} +} \ No newline at end of file diff --git a/core/clients.py b/core/clients.py index 1e6008e042..03921d5a17 100644 --- a/core/clients.py +++ b/core/clients.py @@ -164,7 +164,7 @@ def __init__(self, bot): db = AsyncIOMotorClient(mongo_uri).modmail_bot except ConfigurationError as e: logger.critical( - "Your MONGO_URI might be copied wrong, try re-copying from the source again. " + "Your MongoDB CONNECTION_URI might be copied wrong, try re-copying from the source again. " "Otherwise noted in the following message:" ) logger.critical(e) @@ -210,7 +210,7 @@ async def validate_database_connection(self): if "OperationFailure" in message: logger.critical( - "This is due to having invalid credentials in your MONGO_URI. " + "This is due to having invalid credentials in your MongoDB CONNECTION_URI. " "Remember you need to substitute `` with your actual password." ) logger.critical( From e65997ad2bd0f16a6fa440d41c21b13c21d0b3a9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sun, 1 Nov 2020 17:45:02 +0800 Subject: [PATCH 102/705] Improve plugin install error messages --- cogs/plugins.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index 3330d407ad..227cfc8270 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -166,6 +166,17 @@ async def download_plugin(self, plugin, force=False): async with self.bot.session.get(plugin.url, headers=headers) as resp: logger.debug("Downloading %s.", plugin.url) raw = await resp.read() + + try: + raw = await resp.text() + except UnicodeDecodeError: + pass + else: + if raw == 'Not Found': + raise InvalidPluginError('Plugin not found') + else: + raise InvalidPluginError('Invalid download recieved, non-bytes object') + plugin_io = io.BytesIO(raw) if not plugin.cache_path.parent.exists(): plugin.cache_path.parent.mkdir(parents=True) @@ -321,11 +332,11 @@ async def plugins_add(self, ctx, *, plugin_name: str): try: await self.download_plugin(plugin, force=True) - except Exception: + except Exception as e: logger.warning("Unable to download plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description="Failed to download plugin, check logs for error.", + description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", color=self.bot.error_color, ) @@ -340,11 +351,11 @@ async def plugins_add(self, ctx, *, plugin_name: str): try: await self.load_plugin(plugin) - except Exception: + except Exception as e: logger.warning("Unable to load plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description="Failed to download plugin, check logs for error.", + description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", color=self.bot.error_color, ) From 39e3bc32854f365db24ee7517a7f9d844acc3042 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sun, 1 Nov 2020 17:51:33 +0800 Subject: [PATCH 103/705] Changelog --- CHANGELOG.md | 8 +++++++- bot.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5248d772ee..57b9d415b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +# v3.6.3-dev0 + +### Improved + +- Plugins installations have clearer error messages + # v3.6.2 ### Fixed @@ -41,7 +47,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Bump discord.py version to 1.5.1 - Explicitly state intents used for connection -- Use `--diff` for black CI instead of `--check` ([GH#2816](https://github.com/kyb3r/modmail/issues/2816)) +- Use `--diff` for black CI instead of `--check` ([GH #2816](https://github.com/kyb3r/modmail/issues/2816)) # v3.5.0 diff --git a/bot.py b/bot.py index 15ef85429e..ab5ded6c53 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.6.2" +__version__ = "3.6.3-dev0" import asyncio From c605d68a5e73214499fe5c09446c40ca0df8e8cd Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sun, 1 Nov 2020 17:55:11 +0800 Subject: [PATCH 104/705] Force push to dev --- .env.example | 3 +- .../CODE_OF_CONDUCT.md | 0 CONTRIBUTING.md => .github/CONTRIBUTING.md | 17 +- .github/ISSUE_TEMPLATE/command-request.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- .github/workflows/lints.yml | 2 +- .github/workflows/stale.yml | 17 - .lint.py | 17 - .pylintrc | 511 ------- CHANGELOG.md | 333 +++-- Pipfile | 14 +- Pipfile.lock | 621 +++++---- Procfile | 2 +- README.md | 50 +- SPONSORS.json | 37 - app.json | 58 +- bot.py | 266 ++-- cogs/modmail.py | 385 +++--- cogs/plugins.py | 184 ++- cogs/utility.py | 438 +++--- core/clients.py | 180 ++- core/config.py | 11 +- core/config_help.json | 14 +- core/paginator.py | 2 +- core/thread.py | 64 +- core/time.py | 2 +- core/translations.py | 25 - languages/en.csv | 1172 ----------------- modmail.sh | 3 + plugins/registry.json | 133 +- poetry.lock | 157 ++- pyproject.toml | 20 +- requirements.min.txt | 28 +- runtime.txt | 2 +- translation_files.py | 127 -- 35 files changed, 1638 insertions(+), 3261 deletions(-) rename CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md (100%) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (83%) delete mode 100644 .github/workflows/stale.yml delete mode 100644 .lint.py delete mode 100644 .pylintrc delete mode 100644 core/translations.py delete mode 100644 languages/en.csv create mode 100644 modmail.sh delete mode 100644 translation_files.py diff --git a/.env.example b/.env.example index b3554bf9c9..44c91c59c7 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ TOKEN=MyBotToken LOG_URL=https://logviewername.herokuapp.com/ GUILD_ID=1234567890 +MODMAIL_GUILD_ID=1234567890 OWNERS=Owner1ID,Owner2ID,Owner3ID -MONGO_URI=mongodb+srv://mongodburi +CONNECTION_URI=mongodb+srv://mongodburi diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 83% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md index a95e344610..568e5f2175 100644 --- a/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -15,33 +15,32 @@ We use GitHub to host code, to track issues and feature requests, as well as acc ## We Use [Git Flow](https://atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) ![Simple Image Of A Git Flow Workflow](https://nvie.com/img/hotfix-branches@2x.png) -When contributing to this project please make sure you follow this and name your branches appropriately! +When contributing to this project, please make sure you follow this and name your branches appropriately! ## All Code Changes Happen Through Pull Requests Make sure you know how Git Flow works before contributing! Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests: 1. Fork the repo and create your branch from `master` or `development` according to Git Flow. -2. If you've added code that should be tested, add tests. -3. If you've changed APIs, update the documentation. -4. Ensure the test suite passes. -5. Make sure your code lints. -6. Issue that pull request! +2. Update the CHANGELOG. +3. If you've changed `core/*` or `bot.py`, mark changelog as "BREAKING" since plugins may break. +4. Make sure your code passes the lint checks. +5. Create Issues and pull requests! ## Any contributions you make will be under the GNU Affero General Public License v3.0 In short, when you submit code changes, your submissions are understood to be under the same [GNU Affero General Public License v3.0](https://www.gnu.org/licenses/agpl-3.0.en.html) that covers the project. Feel free to contact the maintainers if that's a concern. ## Report bugs using [Github Issues](https://github.com/kyb3r/modmail/issues) -We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! +We use GitHub issues to track public bugs. Report a bug by [opening a new Issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! ## Write bug reports with detail, background, and sample code **Great Bug Reports** tend to have: -- A quick summary and/or background +- A quick summary and background - Steps to reproduce - Be specific! - What you expected would happen -- What actually happens +- What *actually* happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) diff --git a/.github/ISSUE_TEMPLATE/command-request.md b/.github/ISSUE_TEMPLATE/command-request.md index 44902f2cf3..d3c1673a6b 100644 --- a/.github/ISSUE_TEMPLATE/command-request.md +++ b/.github/ISSUE_TEMPLATE/command-request.md @@ -1,7 +1,7 @@ --- name: Command request about: Request a new command -title: "[COMMAND-REQUEST] your title here" +title: "your title here" labels: command-request assignees: '' diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 48b986344d..7cd7a506cd 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: "[FEATURE-REQUEST] your title here" +title: "your title here" labels: feature-request assignees: '' diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index c84c9af773..52a538bef7 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -31,4 +31,4 @@ jobs: continue-on-error: true - name: Black and flake8 run: | - black . --check + black . --diff diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index b3003ccf92..0000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: "Close Stale Issues" - -on: - schedule: - - cron: "0 0 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is stale because it has been open for 100 days with no activity. Remove stale label or comment or this will be closed in 5 days. Please do not un-stale this issue unless it carries significant contribution.' - days-before-stale: 100 - days-before-close: 5 - exempt-issue-label: 'high priority' diff --git a/.lint.py b/.lint.py deleted file mode 100644 index 9d29372fd8..0000000000 --- a/.lint.py +++ /dev/null @@ -1,17 +0,0 @@ -if __name__ == "__main__": - import sys - from os import listdir - from os.path import join - - from pylint.lint import Run - - THRESHOLD = 9.75 - - cogs = [join("cogs", c) for c in listdir("cogs") if c.endswith(".py")] - core = [join("core", c) for c in listdir("core") if c.endswith(".py")] - - results = Run(["bot.py", *cogs, *core], do_exit=False) - - score = results.linter.stats["global_note"] - if score <= THRESHOLD: - sys.exit(1) diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 21087a91f7..0000000000 --- a/.pylintrc +++ /dev/null @@ -1,511 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-whitelist= - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs=0 - -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# Specify a configuration file. -#rcfile= - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - metaclass-assignment, - missing-docstring, # No doc-string - no-name-in-module, # No name 'file' in module 'core' - fixme, - too-many-public-methods, - too-many-locals, - too-many-statements, - too-many-branches, - too-many-instance-attributes, - too-many-arguments, - too-few-public-methods, - too-many-lines, - line-too-long, - bad-continuation, - invalid-name, - logging-too-many-args - - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[REPORTS] - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit - - -[LOGGING] - -# Format style used to check logging format string. `old` means using % -# formatting, while `new` is for `{}` formatting. -logging-format-style=new - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package.. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - TODO, - BUG - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=99 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -#class-attribute-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. -#class-rgx= - -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. -function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - ex, - _, - id, - db, - f, - dt, - ch, - ts - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=yes - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -#inlinevar-rgx= - -# Naming style matching correct method names. -method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. -#method-rgx= - -# Naming style matching correct module names. -module-naming-style=snake_case - -# Regular expression matching correct module names. Overrides module-naming- -# style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -#variable-rgx= - - -[IMPORTS] - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled). -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled). -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls - - -[DESIGN] - -# Maximum number of arguments for function / method. -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in an if statement. -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=12 - -# Maximum number of locals for function / method body. -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception". -overgeneral-exceptions=BaseException diff --git a/CHANGELOG.md b/CHANGELOG.md index 16c89216f4..57b9d415b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,93 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); -however, insignificant breaking changes does not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). +however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +# v3.6.3-dev0 -# v3.5.0-dev0 +### Improved + +- Plugins installations have clearer error messages + +# v3.6.2 + +### Fixed + +- Plugins downloading requirements in virtual environments + + +# v3.6.1 + +### Added + +- Proper error message if privileged intents not explicitly granted to bot. + + +# v3.6.0 + +### Added + +- Added `thread_move_title` to specify title of thread moved embed. +- Mark NSFW logs in log message. ([GH #2792](https://github.com/kyb3r/modmail/issues/2792)) +- Icon for moderator that closed the thread in log message. ([GH #2828](https://github.com/kyb3r/modmail/issues/2828)) +- Ability to set mentions via user/role ID. ([GH #2796](https://github.com/kyb3r/modmail/issues/2796)) + +### Changed + +- `?move` now consumes rest in category name, which means `?move Long Category Name` works without quotes! +- `?help` shows "No command description" if no description provided. ([PR #2845](https://github.com/kyb3r/modmail/pull/2845)) + +### Fixed +- Unicode errors raised during windows selfhosting + +### Internal + +- Bump discord.py version to 1.5.1 +- Explicitly state intents used for connection +- Use `--diff` for black CI instead of `--check` ([GH #2816](https://github.com/kyb3r/modmail/issues/2816)) + + +# v3.5.0 + +Fixed discord.py issue. + +### Added + +- A confirmation when you manually delete a thread message embed. +- Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. ([GH #2803](https://github.com/kyb3r/modmail/issues/2803)) +- Added `?plugins reset` command to completely reset everything related to plugins. This will fix some problems caused by broken plugins in the file system. +- Support private GitHub repos for plugins (thanks to @officialpiyush pr#2767) + +### Changed + +- Bump discord.py version to v1.3.3. +- Renamed `bot.owner_ids` to `bot.bot_owner_ids` as the attribute is now defined internally for team support. +- Deleting channel manually will now close the thread. +- Deleting messages will no longer cause the bot to produce warnings. +- Plugins will automatically be removed when it fails to load. +- Moved all database-related activities to clients.py under MongoDBClient, with possible future hook for additional database support. +- `bot.db` is deprecated in favour of `bot.api.db` and will be removed in the future. +- Deprecated `bot.plugin_db.get_partition` in favour of `bot.api.get_plugin_partition` (not final). +- Deprecated `MONGO_URI` config var (but will keep support in the future) in favour of `CONNECTION_URI` and `DATABASE_TYPE`. Right now there is one supported database - "mongodb", which is the default. + +### Fixed + +- Plugins not loading in Windows OS. Now uses proactor event loop for asyncio which should fix this. + + +# v3.4.1 + +### Fixed + +- Masked a bunch of noise errors when deleting messages. +- Added more checks for deleting messages. + +### Breaking + +- `thread_initiate` will be dispatched at the beginning of the setup process. +- `thread_create` is dispatched when the thread is registered as a thread by Modmail (i.e., when channel topic is edited). +- `thread_ready` is dispatched when a thread finishes its setup steps. -Translations WIP. # v3.4.0 @@ -26,35 +107,35 @@ Translations WIP. - Multi-command alias is now more stable. With support for a single quote escape `\"`. - New command `?freply`, which behaves exactly like `?reply` with the addition that you can substitute `{channel}`, `{recipient}`, and `{author}` to be their respective values. - New command `?repair`, repair any broken Modmail thread (with help from @officialpiyush). -- Recipient get feedback when they edit message. +- Recipients get feedback when they edit their messages. - Chained delete for DMs now comes with a message. - poetry (in case someone needs it). ### Changed - The look of alias and snippet when previewing. -- Message ID of the thread embed is saved in DB, instead of the original message. +- The database now saves the message ID of the thread embed, instead of the original message. - Swapped the position of user and category for `?contact`. - The log file will no longer grow infinitely large. -- Hard limit of maximum 25 steps for alias. +- A hard limit of a maximum of 25 steps for aliases. - `?disable` is now `?disable new`. ### Fixed - Setting config vars using human time wasn't working. - Fixed some bugs with aliases. -- Fixed a lot of issues with `?edit` and `?delete` and recipient message edit. +- Fixed many issues with `?edit` and `?delete` and recipient message edit. - Masked the error: "AttributeError: 'int' object has no attribute 'name'" - Channel delete event will not be checked until discord.py fixes this issue. -- Chained reaction add / remove. +- Chained reaction add/remove. - Chained delete for thread channels. ### Internal -- Commit to black format line width max = 99, consistent with pylint. -- Alias parser is rewritten without shlex. +- Commit to black format line width max = 99, consistent with PyLint. +- No longer requires shlex for alias parsing. - New checks with thread create / find. -- No more flake8 and travis. +- No more flake8 and Travis. # v3.3.2 @@ -78,19 +159,19 @@ Translations WIP. - Three new config vars: - `enable_plugins` (yes/no default yes) - - When set to no, plugins will not be loaded into the bot. + - When set to no, Modmail will not load plugins. - `error_color` (color format, defaults discord red) - The color of error messages. - `anon_reply_without_command` (yes/no default no) (Thanks to papiersnipper PR#288) - When set, all non-command messages sent to thread channels are forwarded to the recipient anonymously without the need of `?anonreply`. - This config takes precedence over `reply_without_command`. -- `?logs responded [user]` command, it will show all logs that the user has sent an reply. (Thanks to papiersnipper PR#288) +- `?logs responded [user]` command. It will show all the logs that the user has sent a reply. (Thanks to papiersnipper PR#288) - `user` when not provided, defaults to the user who ran the command. -- Open threads in limbo now auto closes if the channel cannot be found. This check is done every time the bot restarts. +- Open threads in limbo now auto-close if Modmail cannot find the channel. Modmail does this check every time the bot restarts. - Ability to disable new threads from getting created. - - `?disable` + - `?disable`. - Ability to fully disable Modmail DM. - - `?disable all` + - `?disable all`. - To re-enable DM: `?enable`, and to see the current status: `?isenable`. - This disabled Modmail interface is customizable with the following config vars: - `disabled_new_thread_title` @@ -104,33 +185,33 @@ Translations WIP. ### Changed -- `?contact` no longer send the "thread created" message to where the command is ran, instead, it's now sent to the newly created thread channel. (Thanks to DAzVise) +- `?contact` no longer send the "thread created" message to where the command was run, instead, it's now sent to the newly created thread channel. (Thanks to DAzVise) - Automatically delete notes command `?note` when there're no attachments attached. - Embed author links used to be inaccessible in many cases, now: - `?anonreply`, `?reply`, and `?note` in the thread channel will link to the sender's profile. - - `?reply` and recipient's DM will also link the sender's profile. + - `?reply` and the recipient's DM will also link the sender's profile. - `?anonreply` in DM channel will link to the first channel of the main guild. - Plugins update (mostly internal). - - `git` is no longer used to install plugins, it now downloads through zip files. + - `git` is no longer used to install plugins; it now downloads through zip files. - `?plugins enabled` renamed to `?plugins loaded` while `enabled` is still an alias to that command. - Reorganized plugins folder structure. - Logging / plugin-related messages change. - - Updating one plugin will not update all other plugins (plugins are no longer separated by repos, but the plugin name itself). -- Help command is in alphabetical order grouped by permissions. -- Notes are no longer always blurple, it's set to `MAIN_COLOR` now. + - Updating one plugin will not update other plugins; repositories no longer separate plugins, but the plugin name itself. +- The help command is in alphabetical order grouped by permissions. +- Notes are no longer always blurple; it's set to `MAIN_COLOR` now. - Added `?plugins update` for updating all installed plugins. - Reintroduce flake8 and use bandit for security issues detection. -- Add travis checks for 3.6 in Linux and 3.7 for MacOS and Windows. -- Eval commands are logged in debug logs. +- Add Travis checks for 3.6 in Linux and 3.7 for macOS and Windows. +- Debug logs not logs eval commands. - Presence updates 30 minutes instead of 45 now. -- Fixed an assortment of problems to do with block. +- Fixed an assortment of problems to do with `?block`. - Existing aliases can be used when creating new aliases. (Thanks to papiersnipper PR#402) ### Internal - Reworked `config.get` and `config.set`, it feeds through the converters before setting/getting. - To get/set the raw value, access through `config[]`. -- Prerelease naming scheme is now `x.x.x-devN`. +- The prerelease naming scheme is now `x.x.x-devN`. - `trigger_typing` has been moved to `core.utils.trigger_typing`, the original location is deprecated. - Simpler status and activity logic. - New logging logic. @@ -143,9 +224,9 @@ Security update! - Supporter permission users used to be able to "hack" snippets to reveal all your config vars, including your token and MongoURI. - Implemented some changes to address this bug: - - All customizable variables used in snippets, close messages, etc, using the `{}` syntax, now forbids chaining 2 or more attributes and attributes that starts with `_`. -- It is advised to update to this version. -- If you felt your credentials have been leaked, consider changing your bot token / mongo uri. + - All customizable variables used in snippets, close messages, etc., using the `{}` syntax, now forbids chaining two or more attributes and attributes that start with `_`. +- We advise you to update to this version. +- If you felt your credentials had been leaked, consider changing your bot token / MongoURI. # v3.2.1 @@ -175,7 +256,7 @@ Security update! ### Internal -- Use regex to parse Changes, Added, Fixed, etc and description. +- Use regex to parse Changes, Added, Fixed, etc. and description. - Adds `PermissionLevel.INVALID` when commands don't have a permission level. # v3.1.1 @@ -195,33 +276,33 @@ Security update! ### Added - `?sfw`, mark a thread as "safe for work", undos `?nsfw`. -- New config variable, `thread_auto_close_silently`, when set to a truthy value, no message will be sent when thread is auto-closed. +- New config variable, `thread_auto_close_silently`, when set to a truthy value, no message will be sent when a thread is auto-closed. - New configuration variable `thread_self_closable_creation_footer` — the footer when `recipient_thread_close` is enabled. - Added a minimalistic version of requirements.txt (named requirements.min.txt) that contains only the absolute minimum of Modmail. - For users having trouble with pipenv or any other reason. -- Multi-step alias, see `?help alias add`. Public beta testing, might be unstable. +- Multi-step alias, see `?help alias add`. Public beta testing might be unstable. - Misc commands without cogs are now displayed in `?help`. - `?help` works for alias and snippets. - `?config help ` shows a help embed for the configuration. -- Support setting permissions for sub commands. -- Support numbers (1-5) as substitutes for Permission Level REGULAR - OWNER in `?perms` sub commands. +- Support setting permissions for subcommands. +- Support numbers (1-5) as substitutes for Permission Level REGULAR - OWNER in `?perms` subcommands. ### Changes - `thread_auto_close_response` has a configurable variable `{timeout}`. - `?snippet` is now the default command name instead of `?snippets` (`?snippets` is still usable). This is to make this consistent with `?alias`/`?aliases`. -- `colorama` is no longer a necessity, this is due to some unsupported OS. -- Changelog command can now take a version argument to jump straight to specified version. +- `colorama` is no longer a necessity; this is due to some unsupported OS. +- Changelog command can now take a version argument to jump straight to the specified version. - `?plugin enabled` results are now sorted alphabetically. -- `?plugin registry` results are now sorted alphabetically, helps user find plugins more easily. +- `?plugin registry` results are now sorted alphabetically, helps users find plugins more easily. - `?plugin registry page-number` plugin registry can specify a page number for quick access. - A reworked interface for `?snippet` and `?alias`. - Add an `?snippet raw ` command for viewing the raw content of a snippet (escaped markdown). - - Add an `?alias raw ` command for viewing the raw content of a alias (escaped markdown). + - Add an `?alias raw ` command for displaying the raw content of an alias (escaped markdown). - The placeholder channel for the streaming status changed to https://www.twitch.tv/discordmodmail/. - Removed unclear `rm` alias for some `remove` commands. - Paginate `?config options`. -- All users configured with a permission level greater than REGULAR has access to the main Modmail category. +- All users configured with a permission level higher than REGULAR has access to the main Modmail category. - Category overrides also changes when a level is removed or added to a user or role. - `@everyone` is now accepted for `?perms add`. @@ -229,12 +310,12 @@ Security update! - `?notify` no longer carries over to the next thread. - `discord.NotFound` errors for `on_raw_reaction_add`. -- `mod_typing` ~~and `user_typing`~~ (`user_typing` is now by-design to show) will no longer show when user is blocked. +- `mod_typing` ~~and `user_typing`~~ (`user_typing` is now by-design to show) will no longer show when the user is blocked. - Better `?block` usage message. -- Resolves errors when message was sent by mods after thread is closed somehow. +- Resolved errors when mods sent messages after a thread is closed somehow. - Recipient join/leave server messages are limited to only the guild set by `GUILD_ID`. -- When creating snippets and aliases, it now checks if another snippets/aliases with the same name exists. -- Was looking for `config.json` in the wrong directory. +- When creating snippets and aliases, it now checks if other snippets/aliases with the same name exist. +- Modmail looked for `config.json` in the wrong directory. ### Internal @@ -254,13 +335,13 @@ Security update! ### Added - New commands, `?alias edit ` and `?snippets edit `. - - They can be used to edit aliases and snippets respectively. + - They can be used to edit aliases and snippets, respectively. # v3.0.2 ### Added -- New command, `?blocked whitelist `, this command prevents users from getting blocked by any means. +- A new command, `?blocked whitelist `, this command prevents users from getting blocked by any means. ### Changed @@ -270,30 +351,30 @@ Security update! ### Fixed -- A lot of bugs with `thread_auto_close` 😅 +- Many bugs with `thread_auto_close`. # v3.0.0 ### Added -- Sponsors command that will list sponsors. -- An alert will now be sent to the log channel if a thread channel fails to create. This could be due to a variety of problems such as insufficient permissions or the category channel limit is met. +- `?sponsors` command will list sponsors. +- An alert will now be sent to the log channel if a thread channel fails to create. This could be due to a variety of problems such as insufficient permissions, or the category channel limit is met. - Threads will close automatically after some time when `thread_auto_close` is set. -- Custom closing message can be set with `thread_auto_close_response`. +- Custom closing messages can be configured with `thread_auto_close_response`. ### Breaking Changes -- Removed autoupdate functionality and the `?update` command in favour of the [Pull app](https://github.com/apps/pull). +- Removed auto-update functionality and the `?update` command in favor of the [Pull app](https://github.com/apps/pull). Read more about updating your bot [here](https://github.com/kyb3r/modmail/wiki/updating) ### Changed -- Channel names now can contain unicode characters. -- Debug logs are now located in a unique file for each bot. (Internal change) +- Channel names now can contain Unicode characters. +- Debug logs are now located in a different file for each bot. (Internal change) - Default cogs always appear first in the help command now. ### Fixed -- Editing notes now works, minor bug with edit command is fixed. +- Editing notes now work, minor bug with edit command is fixed. - Bug in the `?oauth` command where the response message fails to send when an ID is provided. - Plugin requirement installation now works in virtual environments @@ -308,7 +389,7 @@ Fixed a bug with branches and `?plugin update`. ### Added -Branch support for `?plugin add` and in registry. Typically for developers. +Branch support for `?plugin add` and in the registry. Typically for developers. # v2.23.0 @@ -316,11 +397,11 @@ Branch support for `?plugin add` and in registry. Typically for developers. Added a "Mutual servers" field to the genesis embed if: a) The user is not in the main guild. -b) The user shares more than 1 server with the bot. +b) The user shares more than one server with the bot. ### Changed -Notes taken with the `?note` command are now automatically pinned within the thread channel. +Notes with the `?note` command are now automatically pinned within the thread channel. # v2.22.0 @@ -362,14 +443,14 @@ Add your plugin in the `plugins/registry.json` file in the main repository. This update contains mostly internal changes. - Implemented support for the new discord.py v1.1.1. - Improved help text for most commands. - - Completely revamped help command, few user changes. - - Removed abc (internal). + - Completely revamped help command, few users changes. + - Removed ABC (internal). # v2.20.0 ### What's new? -New `oauth` whitelist command which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app check the logviewer [repo](https://github.com/kyb3r/logviewer). +New `?oauth whitelist` command, which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app, check the logviewer [repo](https://github.com/kyb3r/logviewer). # v2.19.1 @@ -377,7 +458,7 @@ New `oauth` whitelist command which allows you to whitelist users so they can lo - Ability to force an update despite having the same version number. Helpful to keep up-to-date with the latest GitHub commit. - `?update force`. -- Plugin developers now have a new event called `on_plugin_ready`, this is coroutine is awaited when all plugins are loaded. Use `on_plugin_ready` instead of `on_ready` since `on_ready` will not get called in plugins. +- Plugin developers now have a new event called `on_plugin_ready`; this is a coroutine and is awaited when all plugins are loaded. Use `on_plugin_ready` instead of `on_ready` since `on_ready` will not get called in plugins. # v2.19.0 @@ -398,17 +479,17 @@ Fix the teams permission bug. ### Changed -Commands now have better error messages, instead of just sending the help message for a command when an argument fails to be converted to its specified object, the bot now says things like "User 'bob' not found" instead. +Commands now have better error messages. Instead of sending the help message for a command when an argument fails to be converted, the bot now says like "User 'bob' not found" instead. # v2.18.1 -Un-deprecated the `OWNERS` config variable to support discord developer team accounts. +Un-deprecated the `OWNERS` config variable to support Discord developer team accounts. # v2.18.0 ### New Permissions System -- A brand new permission system! Replacing the old guild-based permissions (ie. manage channels, manage messages), the new system enables you to customize your desired permission level specific to a command or a group of commands for a role or user. +- A brand new permission system! Replaced the old guild-based permissions (i.e., manage channels, manage messages), with the new system enables you to customize your desired permission level specific to a command or a group of commands for a role or user. - There are five permission levels: - Owner [5] - Administrator [4] @@ -427,7 +508,7 @@ You may add a role or user to a permission group through any of the following me The same applies to individual commands permissions: - `?permissions add command command-name @member#1234` -- ... and the other methods listed above. +- and the other methods listed above. To revoke permission, use `remove` instead of `add`. @@ -440,11 +521,11 @@ By default, all newly set up Modmail will have `OWNER` set to the owner of the b ### Breaking When updating to this version, all prior permission settings with guild-based permissions will be invalidated. You will need to convert to the above system. -`OWNERS` will also get removed, you will need to set owners through `?permissions add level owner 212931293123129` or any way listed above. +`OWNERS` will also get removed; you will need to set owners through `?permissions add level owner 212931293123129` or any way listed above. ### New Command -- A `?delete` command, which is an alternative to manually deleting a message. This command is created to no longer requires manage messages permission to recall thread messages. +- A `?delete` command, which is an alternative to manually deleting a message. This command is created to no longer require "manage messages" permission to recall thread messages. ### Changed @@ -465,28 +546,28 @@ Stricter fallback genesis embed search. ### Changed -How modmail checks if a channel is a thread: +How Modmail checks if a channel is a thread: -1. The bot first checks if the channel topic is in the format `User ID: xxxx`, this means it is a thread. -2. If a channel topic is not found, the bot searches through the message history of a channel to find the thread creation embed. This step should never yield a thread for a normal user, but in the case of another bot messing up the channel topic (happened to a user before) this extra step was added. +1. The bot first checks if the channel topic is in the format `User ID: XXXX`, this means it is a thread. +2. If a channel topic is not found, the bot searches through the message history of a channel to find the thread creation embed. This step should never yield a thread for an average user. Still, in the case of another bot messing up the channel topic (happened to a user before), this extra step was added. # v2.17.0 ### What's new? -Added a config option `reply_without_command` which when present, enables the bot to forward any message sent in a thread channel to the recipient. (Replying without using a command) +Added a config option `reply_without_command`, which, when present, enables the bot to forward any message sent in a thread channel to the recipient. (Replying without using a command) To enable this functionality, do `?config set reply_without_command true` and to disable it, use `?config del reply_without_command`. ### Changed -The `move` command now only requires `manage_messages` perms instead of `manage_channels` +The `move` command now only requires `manage_messages` perms instead of `manage_channels`. # v2.16.1 ### Fixed -An issue where a scheduled close would not execute over a long period of time if the recipient no shares any servers with the bot. +An issue where a scheduled close would not execute over a long time if the recipient no shares any servers with the bot. # v2.16.0 @@ -516,8 +597,8 @@ Added the ability to change the default close message via the introduction of tw They will be provided by string variables that you can incorporate into them: - `closer` - the user object that closed the thread. -- `logkey` - the key for the thread logs e.g. (`5219ccc82ad4`) -- `loglink` - the full link to the thread logs e.g. (`https://logwebsite.com/logs/5219ccc82ad4`) +- `logkey` - the key for the thread logs, e.g. (`5219ccc82ad4`) +- `loglink` - the full link to the thread logs, e.g. (`https://logwebsite.com/logs/5219ccc82ad4`) Example usage would be: ``?config set thread_close_message {closer.mention} closed the thread, here is the link to your logs: [**`{logkey}`**]({loglink})`` @@ -546,9 +627,9 @@ You now have complete control of the look of the thread creation and close embed ### What's new? -Added the ability to disable the `sent_emoji` and `blocked_emoji` when a user messages modmail. +Added the ability to disable the `sent_emoji` and `blocked_emoji` when a user messages Modmail. -You can do this via `?config set sent_emoji disable` +You can do this via `?config set sent_emoji disable`. ### Fixed @@ -565,17 +646,17 @@ Added image link in title in case discord fails to embed an image. - Introduced a new configuration variable `account_age` for setting a minimum account creation age. - Users blocked by this reason will be stored in `blocked` along with other reasons for being blocked. - `account_age` needs to be an ISO-8601 Duration Format (examples: `P12DT3H` 12 days and 3 hours, `P3Y5M` 3 years and 5 months `PT4H14M999S` 4 hours 14 minutes and 999 seconds). https://en.wikipedia.org/wiki/ISO_8601#Durations. - - You can set `account_age` using `config set account_age time` where "time" can be a simple human readable time string or an ISO-8601 Duration Format string. + - You can set `account_age` using `config set account_age time` where "time" can be a simple human-readable time string or an ISO-8601 Duration Format string. ### Changed -- `block` reason cannot start with `System Message: ` as it is now reserved for internal user blocking. -- `block`, like `close`, now supports a block duration (temp blocking). +- `?block` reason cannot start with `System Message: ` as it is now reserved for internal user blocking. +- `?block`, like `?close`, now supports a block duration (temp blocking). # v2.13.10 ### Fixed - Fixed an issue where status and activity do not work if they were modified wrongly in the database. - - This was especially an issue for older Modmail users, as the old `status` configuration variable clashes with the new `status` variable. + - This was primarily an issue for older Modmail users, as the old `status` configuration variable clashes with the new `status` variable. # v2.13.9 @@ -594,7 +675,7 @@ Added image link in title in case discord fails to embed an image. ### What's new? - The ability to enable typing interactions. - - If you want the bot to type in the thread channel if the user is also typing, add the config variable `user_typing` and set it to "yes" or "true". use `config del` to disable the functionality. The same thing in reverse is also possible if you want the user to see the bot type when someone is typing in the thread channel add the `mod_typing` config variable. + - If you want the bot to type in the thread channel if the user is also typing, add the config variable `user_typing` and set it to "yes" or "true". Use `config del` to disable the functionality. The same thing in reverse is also possible if you want the user to see the bot type when someone is typing in the thread channel add the `mod_typing` config variable. - New `status` command, change the bot's status to `online`, `idle`, `dnd`, `invisible`, or `offline`. - To remove the status (change it back to default), use `status clear`. - This also introduces a new internal configuration variable: `status`. Possible values are `online`, `idle`, `dnd`, `invisible`, and `offline`. @@ -611,15 +692,15 @@ Added image link in title in case discord fails to embed an image. ### What's new? - You will no longer need to view your bot debug logs from Heroku. `debug` will show you the recent logs within 24h through a series of embeds. - - If you don't mind your data (may or may not be limited to: user ID, guild ID, bot name) be on the internet, `debug hastebin` will upload a formatted logs file to https://hasteb.in. + - If you don't mind your data (may or may not be limited to user ID, guild ID, bot name) be on the internet, `debug hastebin` will upload a formatted logs file to https://hasteb.in. - `debug clear` will clear the locally cached logs. - - Local logs are automatically cleared at least once every 27h for bots hosted on Heroku. + - Local logs are automatically erased at least once every 27h for bots hosted on Heroku. ### Fixed -- Will no longer show `Unclosed client session` and `Task was destroyed but it is pending!` when the bot terminates. +- Will no longer show `Unclosed client session` and `Task was destroyed, but it is pending!` when the bot terminates. - `thread.create` is now synchronous so that the first message sent can be queued to be sent as soon as a thread is created. - This fixes a problem where if multiple messages are sent in quick succession, the first message sent (which triggers the thread creation) is not sent in order. -- Trying to reply to someone who has DMs disabled or has blocked the bot is now handled and the bot will send a message saying so. +- Trying to reply to someone who has DMs disabled or has blocked the bot is now handled, and the bot will send a message saying so. ### Changed - `print` is replaced by logging. @@ -653,14 +734,14 @@ Added image link in title in case discord fails to embed an image. ### What's new? - Plugins: - - Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it. Add a welcome message to Modmail, or moderation commands? It's all up to your imagination! Have a niche feature request that you think only your server would benefit from? Plugins are your go-to! + - Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it. Add a welcome message to Modmail, or moderation commands? It's all up to your imagination! Have a niche feature request that you think only your server would benefit? Plugins are your go-to! - [Creating Plugins Documentation](https://github.com/kyb3r/modmail/wiki/Plugins). # v2.12.5 ### Fixed -- `config del` command will now work properly on self-hosted db bots. +- `config del` command will now work correctly on self-hosted DB bots. # v2.12.4 @@ -674,14 +755,14 @@ Added image link in title in case discord fails to embed an image. ### Fixed - Patched a bug where `logs` sub-commands were accessible by anyone. -- Patched a bug where an error was raised if there was an open thread where the recipient had left the server. +- Patched a bug where an error was raised when a thread is open where the recipient left the server. Huge thanks to Sasiko for reporting these issues. # v2.12.2 ### Fixed -- Fixed a bug in self-hosted `update` command. +- Fixed a bug in self-hosted `?update` command. # v2.12.1 @@ -692,12 +773,12 @@ Huge thanks to Sasiko for reporting these issues. # v2.12.0 ### Important -**In the future, the Modmail API (https://modmail.tk) will be deprecated. This is due to the fact that we are providing a free service without getting anything in return, and thus we do not have the resources to scale to accommodate for more users. +**In the future, the Modmail API (https://modmail.tk) will be deprecated. This is because we are providing free service without getting anything in return. Thus we do not have the resources to scale to accommodate more users. We recommend using your own database for logs. In the future you will soon get a `backup` command so you can download all your pre-existing data and migrate to your own database.** ### Changed - A lot of painful code cleanup, which is good for us (the developers), but shouldn't affect you. -- The appearance of the `logs` command. Should be clearer with better info now. +- The appearance of the `?logs` command. It should be clearer with better info now. - Bot owners get access to all commands regardless of server permissions. - Blocked users no longer receive a message, only the blocked emoji will be sent. @@ -705,10 +786,10 @@ We recommend using your own database for logs. In the future you will soon get a - **Note:** The following commands only work if you are self-hosting your logs. We recommend you to use your own database. - Log search queries, in the form of two new commands. - `logs search [query]` - this searches all log messages for a query string. -- `logs closed-by [user]` this returns all logs closed by a certain user +- `logs closed-by [user]` this returns all logs closed by a particular user ### Fixed -- `activity listening to music` no longer result in two "to"s ("listening to to music"). +- `activity listening to music` no longer results in two "to"s ("listening to to music"). - This may require you to change your activity message to accommodate this fix. - A problem where `main_category_id` and `log_channel_id` weren't updated when their corresponding channel or category get deleted. @@ -731,7 +812,7 @@ We recommend using your own database for logs. In the future you will soon get a ### What's new? - `anonreply` command to anonymously reply to the recipient. -The username of the anonymous user defaults to the `mod_tag` (the footer text of a mod reply message). The avatar defaults the guild icon URL. However you can change both of these via the `anon_username`, `anon_avatar_url` and `anon_tag` config variables. +The username of the anonymous user defaults to the `mod_tag` (the footer text of a mod reply message) — the avatar defaults to the guild icon URL. However, you can change both of these via the `anon_username`, `anon_avatar_url`, and `anon_tag` config variables. ### Changed - Your bot now logs all messages sent in a thread channel, including discussions that take place. You can now toggle to view them in the log viewer app. @@ -756,7 +837,7 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of - All commands are now blurple instead of green. ### Fixed -- Bug where the close command wouldn't work if you didnt configure a log channel. +- Bug where the close command wouldn't work if you didn't configure a log channel. ### What's new? - Ability to set your own custom `mod_color` and `recipient_color` for the thread message embeds. @@ -773,13 +854,13 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of # v2.9.0 ### What's new? -- New command `note` will add a system message to your thread logs. This is useful for noting the context of a conversation. +- New command `note` will add a system message to your thread logs. - - This is useful for noting the context of a conversation. # v2.8.1 ### Fixed - Fixed bug where thread logs were getting duplicated when using the `contact` command. -- Fixed bug where the wrong key was used for logs which caused some `log` command log links to point to an HTTP 404 Not Found. +- Fixed bug where the wrong key was used for logs, which caused some `log` command log links to point to an HTTP 404 Not Found. - A minor oversight from commit 1ba74d9. # v2.8.0 @@ -796,7 +877,7 @@ The username of the anonymous user defaults to the `mod_tag` (the footer text of ### Security Thread channels will now default to being private (`@everyone`'s read message perms set to `false`). - If the thread creation category could not be resolved. - - This will save you from some trouble if for whatever reason your configuration gets messed up. + - This will save you from some trouble if, for whatever reason, your configuration gets messed up. # v2.7.1 @@ -808,20 +889,20 @@ Thread channels will now default to being private (`@everyone`'s read message pe ### Note -- If your Modmail bot was set up a long time ago, you may experience an issue where messages were sent outside of the category. +- If your Modmail bot was set up a long time ago, you might experience an issue where messages were sent outside of the category. - To fix this, set `main_category_id` to the ID of the Modmail category. # v2.7.0 ### Changed -- `move` command now syncs thread channel permissions with the category that it was moved to. +- `move` command now syncs thread channel permissions with the destination category. - `contact` command now supports an optional category argument (where the thread channel will be created). # v2.6.3 ### Fixes -- Fixed small issue with finding thread. +- Fixed small issue with finding threads. # v2.6.2 @@ -841,8 +922,8 @@ Thread channels will now default to being private (`@everyone`'s read message pe ### Changed - Log URLs are moved to their own collection. - Log URLs are now `https://logs.modmail.tk/LOGKEY`, no more numbers before the log key. -- We still support the numbers so as to not break everyone's URLs so quickly but both work at the moment. -- This is a huge change to the backend logging and there might be migration errors. If so, please contact us in our [discord server](https://discord.gg/2fMbf2N). +- We still support the numbers to not break everyone's URLs so quickly, but both work at the moment. +- This is a huge change to the backend logging, and there might be migration errors. If so, please contact us in our [Discord server](https://discord.gg/2fMbf2N). # v2.5.2 @@ -852,13 +933,13 @@ Thread channels will now default to being private (`@everyone`'s read message pe # v2.5.1 ### Fixes -- Emergency patch to save config. +- Emergency patch to save configs. # v2.5.0 ### Background - Bots hosted by Heroku restart at least once every 27 hours. -- During this period, local caches are deleted, which results in the inability to set the scheduled close time to longer than 24 hours. This update resolves this issue. +- During this period, local caches will be deleted, which results in the inability to set the scheduled close time to longer than 24 hours. This update resolves this issue. - [PR #135](https://github.com/kyb3r/modmail/pull/135) ### Changed @@ -876,7 +957,7 @@ Fixed activity setting due to flawed logic in `config.get()` function. # v2.4.4 ### Fixed -Fixed a bug in activity command where it would fail to set the activity on bot restart if the activity type was `playing`. +Fixed a bug in the `?activity` command where it would fail to set the activity on bot restart if the activity type was `playing`. # v2.4.3 @@ -891,17 +972,17 @@ Fixed a bug in activity command where it would fail to set the activity on bot r # v2.4.1 ### Fixed -- Small bug in `activity` command. +- Small bug in `?activity` command. # v2.4.0 ### What's new? -- Added the `activity` command for setting the activity -- [PR #131](https://github.com/kyb3r/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening` and `streaming`). +- Added the `?activity` command for setting the activity +- [PR #131](https://github.com/kyb3r/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening`, and `streaming`). ### Removed - Removed the deprecated `status` command. -- This also means you will have to reset your bot status with the `activity` command, as `status` command is removed. +- This also means you will have to reset your bot status with the `?activity` command, as the `?status` command was removed. # v2.3.0 @@ -922,7 +1003,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### What's new? - Notify command `notify [role]`. - Notify a given role or yourself to the next thread message received. - - Once a thread message is received you will be pinged once only. + - Once a thread message is received, you will be pinged once only. - Subscribe command `sub [role]` / `unsub [role]`. - Subscribes yourself or a given role to be notified when thread messages are received. @@ -939,15 +1020,15 @@ Fixed a bug in activity command where it would fail to set the activity on bot r # v2.1.0 ### What's new? -- Ability to set a custom thread creation response message. +- Ability to set a custom thread-creation-response message. - Via `config set thread_creation_response [message]`. ### Changed -- Improve logs command format. -- Improve thread log channel message to have more relevant info. +- Improve `?logs` command format. +- Improve thread log channel messages to have more relevant info. - Improve close command. - - You now can close the thread after a delay and use a custom thread close message. - - You also now have the ability to close a thread silently. + - You can now close the thread after a delay and use a custom thread close message. + - You also now can close a thread silently. # v2.0.10 @@ -962,7 +1043,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Fixes - Support multiple images and file attachments in one message. -- This is only possible on mobile so its good to handle it in code. +- This is only possible on mobile, so its good to handle it in code. # v2.0.8 @@ -973,7 +1054,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r - You can do this via the `config set main_category_id ` command. ### Changed -- You now have the ability to supply a reason when blocking a user. +- You can now supply a reason when blocking a user. - Blocked users are now stored in the database instead of in the channel topic. - This means you can delete the top channel in the Modmail category now (after migrating the currently blocked users). @@ -984,8 +1065,8 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Changed - `update` command now shows the latest changes directly from CHANGELOG.md. -- Auto update messages also show the latest changes from the GitHub repo. -- Removed "latest changes" section from the `about` command. +- Auto-update messages also show the latest changes from the GitHub repo. +- Removed the "latest changes" section from the `about` command. # v2.0.6 @@ -998,20 +1079,20 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Changed - `alias` command now checks if you are adding a valid alias-command combo. -- Deleting a channel manually will now correctly close the thread and post logs. +- Manually deleting a channel will now correctly close the thread and post logs. # v2.0.4 ### Fixed -- Fixed a one-off bug where the channel topic disappears, but Modmail operations should still continue. +- Fixed a one-off bug where the channel topic disappears, but Modmail operations should continue. - Fixed `linked_message_id` issues. # v2.0.3 ### Fixed -- Thread creation embed now shows the correct number of past logs. +- The thread creation embed now shows the correct number of past logs. - If using a separate server setup, roles in the info embed now are shown as names instead of mentions. - - This is due to the fact that you can't mention roles across servers. + - This is because you can't mention roles across servers. # v2.0.2 @@ -1023,7 +1104,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r ### Changed - Improved `block` / `unblock` commands. - - They now take a wider range of arguments: usernames, nicknames, mentions and user IDs. + - They now take a more comprehensive range of arguments: usernames, nicknames, mentions, and user IDs. ### Fixed - Setup command now configures permissions correctly so that the bot will always be able to see the main operations category. @@ -1031,7 +1112,7 @@ Fixed a bug in activity command where it would fail to set the activity on bot r # v2.0.0 This release introduces the use of our centralized [API service](https://github.com/kyb3r/webserver) to enable dynamic configuration, auto-updates, and thread logs. -To use this release you must acquire an API token from https://modmail.tk. +To use this release, you must acquire an API token from https://modmail.tk. Read the updated installation guide [here](https://github.com/kyb3r/modmail/wiki/installation). ### Changed diff --git a/Pipfile b/Pipfile index 9173c3a5fe..01485b1e63 100644 --- a/Pipfile +++ b/Pipfile @@ -4,27 +4,25 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -black = "==19.3b0" +black = "==19.10b0" pylint = "*" bandit = "==1.6.2" +flake8 = "*" [packages] colorama = ">=0.4.0" python-dateutil = ">=2.7.0" emoji = ">=0.2" -uvloop = {version=">=0.12.0", sys_platform = "!= 'win32'"} +uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} motor = ">=2.0.0" natural = "==0.2.0" isodate = ">=0.6.0" dnspython = "~=1.16.0" -parsedatetime = "==2.5" -aiohttp = "<3.6.0,>=3.3.0" +parsedatetime = "==2.6" +aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -"discord.py" = "==1.2.5" - -[requires] -python_version = "3.7" +"discord.py" = "==1.5.1" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 06d263645b..005ce37f67 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,12 +1,10 @@ { "_meta": { "hash": { - "sha256": "c2eb0898f236534a02cb1c198d74c82fed052b4445e39f99c1af3e58d22aa435" + "sha256": "0491618cb8bd6d70e4ab3337c23b72fc3b1d5f9ca0603d8be6b890b661039102" }, "pipfile-spec": 6, - "requires": { - "python_version": "3.7" - }, + "requires": {}, "sources": [ { "name": "pypi", @@ -18,52 +16,52 @@ "default": { "aiohttp": { "hashes": [ - "sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55", - "sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed", - "sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10", - "sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5", - "sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1", - "sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939", - "sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390", - "sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa", - "sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc", - "sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5", - "sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d", - "sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf", - "sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6", - "sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72", - "sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12", - "sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366", - "sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4", - "sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300", - "sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d", - "sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303", - "sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6", - "sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889" + "sha256:1a4160579ffbc1b69e88cb6ca8bb0fbd4947dfcbf9fb1e2a4fc4c7a4a986c1fe", + "sha256:206c0ccfcea46e1bddc91162449c20c72f308aebdcef4977420ef329c8fcc599", + "sha256:2ad493de47a8f926386fa6d256832de3095ba285f325db917c7deae0b54a9fc8", + "sha256:319b490a5e2beaf06891f6711856ea10591cfe84fe9f3e71a721aa8f20a0872a", + "sha256:470e4c90da36b601676fe50c49a60d34eb8c6593780930b1aa4eea6f508dfa37", + "sha256:60f4caa3b7f7a477f66ccdd158e06901e1d235d572283906276e3803f6b098f5", + "sha256:66d64486172b032db19ea8522328b19cfb78a3e1e5b62ab6a0567f93f073dea0", + "sha256:687461cd974722110d1763b45c5db4d2cdee8d50f57b00c43c7590d1dd77fc5c", + "sha256:698cd7bc3c7d1b82bb728bae835724a486a8c376647aec336aa21a60113c3645", + "sha256:797456399ffeef73172945708810f3277f794965eb6ec9bd3a0c007c0476be98", + "sha256:a885432d3cabc1287bcf88ea94e1826d3aec57fd5da4a586afae4591b061d40d", + "sha256:c506853ba52e516b264b106321c424d03f3ddef2813246432fa9d1cefd361c81", + "sha256:fb83326d8295e8840e4ba774edf346e87eca78ba8a89c55d2690352842c15ba5" ], "index": "pypi", - "version": "==3.5.4" + "version": "==3.6.3" + }, + "appdirs": { + "hashes": [ + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" + ], + "version": "==1.4.4" }, "async-timeout": { "hashes": [ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], + "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", + "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" ], - "version": "==19.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.2.0" }, "certifi": { "hashes": [ - "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", - "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" + "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", + "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" ], - "version": "==2019.11.28" + "version": "==2020.6.20" }, "chardet": { "hashes": [ @@ -74,18 +72,26 @@ }, "colorama": { "hashes": [ - "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", - "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1" + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], "index": "pypi", - "version": "==0.4.3" + "version": "==0.4.4" }, "discord.py": { "hashes": [ - "sha256:7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d" + "sha256:2367359e31f6527f8a936751fc20b09d7495dd6a76b28c8fb13d4ca6c55b7563", + "sha256:def00dc50cf36d21346d71bc89f0cad8f18f9a3522978dc18c7796287d47de8b" ], "index": "pypi", - "version": "==1.2.5" + "version": "==1.5.1" + }, + "distlib": { + "hashes": [ + "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb", + "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1" + ], + "version": "==0.3.1" }, "dnspython": { "hashes": [ @@ -97,17 +103,25 @@ }, "emoji": { "hashes": [ - "sha256:60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174" + "sha256:e42da4f8d648f8ef10691bc246f682a1ec6b18373abfd9be10ec0b398823bd11" ], "index": "pypi", - "version": "==0.5.4" + "version": "==0.6.0" + }, + "filelock": { + "hashes": [ + "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", + "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" + ], + "version": "==3.0.12" }, "idna": { "hashes": [ - "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", - "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", + "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "version": "==2.8" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.10" }, "isodate": { "hashes": [ @@ -119,34 +133,34 @@ }, "motor": { "hashes": [ - "sha256:599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", - "sha256:756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", - "sha256:97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a" + "sha256:428d94750123d19fcd0a89b8671ff9b4656f205217bad9f44161748c64c5fc80", + "sha256:f1692b760d834707e3477996ce8d407af8cd61c1a2abedbf81c22ef14675e61a" ], "index": "pypi", - "version": "==2.1.0" + "version": "==2.3.0" }, "multidict": { "hashes": [ - "sha256:09c19f642e055550c9319d5123221b7e07fc79bda58122aa93910e52f2ab2f29", - "sha256:0c1a5d5f7aa7189f7b83c4411c2af8f1d38d69c4360d5de3eea129c65d8d7ce2", - "sha256:12f22980e7ed0972a969520fb1e55682c9fca89a68b21b49ec43132e680be812", - "sha256:258660e9d6b52de1a75097944e12718d3aa59adc611b703361e3577d69167aaf", - "sha256:3374a23e707848f27b3438500db0c69eca82929337656fce556bd70031fbda74", - "sha256:503b7fce0054c73aa631cc910a470052df33d599f3401f3b77e54d31182525d5", - "sha256:6ce55f2c45ffc90239aab625bb1b4864eef33f73ea88487ef968291fbf09fb3f", - "sha256:725496dde5730f4ad0a627e1a58e2620c1bde0ad1c8080aae15d583eb23344ce", - "sha256:a3721078beff247d0cd4fb19d915c2c25f90907cf8d6cd49d0413a24915577c6", - "sha256:ba566518550f81daca649eded8b5c7dd09210a854637c82351410aa15c49324a", - "sha256:c42362750a51a15dc905cb891658f822ee5021bfbea898c03aa1ed833e2248a5", - "sha256:cf14aaf2ab067ca10bca0b14d5cbd751dd249e65d371734bc0e47ddd8fafc175", - "sha256:cf24e15986762f0e75a622eb19cfe39a042e952b8afba3e7408835b9af2be4fb", - "sha256:d7b6da08538302c5245cd3103f333655ba7f274915f1f5121c4f4b5fbdb3febe", - "sha256:e27e13b9ff0a914a6b8fb7e4947d4ac6be8e4f61ede17edffabd088817df9e26", - "sha256:e53b205f8afd76fc6c942ef39e8ee7c519c775d336291d32874082a87802c67c", - "sha256:ec804fc5f68695d91c24d716020278fcffd50890492690a7e1fef2e741f7172c" - ], - "version": "==4.7.1" + "sha256:1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", + "sha256:275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", + "sha256:3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", + "sha256:4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", + "sha256:5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", + "sha256:51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", + "sha256:5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", + "sha256:6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", + "sha256:7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", + "sha256:9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", + "sha256:c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", + "sha256:d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", + "sha256:e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", + "sha256:f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", + "sha256:fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", + "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", + "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" + ], + "markers": "python_version >= '3.5'", + "version": "==4.7.6" }, "natural": { "hashes": [ @@ -157,78 +171,79 @@ }, "parsedatetime": { "hashes": [ - "sha256:3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1", - "sha256:d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667" + "sha256:4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455", + "sha256:cb96edd7016872f58479e35879294258c71437195760746faffedb692aef000b" ], "index": "pypi", - "version": "==2.5" + "version": "==2.6" }, "pipenv": { "hashes": [ - "sha256:56ad5f5cb48f1e58878e14525a6e3129d4306049cb76d2f6a3e95df0d5fc6330", - "sha256:7df8e33a2387de6f537836f48ac6fcd94eda6ed9ba3d5e3fd52e35b5bc7ff49e", - "sha256:a673e606e8452185e9817a987572b55360f4d28b50831ef3b42ac3cab3fee846" + "sha256:448ac3a36443db633d52a2359cac15ecbc4f429eab4ddd420697602b721d1c5a", + "sha256:eff0e10eadb330f612edfa5051d3d8e775e9e0e918c3c50361da703bd0daa035" ], "index": "pypi", - "version": "==2018.11.26" + "version": "==2020.8.13" }, "pymongo": { "hashes": [ - "sha256:0369136c6e79c5edc16aa5de2b48a1b1c1fe5e6f7fc5915a2deaa98bd6e9dad5", - "sha256:08364e1bea1507c516b18b826ec790cb90433aec2f235033ec5eecfd1011633b", - "sha256:0af1d2bc8cc9503bf92ec3669a77ec3a6d7938193b583fb867b7e9696eed52e8", - "sha256:0cfd1aeeb8c0a634646ab3ebeb4ce6828b94b2e33553a69ff7e6c07c250bf201", - "sha256:1b4a13dff15641e58620524db15d7a323d60572b2b187261c5cb58c36d74778d", - "sha256:22fbdb908257f9aaaa372a7684f3e094a05ca52eb84f8f381c8b1827c49556fd", - "sha256:264272fd1c95fc48002ad85d5e41270831777b4180f2500943e45e12b2a3ab43", - "sha256:3372e98eebbfd05ebf020388003f8a4438bed41e0fef1ef696d2c13633c416c8", - "sha256:339d24ecdc42745d2dc09b26fda8151988e806ca81134a7bd10513c4031d91e1", - "sha256:38281855fc3961ba5510fbb503b8d16cc1fcb326e9f7ba0dd096ed4eb72a7084", - "sha256:4acdd2e16392472bfd49ca49038845c95e5254b5af862b55f7f2cc79aa258886", - "sha256:4e0c006bc6e98e861b678432e05bf64ba3eb889b6ab7e7bf1ebaecf9f1ba0e58", - "sha256:4e4284bcbe4b7be1b37f9641509085b715c478e7fbf8f820358362b5dd359379", - "sha256:4e5e94a5f9823f0bd0c56012a57650bc6772636c29d83d253260c26b908fcfd9", - "sha256:4e61f30800a40f1770b2ec56bbf5dc0f0e3f7e9250eb05fa4feb9ccb7bbe39ca", - "sha256:53577cf57ba9d93b58ab41d45250277828ff83c5286dde14f855e4b17ec19976", - "sha256:681cb31e8631882804a6cc3c8cc8f54a74ff3a82261a78e50f20c5eec05ac855", - "sha256:6dfc2710f43dd1d66991a0f160d196356732ccc8aa9dbc6875aeba78388fa142", - "sha256:72218201b13d8169be5736417987e9a0a3b10d4349e40e4db7a6a5ac670c7ef2", - "sha256:7247fbcdbf7ab574eb70743461b3cfc14d9cfae3f27a9afb6ce14d87f67dd0b5", - "sha256:72651f4b4adf50201891580506c8cca465d94d38f26ed92abfc56440662c723c", - "sha256:87b3aaf12ad6a9b5570b12d2a4b8802757cb3588a903aafd3c25f07f9caf07e3", - "sha256:87c28b7b37617c5a01eb396487f7d3b61a453e1fa0475a175ab87712d6f5d52f", - "sha256:88efe627b628f36ef53f09abb218d4630f83d8ebde7028689439559475c43dae", - "sha256:89bfbca22266f12df7fb80092b7c876734751d02b93789580b68957ad4a8bf56", - "sha256:908a3caf348a672b28b8a06fe7b4a27c2fdcf7f873df671e4027d48bcd7f971f", - "sha256:9128e7bea85f3a3041306fa14a7aa82a24b47881918500e1b8396dd1c933b5a6", - "sha256:9737d6d688a15b8d5c0bfa909638b79261e195be817b9f1be79c722bbb23cd76", - "sha256:98a8305da158f46e99e7e51db49a2f8b5fcdd7683ea7083988ccb9c4450507a6", - "sha256:99285cd44c756f0900cbdb5fe75f567c0a76a273b7e0467f23cb76f47e60aac0", - "sha256:9ed568f8026ffeb00ce31e5351e0d09d704cc19a29549ba4da0ac145d2a26fdf", - "sha256:a006162035032021dfd00a879643dc06863dac275f9210d843278566c719eebc", - "sha256:a03cb336bc8d25a11ff33b94967478a9775b0d2b23b39e952d9cc6cb93b75d69", - "sha256:a863ceb67be163060d1099b7e89b6dd83d6dd50077c7ceae31ac844c4c2baff9", - "sha256:b82628eaf0a16c1f50e1c205fd1dd406d7874037dd84643da89e91b5043b5e82", - "sha256:bc6446a41fb7eeaf2c808bab961b9bac81db0f5de69eab74eebe1b8b072399f7", - "sha256:c42d290ed54096355838421cf9d2a56e150cb533304d2439ef1adf612a986eaf", - "sha256:c43879fe427ea6aa6e84dae9fbdc5aa14428a4cfe613fe0fee2cc004bf3f307c", - "sha256:c566cbdd1863ba3ccf838656a1403c3c81fdb57cbe3fdd3515be7c9616763d33", - "sha256:c5b7a0d7e6ca986de32b269b6dbbd5162c1a776ece72936f55decb4d1b197ee9", - "sha256:ca109fe9f74da4930590bb589eb8fdf80e5d19f5cd9f337815cac9309bbd0a76", - "sha256:d0260ba68f9bafd8775b2988b5aeace6e69a37593ec256e23e150c808160c05c", - "sha256:d2ce33501149b373118fcfec88a292a87ef0b333fb30c7c6aac72fe64700bdf6", - "sha256:d582ea8496e2a0e124e927a67dca55c8833f0dbfbc2c84aaf0e5949a2dd30c51", - "sha256:d68b9ab0a900582a345fb279675b0ad4fac07d6a8c2678f12910d55083b7240d", - "sha256:dbf1fa571db6006907aeaf6473580aaa76041f4f3cd1ff8a0039fd0f40b83f6d", - "sha256:e032437a7d2b89dab880c79379d88059cee8019da0ff475d924c4ccab52db88f", - "sha256:e0f5798f3ad60695465a093e3d002f609c41fef3dcb97fcefae355d24d3274cf", - "sha256:e756355704a2cf91a7f4a649aa0bbf3bbd263018b9ed08f60198c262f4ee24b6", - "sha256:e824b4b87bd88cbeb25c8babeadbbaaaf06f02bbb95a93462b7c6193a064974e", - "sha256:ea1171470b52487152ed8bf27713cc2480dc8b0cd58e282a1bff742541efbfb8", - "sha256:fa19aef44d5ed8f798a8136ff981aedfa508edac3b1bed481eca5dde5f14fd3d", - "sha256:fceb6ae5a149a42766efb8344b0df6cfb21b55c55f360170abaddb11d43af0f1" - ], - "version": "==3.10.0" + "sha256:03dc64a9aa7a5d405aea5c56db95835f6a2fa31b3502c5af1760e0e99210be30", + "sha256:05fcc6f9c60e6efe5219fbb5a30258adb3d3e5cbd317068f3d73c09727f2abb6", + "sha256:076a7f2f7c251635cf6116ac8e45eefac77758ee5a77ab7bd2f63999e957613b", + "sha256:137e6fa718c7eff270dbd2fc4b90d94b1a69c9e9eb3f3de9e850a7fd33c822dc", + "sha256:1f865b1d1c191d785106f54df9abdc7d2f45a946b45fd1ea0a641b4f982a2a77", + "sha256:213c445fe7e654621c6309e874627c35354b46ef3ee807f5a1927dc4b30e1a67", + "sha256:25e617daf47d8dfd4e152c880cd0741cbdb48e51f54b8de9ddbfe74ecd87dd16", + "sha256:3d9bb1ba935a90ec4809a8031efd988bdb13cdba05d9e9a3e9bf151bf759ecde", + "sha256:40696a9a53faa7d85aaa6fd7bef1cae08f7882640bad08c350fb59dee7ad069b", + "sha256:421aa1b92c291c429668bd8d8d8ec2bd00f183483a756928e3afbf2b6f941f00", + "sha256:4437300eb3a5e9cc1a73b07d22c77302f872f339caca97e9bf8cf45eca8fa0d2", + "sha256:455f4deb00158d5ec8b1d3092df6abb681b225774ab8a59b3510293b4c8530e3", + "sha256:475a34a0745c456ceffaec4ce86b7e0983478f1b6140890dff7b161e7bcd895b", + "sha256:4797c0080f41eba90404335e5ded3aa66731d303293a675ff097ce4ea3025bb9", + "sha256:4ae23fbbe9eadf61279a26eba866bbf161a6f7e2ffad14a42cf20e9cb8e94166", + "sha256:4b32744901ee9990aa8cd488ec85634f443526def1e5190a407dc107148249d7", + "sha256:50127b13b38e8e586d5e97d342689405edbd74ad0bd891d97ee126a8c7b6e45f", + "sha256:50531caa7b4be1c4ed5e2d5793a4e51cc9bd62a919a6fd3299ef7c902e206eab", + "sha256:63a5387e496a98170ffe638b435c0832c0f2011a6f4ff7a2880f17669fff8c03", + "sha256:68220b81850de8e966d4667d5c325a96c6ac0d6adb3d18935d6e3d325d441f48", + "sha256:689142dc0c150e9cb7c012d84cac2c346d40beb891323afb6caf18ec4caafae0", + "sha256:6a15e2bee5c4188369a87ed6f02de804651152634a46cca91966a11c8abd2550", + "sha256:7122ffe597b531fb065d3314e704a6fe152b81820ca5f38543e70ffcc95ecfd4", + "sha256:7307024b18266b302f4265da84bb1effb5d18999ef35b30d17592959568d5c0a", + "sha256:7a4a6f5b818988a3917ec4baa91d1143242bdfece8d38305020463955961266a", + "sha256:83c5a3ecd96a9f3f11cfe6dfcbcec7323265340eb24cc996acaecea129865a3a", + "sha256:890b0f1e18dbd898aeb0ab9eae1ab159c6bcbe87f0abb065b0044581d8614062", + "sha256:8deda1f7b4c03242f2a8037706d9584e703f3d8c74d6d9cac5833db36fe16c42", + "sha256:8ea13d0348b4c96b437d944d7068d59ed4a6c98aaa6c40d8537a2981313f1c66", + "sha256:91e96bf85b7c07c827d339a386e8a3cf2e90ef098c42595227f729922d0851df", + "sha256:96782ebb3c9e91e174c333208b272ea144ed2a684413afb1038e3b3342230d72", + "sha256:9755c726aa6788f076114dfdc03b92b03ff8860316cca00902cce88bcdb5fedd", + "sha256:9dbab90c348c512e03f146e93a5e2610acec76df391043ecd46b6b775d5397e6", + "sha256:9ee0eef254e340cc11c379f797af3977992a7f2c176f1a658740c94bf677e13c", + "sha256:9fc17fdac8f1973850d42e51e8ba6149d93b1993ed6768a24f352f926dd3d587", + "sha256:a2787319dc69854acdfd6452e6a8ba8f929aeb20843c7f090e04159fc18e6245", + "sha256:b7c522292407fa04d8195032493aac937e253ad9ae524aab43b9d9d242571f03", + "sha256:bd312794f51e37dcf77f013d40650fe4fbb211dd55ef2863839c37480bd44369", + "sha256:c0d660a186e36c526366edf8a64391874fe53cf8b7039224137aee0163c046df", + "sha256:c4869141e20769b65d2d72686e7a7eb141ce9f3168106bed3e7dcced54eb2422", + "sha256:cc4057f692ac35bbe82a0a908d42ce3a281c9e913290fac37d7fa3bd01307dfb", + "sha256:cccf1e7806f12300e3a3b48f219e111000c2538483e85c869c35c1ae591e6ce9", + "sha256:ce208f80f398522e49d9db789065c8ad2cd37b21bd6b23d30053474b7416af11", + "sha256:d0565481dc196986c484a7fb13214fc6402201f7fb55c65fd215b3324962fe6c", + "sha256:d1b3366329c45a474b3bbc9b9c95d4c686e03f35da7fd12bc144626d1f2a7c04", + "sha256:d226e0d4b9192d95079a9a29c04dd81816b1ce8903b8c174a39224fe978547cb", + "sha256:d38b35f6eef4237b1d0d8e845fc1546dad85c55eba447e28c211da8c7ef9697c", + "sha256:d64c98277ea80e4484f1332ab107e8dfd173a7dcf1bdbf10a9cccc97aaab145f", + "sha256:d9de8427a5601799784eb0e7fa1b031aa64086ce04de29df775a8ca37eedac41", + "sha256:e6a15cf8f887d9f578dd49c6fb3a99d53e1d922fdd67a245a67488d77bf56eb2", + "sha256:e8c446882cbb3774cd78c738c9f58220606b702b7c1655f1423357dc51674054", + "sha256:e8d188ee39bd0ffe76603da887706e4e7b471f613625899ddf1e27867dc6a0d3", + "sha256:ef76535776c0708a85258f6dc51d36a2df12633c735f6d197ed7dfcaa7449b99", + "sha256:f6efca006a81e1197b925a7d7b16b8f61980697bb6746587aad8842865233218" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==3.11.0" }, "python-dateutil": { "hashes": [ @@ -240,18 +255,19 @@ }, "python-dotenv": { "hashes": [ - "sha256:debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", - "sha256:f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544" + "sha256:8c10c99a1b25d9a68058a1ad6f90381a62ba68230ca93966882a4dbc3bc9c33d", + "sha256:c10863aee750ad720f4f43436565e4c1698798d763b63234fb5021b6c616e423" ], "index": "pypi", - "version": "==0.10.3" + "version": "==0.14.0" }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.13.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.15.0" }, "uvloop": { "hashes": [ @@ -265,94 +281,72 @@ "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362" ], - "index": "pypi", "markers": "sys_platform != 'win32'", "version": "==0.14.0" }, "virtualenv": { "hashes": [ - "sha256:116655188441670978117d0ebb6451eb6a7526f9ae0796cc0dee6bd7356909b0", - "sha256:b57776b44f91511866594e477dd10e76a6eb44439cdd7f06dcd30ba4c5bd854f" + "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2", + "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380" ], - "version": "==16.7.8" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.1.0" }, "virtualenv-clone": { "hashes": [ - "sha256:532f789a5c88adf339506e3ca03326f20ee82fd08ee5586b44dc859b5b4468c5", - "sha256:c88ae171a11b087ea2513f260cdac9232461d8e9369bcd1dc143fc399d220557" - ], - "version": "==0.5.3" - }, - "websockets": { - "hashes": [ - "sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136", - "sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6", - "sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1", - "sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538", - "sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4", - "sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908", - "sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0", - "sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d", - "sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c", - "sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d", - "sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c", - "sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb", - "sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf", - "sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e", - "sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96", - "sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584", - "sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484", - "sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d", - "sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559", - "sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff", - "sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454" - ], - "version": "==6.0" + "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", + "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.5.4" }, "yarl": { "hashes": [ - "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", - "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", - "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", - "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", - "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", - "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", - "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", - "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", - "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", - "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", - "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", - "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", - "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", - "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", - "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", - "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", - "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2" - ], - "version": "==1.4.2" + "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", + "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593", + "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2", + "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8", + "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d", + "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692", + "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02", + "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a", + "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8", + "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6", + "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511", + "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e", + "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a", + "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb", + "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f", + "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", + "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" + ], + "markers": "python_version >= '3.5'", + "version": "==1.5.1" } }, "develop": { "appdirs": { "hashes": [ - "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", - "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" ], - "version": "==1.4.3" + "version": "==1.4.4" }, "astroid": { "hashes": [ - "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", - "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42" + "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", + "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" ], - "version": "==2.3.3" + "markers": "python_version >= '3.5'", + "version": "==2.4.2" }, "attrs": { "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", + "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" ], - "version": "==19.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.2.0" }, "bandit": { "hashes": [ @@ -364,39 +358,59 @@ }, "black": { "hashes": [ - "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", - "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c" + "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", + "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539" ], "index": "pypi", - "version": "==19.3b0" + "version": "==19.10b0" }, "click": { "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==7.1.2" + }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "index": "pypi", + "version": "==0.4.4" + }, + "flake8": { + "hashes": [ + "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839", + "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b" ], - "version": "==7.0" + "index": "pypi", + "version": "==3.8.4" }, - "gitdb2": { + "gitdb": { "hashes": [ - "sha256:1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350", - "sha256:96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b" + "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", + "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], - "version": "==2.0.6" + "markers": "python_version >= '3.4'", + "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:9c2398ffc3dcb3c40b27324b316f08a4f93ad646d5a6328cafbb871aa79f5e42", - "sha256:c155c6a2653593ccb300462f6ef533583a913e17857cfef8fc617c246b6dc245" + "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b", + "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8" ], - "version": "==3.0.5" + "markers": "python_version >= '3.4'", + "version": "==3.1.11" }, "isort": { "hashes": [ - "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", - "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7", + "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58" ], - "version": "==4.3.21" + "markers": "python_version >= '3.6' and python_version < '4.0'", + "version": "==5.6.4" }, "lazy-object-proxy": { "hashes": [ @@ -422,6 +436,7 @@ "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.3" }, "mccabe": { @@ -431,96 +446,164 @@ ], "version": "==0.6.1" }, + "pathspec": { + "hashes": [ + "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", + "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061" + ], + "version": "==0.8.0" + }, "pbr": { "hashes": [ - "sha256:139d2625547dbfa5fb0b81daebb39601c478c21956dc57e2e07b74450a8c506b", - "sha256:61aa52a0f18b71c5cc58232d2cf8f8d09cd67fcad60b742a60124cb8d6951488" + "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9", + "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00" ], - "version": "==5.4.4" + "markers": "python_version >= '2.6'", + "version": "==5.5.1" + }, + "pycodestyle": { + "hashes": [ + "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", + "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.6.0" + }, + "pyflakes": { + "hashes": [ + "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", + "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.2.0" }, "pylint": { "hashes": [ - "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", - "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4" + "sha256:bb4a908c9dadbc3aac18860550e870f58e1a02c9f2c204fdf5693d73be061210", + "sha256:bfe68f020f8a0fece830a22dd4d5dddb4ecc6137db04face4c3420a46a52239f" ], "index": "pypi", - "version": "==2.4.4" + "version": "==2.6.0" }, "pyyaml": { "hashes": [ - "sha256:0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc", - "sha256:2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803", - "sha256:35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc", - "sha256:38a4f0d114101c58c0f3a88aeaa44d63efd588845c5a2df5290b73db8f246d15", - "sha256:483eb6a33b671408c8529106df3707270bfacb2447bf8ad856a4b4f57f6e3075", - "sha256:4b6be5edb9f6bb73680f5bf4ee08ff25416d1400fbd4535fe0069b2994da07cd", - "sha256:7f38e35c00e160db592091751d385cd7b3046d6d51f578b29943225178257b31", - "sha256:8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f", - "sha256:c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c", - "sha256:e4c015484ff0ff197564917b4b4246ca03f411b9bd7f16e02a2f586eb48b6d04", - "sha256:ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4" - ], - "version": "==5.2" + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", + "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", + "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", + "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" + ], + "version": "==5.3.1" + }, + "regex": { + "hashes": [ + "sha256:0cb23ed0e327c18fb7eac61ebbb3180ebafed5b9b86ca2e15438201e5903b5dd", + "sha256:1a065e7a6a1b4aa851a0efa1a2579eabc765246b8b3a5fd74000aaa3134b8b4e", + "sha256:1a511470db3aa97432ac8c1bf014fcc6c9fbfd0f4b1313024d342549cf86bcd6", + "sha256:1c447b0d108cddc69036b1b3910fac159f2b51fdeec7f13872e059b7bc932be1", + "sha256:2278453c6a76280b38855a263198961938108ea2333ee145c5168c36b8e2b376", + "sha256:240509721a663836b611fa13ca1843079fc52d0b91ef3f92d9bba8da12e768a0", + "sha256:4e21340c07090ddc8c16deebfd82eb9c9e1ec5e62f57bb86194a2595fd7b46e0", + "sha256:570e916a44a361d4e85f355aacd90e9113319c78ce3c2d098d2ddf9631b34505", + "sha256:59d5c6302d22c16d59611a9fd53556554010db1d47e9df5df37be05007bebe75", + "sha256:6a46eba253cedcbe8a6469f881f014f0a98819d99d341461630885139850e281", + "sha256:6f567df0601e9c7434958143aebea47a9c4b45434ea0ae0286a4ec19e9877169", + "sha256:781906e45ef1d10a0ed9ec8ab83a09b5e0d742de70e627b20d61ccb1b1d3964d", + "sha256:8469377a437dbc31e480993399fd1fd15fe26f382dc04c51c9cb73e42965cc06", + "sha256:8cd0d587aaac74194ad3e68029124c06245acaeddaae14cb45844e5c9bebeea4", + "sha256:97a023f97cddf00831ba04886d1596ef10f59b93df7f855856f037190936e868", + "sha256:a973d5a7a324e2a5230ad7c43f5e1383cac51ef4903bf274936a5634b724b531", + "sha256:af360e62a9790e0a96bc9ac845d87bfa0e4ee0ee68547ae8b5a9c1030517dbef", + "sha256:b706c70070eea03411b1761fff3a2675da28d042a1ab7d0863b3efe1faa125c9", + "sha256:bfd7a9fddd11d116a58b62ee6c502fd24cfe22a4792261f258f886aa41c2a899", + "sha256:c30d8766a055c22e39dd7e1a4f98f6266169f2de05db737efe509c2fb9c8a3c8", + "sha256:c53dc8ee3bb7b7e28ee9feb996a0c999137be6c1d3b02cb6b3c4cba4f9e5ed09", + "sha256:c95d514093b80e5309bdca5dd99e51bcf82c44043b57c34594d9d7556bd04d05", + "sha256:d43cf21df524283daa80ecad551c306b7f52881c8d0fe4e3e76a96b626b6d8d8", + "sha256:d62205f00f461fe8b24ade07499454a3b7adf3def1225e258b994e2215fd15c5", + "sha256:e289a857dca3b35d3615c3a6a438622e20d1bf0abcb82c57d866c8d0be3f44c4", + "sha256:e5f6aa56dda92472e9d6f7b1e6331f4e2d51a67caafff4d4c5121cadac03941e", + "sha256:f4b1c65ee86bfbf7d0c3dfd90592a9e3d6e9ecd36c367c884094c050d4c35d04" + ], + "version": "==2020.10.23" }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.13.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.15.0" }, - "smmap2": { + "smmap": { "hashes": [ - "sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde", - "sha256:29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a" + "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", + "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], - "version": "==2.0.5" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==3.0.4" }, "stevedore": { "hashes": [ - "sha256:01d9f4beecf0fbd070ddb18e5efb10567801ba7ef3ddab0074f54e3cd4e91730", - "sha256:e0739f9739a681c7a1fda76a102b65295e96a144ccdb552f2ae03c5f0abe8a14" + "sha256:5e1ab03eaae06ef6ce23859402de785f08d97780ed774948ef16c4652c41bc62", + "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0" ], - "version": "==1.31.0" + "markers": "python_version >= '3.6'", + "version": "==3.2.2" }, "toml": { "hashes": [ - "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", - "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", + "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" ], - "version": "==0.10.0" + "version": "==0.10.1" }, "typed-ast": { "hashes": [ - "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", - "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", - "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", - "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", - "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", - "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", - "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", - "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", - "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", - "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", - "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", - "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", - "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", - "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", - "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", - "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", - "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", - "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", - "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", - "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" - ], - "markers": "implementation_name == 'cpython' and python_version < '3.8'", - "version": "==1.4.0" + "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", + "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", + "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d", + "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", + "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", + "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", + "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c", + "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", + "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", + "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", + "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", + "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", + "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", + "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d", + "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", + "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", + "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c", + "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", + "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395", + "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", + "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", + "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", + "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", + "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", + "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072", + "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298", + "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91", + "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", + "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f", + "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" + ], + "version": "==1.4.1" }, "wrapt": { "hashes": [ - "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" + "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" ], - "version": "==1.11.2" + "version": "==1.12.1" } } } diff --git a/Procfile b/Procfile index 5ae4640def..29cff6d9d1 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -worker: pipenv run bot +worker: python bot.py diff --git a/README.md b/README.md index 52e4c4abd8..6173484788 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
@@ -31,10 +31,6 @@ Made with Python 3.7 - - - - @@ -50,25 +46,25 @@ ## What is Modmail? -Modmail is similar to Reddit's Modmail both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way. +Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way. This bot is free for everyone and always will be. If you like this project and would like to show your appreciation, you can support us on **[Patreon](https://www.patreon.com/kyber)**, cool benefits included! ## How does it work? -When a member sends a direct message to the bot, Modmail will create a channel or "thread" within an isolated category. All further DM messages will automatically relay to that channel, for any available staff can respond within the channel. +When a member sends a direct message to the bot, Modmail will create a channel or "thread" into a designated category. All further DM messages will automatically relay to that channel; any available staff can respond within the channel. -All threads are logged and you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.logviewer.tech/example). +Our Logviewer will save the threads so you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.logviewer.tech/example). ## Features * **Highly Customisable:** * Bot activity, prefix, category, log channel, etc. * Command permission system. - * Interface elements (color, responses, reactions, etc). + * Interface elements (color, responses, reactions, etc.). * Snippets and *command aliases*. * Minimum duration for accounts to be created before allowed to contact Modmail (`account_age`). - * Minimum duration for members to be in the guild before allowed to contact Modmail (`guild_age`). + * Minimum length for members to be in the guild before allowed to contact Modmail (`guild_age`). * **Advanced Logging Functionality:** * When you close a thread, Modmail will generate a [log link](https://logs.logviewer.tech/example) and post it to your log channel. @@ -90,11 +86,11 @@ This list is ever-growing thanks to active development and our exceptional contr Where can I find the Modmail bot invite link? -Unfortunately, due to how this bot functions, it cannot be invited. This is to ensure the individuality to your server and grant you full control over your bot and data. Nonetheless, you can easily obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time)... +Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time). ### Heroku -This bot can be hosted on Heroku. +You can host this bot on Heroku. Installation via Heroku is possible with your web browser alone. The [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) (which includes a video tutorial!) will guide you through the entire installation process. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. @@ -108,11 +104,11 @@ To configure automatic updates: ### Hosting for Patreons -If you don't want to go through the trouble of setting up your very own Modmail bot, and/or want to support this project, we offer the all inclusive installation, hosting and maintenance of your Modmail with [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! +If you don't want to go through the trouble of setting up your very own Modmail bot or wish to support this project, we got a solution for you! We offer the complete installation, hosting, and maintenance of your Modmail with [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! ### Locally -Local hosting of Modmail is also possible, first you will need [`Python 3.7`](https://www.python.org/downloads/). +Local hosting of Modmail is also possible. First, you will need [`Python 3.7`](https://www.python.org/downloads/release/python-376/). Follow the [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) and disregard deploying the Heroku bot application. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. @@ -147,7 +143,7 @@ You can build your own Docker image: $ docker build . --tag=modmail ``` -or run directly from a pre-built version from https://hub.docker.com/. Currently there are two community release of Modmail: +Or run directly from a pre-built version from https://hub.docker.com/. - Kyber's: @@ -155,22 +151,12 @@ or run directly from a pre-built version from https://hub.docker.com/. Currently $ docker pull kyb3rr/modmail ``` -- Taku's: - -```console -$ docker pull taaku18/modmail -# You can also choose one of the following: -$ docker pull taaku18/modmail:dev -$ docker pull taaku18/modmail: ( ex: 3.2.0, 3.2, etc.) -``` - And to run your docker image: ```console -$ docker run --env-file .env user/modmail +$ docker run --env-file .env kyb3rr/modmail ``` -- Replace `user/modmail` with `kyb3rr/modmail`, `taaku18/modmail`, `taaku18/modmail:3.2`, etc as above. -- `.env` should be the path to your env file, you can also supply a path: `/path/to/.env`. +- `.env` should be the path to your env file; you can also supply a path: `/path/to/.env`. ## Sponsors @@ -180,18 +166,14 @@ Special thanks to our sponsors for supporting the project. - - - - Become a sponsor on [Patreon](https://patreon.com/kyber). ## Plugins Modmail supports the use of third-party plugins to extend or add functionalities to the bot. -This allows niche features as well as anything else outside of the scope of the core functionality of Modmail. +Plugins allow niche features as well as anything else outside of the scope of the core functionality of Modmail. -A list of third-party plugins can be found using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/kyb3r/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. +You can find a list of third-party plugins using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/kyb3r/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. To develop your own, check out the [plugins documentation](https://github.com/kyb3r/modmail/wiki/Plugins). @@ -199,6 +181,6 @@ Plugins requests and support is available in our [Modmail Plugins Server](https: ## Contributing -Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our contribution [guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. +Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. If you like this project and would like to show your appreciation, support us on **[Patreon](https://www.patreon.com/kyber)**! diff --git a/SPONSORS.json b/SPONSORS.json index d30134e015..ceed37be23 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -26,42 +26,5 @@ } ] } - }, - { - "embed": { - "title": "Hey there!", - "description": "Nice to see you here! You can support us by subscribing on youtube -> [Youtube](https://www.youtube.com/user/RoomieOfficial) <- and also join our [Discord](https://discord.gg/zaeVCaV)!", - "url": "https://discord.gg/zaeVCaV", - "color": 13003681, - "footer": { - "icon_url": "https://imgur.com/Mrc9pLd.gif", - "text": "everyone is a clown" - }, - "thumbnail": { - "url": "https://imgur.com/Mrc9pLd.gif" - }, - "image": { - "url": "https://imgur.com/ZUFiL6b.gif" - }, - "author": { - "name": "Roomieofficial", - "url": "https://discord.gg/zaeVCaV", - "icon_url": "https://imgur.com/6hBkt7Z.png" - }, - "fields": [ - { - "name": "What is all this about 🤔", - "value": "We are mainly focused on everything that has anything to do with music or singing! " - }, - { - "name": "Youtube 🙄", - "value": "U will get great content if you follow our [Youtube](https://www.youtube.com/user/RoomieOfficial) with weekly uploads." - }, - { - "name": "Discord 😁", - "value": "Make sure to join our [Discord](https://discord.gg/zaeVCaV) We have weekly events, 24/7 chats and more!" - } - ] - } } ] diff --git a/app.json b/app.json index 76fe320a30..41697cf064 100644 --- a/app.json +++ b/app.json @@ -1,27 +1,35 @@ { - "name": "Modmail", - "description": "An easy to install Modmail bot for Discord - DM to contact mods!", - "repository": "https://github.com/kyb3r/modmail", - "env": { - "TOKEN": { - "description": "Your discord bot's token.", - "required": true - }, - "GUILD_ID": { - "description": "The id for the server you are hosting this bot for.", - "required": true - }, - "OWNERS": { - "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", - "required": true - }, - "MONGO_URI": { - "description": "Mongo DB connection URI for self-hosting your data.", - "required": true - }, - "LOG_URL": { - "description": "The url of the log viewer app for viewing self-hosted logs.", - "required": true + "name": "Modmail", + "description": "An easy to install Modmail bot for Discord - DM to contact mods!", + "repository": "https://github.com/kyb3r/modmail", + "env": { + "TOKEN": { + "description": "Your discord bot's token.", + "required": true + }, + "GUILD_ID": { + "description": "The id for the server you are hosting this bot for.", + "required": true + }, + "MODMAIL_GUILD_ID": { + "description": "The ID of the discord server where the threads channels should be created (receiving server). Default to GUILD_ID.", + "required": false + }, + "OWNERS": { + "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", + "required": true + }, + "CONNECTION_URI": { + "description": "The connection URI for your database.", + "required": true + }, + "DATABASE_TYPE": { + "description": "The type of your database. There is only one supported database at the moment - MongoDB (default).", + "required": false + }, + "LOG_URL": { + "description": "The url of the log viewer app for viewing self-hosted logs.", + "required": true + } } - } -} +} \ No newline at end of file diff --git a/bot.py b/bot.py index a379567b4d..ab5ded6c53 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.5.0-dev0" +__version__ = "3.6.3-dev0" import asyncio @@ -18,8 +18,6 @@ from aiohttp import ClientSession from emoji import UNICODE_EMOJI -from motor.motor_asyncio import AsyncIOMotorClient -from pymongo.errors import ConfigurationError from pkg_resources import parse_version @@ -31,8 +29,8 @@ except ImportError: pass -from core import checks, translations -from core.clients import ApiClient, PluginDatabaseClient +from core import checks +from core.clients import ApiClient, PluginDatabaseClient, MongoDBClient from core.config import ConfigManager from core.utils import human_join, normalize_alias from core.models import PermissionLevel, SafeFormatter, getLogger, configure_logging @@ -46,10 +44,17 @@ if not os.path.exists(temp_dir): os.mkdir(temp_dir) +if sys.platform == "win32": + try: + asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) + except AttributeError: + logger.error("Failed to use WindowsProactorEventLoopPolicy.", exc_info=True) + class ModmailBot(commands.Bot): def __init__(self): - super().__init__(command_prefix=None) # implemented in `get_prefix` + intents = discord.Intents.all() + super().__init__(command_prefix=None, intents=intents) # implemented in `get_prefix` self._session = None self._api = None self.metadata_loop = None @@ -66,22 +71,7 @@ def __init__(self): self.log_file_name = os.path.join(temp_dir, f"{self.token.split('.')[0]}.log") self._configure_logging() - mongo_uri = self.config["mongo_uri"] - if mongo_uri is None: - logger.critical("A Mongo URI is necessary for the bot to function.") - raise RuntimeError - - try: - self.db = AsyncIOMotorClient(mongo_uri).modmail_bot - except ConfigurationError as e: - logger.critical( - "Your MONGO_URI might be copied wrong, try re-copying from the source again. " - "Otherwise noted in the following message:" - ) - logger.critical(e) - sys.exit(0) - - self.plugin_db = PluginDatabaseClient(self) + self.plugin_db = PluginDatabaseClient(self) # Deprecated self.startup() @property @@ -100,9 +90,12 @@ def uptime(self) -> str: def startup(self): logger.line() - logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬") - logger.info("││││ │ │││││├─┤││") - logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") + if os.name != "nt": + logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬") + logger.info("││││ │ │││││├─┤││") + logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") + else: + logger.info("MODMAIL") logger.info("v%s", __version__) logger.info("Authors: kyb3r, fourjr, Taaku18") logger.line() @@ -152,9 +145,18 @@ def session(self) -> ClientSession: @property def api(self) -> ApiClient: if self._api is None: - self._api = ApiClient(self) + if self.config["database_type"].lower() == "mongodb": + self._api = MongoDBClient(self) + else: + logger.critical("Invalid database type.") + raise RuntimeError return self._api + @property + def db(self): + # deprecated + return self.api.db + async def get_prefix(self, message=None): return [self.prefix, f"<@{self.user.id}> ", f"<@!{self.user.id}> "] @@ -165,6 +167,10 @@ def run(self, *args, **kwargs): pass except discord.LoginFailure: logger.critical("Invalid token") + except discord.PrivilegedIntentsRequired: + logger.critical( + "Privileged intents are not explicitly granted in the discord developers dashboard." + ) except Exception: logger.critical("Fatal exception", exc_info=True) finally: @@ -180,7 +186,7 @@ def run(self, *args, **kwargs): logger.error(" - Shutting down bot - ") @property - def owner_ids(self): + def bot_owner_ids(self): owner_ids = self.config["owners"] if owner_ids is not None: owner_ids = set(map(int, str(owner_ids).split(","))) @@ -192,7 +198,7 @@ def owner_ids(self): return owner_ids async def is_owner(self, user: discord.User) -> bool: - if user.id in self.owner_ids: + if user.id in self.bot_owner_ids: return True return await super().is_owner(user) @@ -370,37 +376,16 @@ def command_perm(self, command_name: str) -> PermissionLevel: async def on_connect(self): try: - await self.validate_database_connection() + await self.api.validate_database_connection() except Exception: logger.debug("Logging out due to failed database connection.") return await self.logout() logger.debug("Connected to gateway.") await self.config.refresh() - await self.setup_indexes() + await self.api.setup_indexes() self._connected.set() - async def setup_indexes(self): - """Setup text indexes so we can use the $search operator""" - coll = self.db.logs - index_name = "messages.content_text_messages.author.name_text_key_text" - - index_info = await coll.index_information() - - # Backwards compatibility - old_index = "messages.content_text_messages.author.name_text" - if old_index in index_info: - logger.info("Dropping old index: %s", old_index) - await coll.drop_index(old_index) - - if index_name not in index_info: - logger.info('Creating "text" index for logs collection.') - logger.info("Name: %s", index_name) - await coll.create_index( - [("messages.content", "text"), ("messages.author.name", "text"), ("key", "text")] - ) - logger.debug("Successfully configured and verified database indexes.") - async def on_ready(self): """Bot startup, sets uptime.""" @@ -416,7 +401,8 @@ async def on_ready(self): logger.info("Logged in as: %s", self.user) logger.info("Bot ID: %s", self.user.id) owners = ", ".join( - getattr(self.get_user(owner_id), "name", str(owner_id)) for owner_id in self.owner_ids + getattr(self.get_user(owner_id), "name", str(owner_id)) + for owner_id in self.bot_owner_ids ) logger.info("Owners: %s", owners) logger.info("Prefix: %s", self.prefix) @@ -469,7 +455,7 @@ async def on_ready(self): { "open": False, "closed_at": str(datetime.utcnow()), - "close_message": _("Channel has been deleted, no closer found."), + "close_message": "Channel has been deleted, no closer found.", "closer": { "id": str(self.user.id), "name": self.user.name, @@ -498,6 +484,17 @@ async def on_ready(self): self.metadata_loop.before_loop(self.before_post_metadata) self.metadata_loop.start() + other_guilds = [ + guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild} + ] + if any(other_guilds): + logger.warning( + "The bot is in more servers other than the main and staff server." + "This may cause data compromise (%s).", + ", ".join(guild.name for guild in other_guilds), + ) + logger.warning("If the external servers are valid, you may ignore this message.") + async def convert_emoji(self, name: str) -> str: ctx = SimpleNamespace(bot=self, guild=self.modmail_guild) converter = commands.EmojiConverter() @@ -549,9 +546,7 @@ def check_account_age(self, author: discord.Member) -> bool: logger.debug("Blocked due to account age, user %s.", author.name) if str(author.id) not in self.blocked_users: - new_reason = _("System Message: New Account. Required to wait for {time}.").format( - time=delta - ) + new_reason = f"System Message: New Account. Required to wait for {delta}." self.blocked_users[str(author.id)] = new_reason return False @@ -617,7 +612,7 @@ def check_manual_blocked(self, author: discord.Member) -> bool: return False async def _process_blocked(self, message): - x, blocked_emoji = await self.retrieve_emoji() + _, blocked_emoji = await self.retrieve_emoji() if await self.is_blocked(message.author, channel=message.channel, send_message=True): await self.add_reaction(message, blocked_emoji) return True @@ -937,7 +932,7 @@ async def on_typing(self, channel, user, _): return await thread.recipient.trigger_typing() - async def handle_reaction_events(self, payload, *, add): + async def handle_reaction_events(self, payload): user = self.get_user(payload.user_id) if user.bot: return @@ -963,7 +958,7 @@ async def handle_reaction_events(self, payload, *, add): if not thread: return if ( - add + payload.event_type == "REACTION_ADD" and message.embeds and str(reaction) == str(close_emoji) and self.config.get("recipient_thread_close") @@ -987,14 +982,14 @@ async def handle_reaction_events(self, payload, *, add): if not thread: return try: - x, linked_message = await thread.find_linked_messages( + _, linked_message = await thread.find_linked_messages( message.id, either_direction=True ) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return - if add: + if payload.event_type == "REACTION_ADD": if await self.add_reaction(linked_message, reaction): await self.add_reaction(message, reaction) else: @@ -1005,28 +1000,15 @@ async def handle_reaction_events(self, payload, *, add): logger.warning("Failed to remove reaction: %s", e) async def on_raw_reaction_add(self, payload): - await self.handle_reaction_events(payload, add=True) + await self.handle_reaction_events(payload) async def on_raw_reaction_remove(self, payload): - await self.handle_reaction_events(payload, add=False) + await self.handle_reaction_events(payload) async def on_guild_channel_delete(self, channel): if channel.guild != self.modmail_guild: return - try: - audit_logs = self.modmail_guild.audit_logs() - entry = await audit_logs.find(lambda a: a.target == channel) - mod = entry.user - except AttributeError as e: - # discord.py broken implementation with discord API - # TODO: waiting for dpy - logger.warning("Failed to retrieve audit log: %s.", e) - return - - if mod == self.user: - return - if isinstance(channel, discord.CategoryChannel): if self.main_category == channel: logger.debug("Main category was deleted.") @@ -1043,6 +1025,19 @@ async def on_guild_channel_delete(self, channel): await self.config.update() return + audit_logs = self.modmail_guild.audit_logs( + limit=10, action=discord.AuditLogAction.channel_delete + ) + entry = await audit_logs.find(lambda a: int(a.target.id) == channel.id) + + if entry is None: + logger.debug("Cannot find the audit log entry for channel delete of %d.", channel.id) + return + + mod = entry.user + if mod == self.user: + return + thread = await self.threads.find(channel=channel) if thread and thread.channel == channel: logger.debug("Manually closed channel %s.", channel.name) @@ -1070,20 +1065,60 @@ async def on_member_join(self, member): async def on_message_delete(self, message): """Support for deleting linked messages""" - # TODO: use audit log to check if modmail deleted the message - if message.embeds and not isinstance(message.channel, discord.DMChannel): - thread = await self.threads.find(channel=message.channel) + + if message.is_system(): + return + + if isinstance(message.channel, discord.DMChannel): + if message.author == self.user: + return + thread = await self.threads.find(recipient=message.author) + if not thread: + return try: - await thread.delete_message(message) + message = await thread.find_linked_message_from_dm(message) except ValueError as e: - if str(e) not in {"DM message not found.", " Malformed thread message."}: - logger.warning("Failed to find linked message to delete: %s", e) - else: - thread = await self.threads.find(recipient=message.author) - message = await thread.find_linked_message_from_dm(message) + if str(e) != "Thread channel message not found.": + logger.debug("Failed to find linked message to delete: %s", e) + return embed = message.embeds[0] embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=embed.footer.icon_url) await message.edit(embed=embed) + return + + if message.author != self.user: + return + + thread = await self.threads.find(channel=message.channel) + if not thread: + return + + audit_logs = self.modmail_guild.audit_logs( + limit=10, action=discord.AuditLogAction.message_delete + ) + + entry = await audit_logs.find(lambda a: a.target == self.user) + + if entry is None: + return + + try: + await thread.delete_message(message, note=False) + embed = discord.Embed( + description="Successfully deleted message.", color=self.main_color + ) + except ValueError as e: + if str(e) not in {"DM message not found.", "Malformed thread message."}: + logger.debug("Failed to find linked message to delete: %s", e) + embed = discord.Embed( + description="Failed to delete message.", color=self.error_color + ) + else: + return + except discord.NotFound: + return + embed.set_footer(text=f"Message ID: {message.id} from {message.author}.") + return await message.channel.send(embed=embed) async def on_bulk_message_delete(self, messages): await discord.utils.async_all(self.on_message_delete(msg) for msg in messages) @@ -1096,10 +1131,13 @@ async def on_message_edit(self, before, after): if isinstance(after.channel, discord.DMChannel): thread = await self.threads.find(recipient=before.author) + if not thread: + return + try: await thread.edit_dm_message(after, after.content) except ValueError: - x, blocked_emoji = await self.retrieve_emoji() + _, blocked_emoji = await self.retrieve_emoji() await self.add_reaction(after, blocked_emoji) else: embed = discord.Embed( @@ -1147,45 +1185,17 @@ async def on_command_error(self, context, exception): corrected_permission_level.name, ) logger.warning("CheckFailure: %s", exception) + elif isinstance(exception, commands.DisabledCommand): + logger.info( + "DisabledCommand: %s is trying to run eval but it's disabled", context.author.name + ) else: logger.error("Unexpected exception:", exc_info=exception) - async def validate_database_connection(self): - try: - await self.db.command("buildinfo") - except Exception as exc: - logger.critical("Something went wrong while connecting to the database.") - message = f"{type(exc).__name__}: {str(exc)}" - logger.critical(message) - - if "ServerSelectionTimeoutError" in message: - logger.critical( - "This may have been caused by not whitelisting " - "IPs correctly. Make sure to whitelist all " - "IPs (0.0.0.0/0) https://i.imgur.com/mILuQ5U.png" - ) - - if "OperationFailure" in message: - logger.critical( - "This is due to having invalid credentials in your MONGO_URI. " - "Remember you need to substitute `` with your actual password." - ) - logger.critical( - "Be sure to URL encode your username and password (not the entire URL!!), " - "https://www.urlencoder.io/, if this issue persists, try changing your username and password " - "to only include alphanumeric characters, no symbols." - "" - ) - raise - else: - logger.debug("Successfully connected to the database.") - logger.line("debug") - async def post_metadata(self): - owner = (await self.application_info()).owner + info = await self.application_info() + data = { - "owner_name": str(owner), - "owner_id": owner.id, "bot_id": self.user.id, "bot_name": str(self.user), "avatar_url": str(self.user.avatar_url), @@ -1199,7 +1209,20 @@ async def post_metadata(self): "last_updated": str(datetime.utcnow()), } - async with self.session.post("https://api.logviewer.tech/metadata", json=data): + if info.team is not None: + data.update( + { + "owner_name": info.team.owner.name + if info.team.owner is not None + else "No Owner", + "owner_id": info.team.owner_id, + "team": True, + } + ) + else: + data.update({"owner_name": info.owner.name, "owner_id": info.owner.id, "team": False}) + + async with self.session.post("https://api.modmail.dev/metadata", json=data): logger.debug("Uploading metadata to Modmail server.") async def before_post_metadata(self): @@ -1220,7 +1243,6 @@ def main(): except ImportError: pass - translations.init() bot = ModmailBot() bot.run() diff --git a/cogs/modmail.py b/cogs/modmail.py index 76a28b3c9c..44f0e9dcde 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -41,23 +41,17 @@ async def setup(self, ctx): if ctx.guild != self.bot.modmail_guild: return await ctx.send( - _( - "You can only setup in the Modmail guild: {guild_name}.".format( - guild_name=self.bot.modmail_guild - ) - ) + f"You can only setup in the Modmail guild: {self.bot.modmail_guild}." ) if self.bot.main_category is not None: logger.debug("Can't re-setup server, main_category is found.") - return await ctx.send( - _("{guild_name} is already set up.").format(guild_name=self.bot.modmail_guild) - ) + return await ctx.send(f"{self.bot.modmail_guild} is already set up.") if self.bot.modmail_guild is None: embed = discord.Embed( - title=_("Error"), - description=_("Modmail functioning guild not found."), + title="Error", + description="Modmail functioning guild not found.", color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -94,29 +88,21 @@ async def setup(self, ctx): ) embed = discord.Embed( - title=_("Friendly Reminder"), - description=_( - "You may use the `{prefix}config set log_channel_id " - "` command to set up a custom log channel, then you can delete this default " - "{log_channel} log channel." - ).format(prefix=self.bot.prefix, log_channel=log_channel.mention), + title="Friendly Reminder", + description=f"You may use the `{self.bot.prefix}config set log_channel_id " + "` command to set up a custom log channel, then you can delete this default " + f"{log_channel.mention} log channel.", color=self.bot.main_color, ) embed.add_field( - name=_("Thanks for using the bot!"), - value=_( - "If you like what you see, consider giving the " - "[repo a star](https://github.com/kyb3r/modmail) :star: or if you are " - "feeling generous, check us out on [Patreon](https://patreon.com/kyber)!" - ), + name="Thanks for using our bot!", + value="If you like what you see, consider giving the " + "[repo a star](https://github.com/kyb3r/modmail) :star: and if you are " + "feeling extra generous, buy us coffee on [Patreon](https://patreon.com/kyber) :heart:!", ) - embed.set_footer( - text=_('Type "{prefix}help" for a complete list of commands.').format( - prefix=self.bot.prefix - ) - ) + embed.set_footer(text=f'Type "{self.bot.prefix}help" for a complete list of commands.') await log_channel.send(embed=embed) self.bot.config["main_category_id"] = category.id @@ -124,20 +110,18 @@ async def setup(self, ctx): await self.bot.config.update() await ctx.send( - _( - "**Successfully set up server.**\n" - "Consider setting permission levels " - "to give access to roles or users the ability to use Modmail.\n\n" - "Type:\n- `{prefix}permissions` and `{prefix}permissions add` " - "for more info on setting permissions.\n" - "- `{prefix}config help` for a list of available customizations." - ).format(prefix=self.bot.prefix) + "**Successfully set up server.**\n" + "Consider setting permission levels to give access to roles " + "or users the ability to use Modmail.\n\n" + f"Type:\n- `{self.bot.prefix}permissions` and `{self.bot.prefix}permissions add` " + "for more info on setting permissions.\n" + f"- `{self.bot.prefix}config help` for a list of available customizations." ) if not self.bot.config["command_permissions"] and not self.bot.config["level_permissions"]: await self.bot.update_perms(PermissionLevel.REGULAR, -1) - for owner_ids in self.bot.owner_ids: - await self.bot.update_perms(PermissionLevel.OWNER, owner_ids) + for owner_id in self.bot.bot_owner_ids: + await self.bot.update_perms(PermissionLevel.OWNER, owner_id) @commands.group(aliases=["snippets"], invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -186,7 +170,7 @@ async def snippet(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): description = format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name=_("Snippets"), icon_url=ctx.guild.icon_url) + embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -228,27 +212,25 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte """ if name in self.bot.snippets: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("Snippet `{name}` already exists.").format(name=name), + description=f"Snippet `{name}` already exists.", ) return await ctx.send(embed=embed) if name in self.bot.aliases: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("An alias with the same name already exists: `{name}`.").format( - name=name - ), + description=f"An alias that shares the same name exists: `{name}`.", ) return await ctx.send(embed=embed) if len(name) > 120: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("Snippet names cannot be longer than 120 characters."), + description="Snippet names cannot be longer than 120 characters.", ) return await ctx.send(embed=embed) @@ -269,9 +251,9 @@ async def snippet_remove(self, ctx, *, name: str.lower): if name in self.bot.snippets: embed = discord.Embed( - title=_("Removed snippet"), + title="Removed snippet", color=self.bot.main_color, - description=_("Snippet `{name}` is now deleted.").format(name=name), + description=f"Snippet `{name}` is now deleted.", ) self.bot.snippets.pop(name) await self.bot.config.update() @@ -294,42 +276,63 @@ async def snippet_edit(self, ctx, name: str.lower, *, value): await self.bot.config.update() embed = discord.Embed( - title=_("Edited snippet"), + title="Edited snippet", color=self.bot.main_color, - description=f_('`{name}` will now send "{value}".'), + description=f'`{name}` will now send "{value}".', ) else: embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") await ctx.send(embed=embed) - @commands.command() + @commands.command(usage=" [options]") @checks.has_permissions(PermissionLevel.MODERATOR) @checks.thread_only() - async def move(self, ctx, category: discord.CategoryChannel, *, specifics: str = None): + async def move(self, ctx, *, arguments): """ Move a thread to another category. `category` may be a category ID, mention, or name. - `specifics` is a string which takes in arguments on how to perform the move. Ex: "silently" + `options` is a string which takes in arguments on how to perform the move. Ex: "silently" """ + split_args = arguments.strip('"').split(" ") + + # manually parse arguments, consumes as much of args as possible for category + for i in range(len(split_args)): + try: + if i == 0: + fmt = arguments + else: + fmt = " ".join(split_args[:-i]) + + category = await commands.CategoryChannelConverter().convert(ctx, fmt) + except commands.BadArgument: + if i == len(split_args) - 1: + # last one + raise + pass + else: + break + + options = " ".join(arguments.split(" ")[-i:]) + thread = ctx.thread silent = False - if specifics: + if options: silent_words = ["silent", "silently"] - silent = any(word in silent_words for word in specifics.split()) + silent = any(word in silent_words for word in options.split()) await thread.channel.edit(category=category, sync_permissions=True) if self.bot.config["thread_move_notify"] and not silent: embed = discord.Embed( - title=_("Thread Moved"), + title=self.bot.config["thread_move_title"], description=self.bot.config["thread_move_response"], color=self.bot.main_color, ) await thread.recipient.send(embed=embed) - sent_emoji, x = await self.bot.retrieve_emoji() + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) async def send_scheduled_close_message(self, ctx, after, silent=False): @@ -338,17 +341,15 @@ async def send_scheduled_close_message(self, ctx, after, silent=False): silent = "*silently* " if silent else "" embed = discord.Embed( - title=_("Scheduled close"), - description=_("This thread will close {silent}in {time}.").format( - silent=silent, time=human_delta - ), + title="Scheduled close", + description=f"This thread will close {silent}in {human_delta}.", color=self.bot.error_color, ) if after.arg and not silent: - embed.add_field(name=_("Message"), value=after.arg) + embed.add_field(name="Message", value=after.arg) - embed.set_footer(text=_("Closing will be cancelled if a thread message is sent.")) + embed.set_footer(text="Closing will be cancelled if a thread message is sent.") embed.timestamp = after.dt await ctx.send(embed=embed) @@ -382,21 +383,20 @@ async def close(self, ctx, *, after: UserFriendlyTime = None): close_after = (after.dt - now).total_seconds() if after else 0 message = after.arg if after else None - silent = str(message).lower() in {_("silent"), _("silently")} - cancel = str(message).lower() == _("cancel") + silent = str(message).lower() in {"silent", "silently"} + cancel = str(message).lower() == "cancel" if cancel: if thread.close_task is not None or thread.auto_close_task is not None: await thread.cancel_closure(all=True) embed = discord.Embed( - color=self.bot.error_color, - description=_("Scheduled close has been cancelled."), + color=self.bot.error_color, description="Scheduled close has been cancelled." ) else: embed = discord.Embed( color=self.bot.error_color, - description=_("This thread has not already been scheduled to close."), + description="This thread has not already been scheduled to close.", ) return await ctx.send(embed=embed) @@ -446,18 +446,14 @@ async def notify( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} is already going to be mentioned.").format( - mention=mention - ), + description=f"{mention} is already going to be mentioned.", ) else: mentions.append(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=_( - "{mention} will be mentioned " "on the next message received." - ).format(mention=mention), + description=f"{mention} will be mentioned on the next message received.", ) return await ctx.send(embed=embed) @@ -488,16 +484,13 @@ async def unnotify( if mention not in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} does not have a pending notification.").format( - mention=mention - ), + description=f"{mention} does not have a pending notification.", ) else: mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( - color=self.bot.main_color, - description=_("{mention} will no longer be notified.").format(mention=mention), + color=self.bot.main_color, description=f"{mention} will no longer be notified." ) return await ctx.send(embed=embed) @@ -530,18 +523,14 @@ async def subscribe( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} is already subscribed to this thread.").format( - mention=mention - ), + description=f"{mention} is not subscribed to this thread.", ) else: mentions.append(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=_( - "{mention} will now be " "notified of all messages received." - ).format(mention=mention), + description=f"{mention} will now be notified of all messages received.", ) return await ctx.send(embed=embed) @@ -572,18 +561,14 @@ async def unsubscribe( if mention not in mentions: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} is not already subscribed to this thread.").format( - mention=mention - ), + description=f"{mention} is not subscribed to this thread.", ) else: mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( color=self.bot.main_color, - description=_("{mention} is now unsubscribed to this thread.").format( - mention=mention - ), + description=f"{mention} is now unsubscribed from this thread.", ) return await ctx.send(embed=embed) @@ -593,7 +578,7 @@ async def unsubscribe( async def nsfw(self, ctx): """Flags a Modmail thread as NSFW (not safe for work).""" await ctx.channel.edit(nsfw=True) - sent_emoji, x = await self.bot.retrieve_emoji() + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -602,7 +587,7 @@ async def nsfw(self, ctx): async def sfw(self, ctx): """Flags a Modmail thread as SFW (safe for work).""" await ctx.channel.edit(nsfw=False) - sent_emoji, x = await self.bot.retrieve_emoji() + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -635,26 +620,24 @@ def format_log_embeds(self, logs, avatar_url): embed.add_field(name="Created", value=duration(created_at, now=datetime.utcnow())) closer = entry.get("closer") if closer is None: - closer_msg = _("Unknown") + closer_msg = "Unknown" else: closer_msg = f"<@{closer['id']}>" - embed.add_field(name=_("Closed By"), value=closer_msg) + embed.add_field(name="Closed By", value=closer_msg) if entry["recipient"]["id"] != entry["creator"]["id"]: - embed.add_field(name=_("Created by"), value=f"<@{entry['creator']['id']}>") + embed.add_field(name="Created by", value=f"<@{entry['creator']['id']}>") - embed.add_field( - name=_("Preview"), value=format_preview(entry["messages"]), inline=False - ) + embed.add_field(name="Preview", value=format_preview(entry["messages"]), inline=False) if closer is not None: # BUG: Currently, logviewer can't display logs without a closer. - embed.add_field(name=_("Link"), value=log_url) + embed.add_field(name="Link", value=log_url) else: logger.debug("Invalid log entry: no closer.") - embed.add_field(name=_("Log Key"), value=f"`{entry['key']}`") + embed.add_field(name="Log Key", value=f"`{entry['key']}`") - embed.set_footer(text=_("Recipient ID") + ": " + str(entry["recipient"]["id"])) + embed.set_footer(text="Recipient ID: " + str(entry["recipient"]["id"])) embeds.append(embed) return embeds @@ -685,7 +668,7 @@ async def logs(self, ctx, *, user: User = None): if not any(not log["open"] for log in logs): embed = discord.Embed( color=self.bot.error_color, - description=_("This user does not have any previous logs."), + description="This user does not have any previous logs.", ) return await ctx.send(embed=embed) @@ -707,18 +690,13 @@ async def logs_closed_by(self, ctx, *, user: User = None): """ user = user if user is not None else ctx.author - query = {"guild_id": str(self.bot.guild_id), "open": False, "closer.id": str(user.id)} - - projection = {"messages": {"$slice": 5}} - - entries = await self.bot.db.logs.find(query, projection).to_list(None) - + entries = await self.bot.api.search_closed_by(user.id) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=self.bot.error_color, - description=_("No log entries have been found for that query"), + description="No log entries have been found for that query.", ) return await ctx.send(embed=embed) @@ -737,14 +715,14 @@ async def logs_delete(self, ctx, key_or_link: str): if not success: embed = discord.Embed( - title=_("Error"), - description=_("Log entry `{key}` not found.").format(key=key), + title="Error", + description=f"Log entry `{key}` not found.", color=self.bot.error_color, ) else: embed = discord.Embed( title="Success", - description=_("Log entry `{key}` successfully deleted.").format(key=key), + description=f"Log entry `{key}` successfully deleted.", color=self.bot.main_color, ) @@ -768,9 +746,7 @@ async def logs_responded(self, ctx, *, user: User = None): if not embeds: embed = discord.Embed( color=self.bot.error_color, - description=_("{mention} has not responded to any threads.").format( - mention=getattr(user, "mention", user.id) - ), + description=f"{getattr(user, 'mention', user.id)} has not responded to any threads.", ) return await ctx.send(embed=embed) @@ -788,22 +764,14 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): await ctx.trigger_typing() - query = { - "guild_id": str(self.bot.guild_id), - "open": False, - "$text": {"$search": f'"{query}"'}, - } - - projection = {"messages": {"$slice": 5}} - - entries = await self.bot.db.logs.find(query, projection).to_list(limit) + entries = await self.bot.api.search_by_text(query, limit) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=self.bot.error_color, - description=_("No log entries have been found for that query."), + description="No log entries have been found for that query.", ) return await ctx.send(embed=embed) @@ -896,13 +864,13 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): except ValueError: return await ctx.send( embed=discord.Embed( - title=_("Failed"), - description=_("Cannot find a message to edit."), + title="Failed", + description="Cannot find a message to edit.", color=self.bot.error_color, ) ) - sent_emoji, x = await self.bot.retrieve_emoji() + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -926,7 +894,7 @@ async def contact( if user.bot: embed = discord.Embed( - color=self.bot.error_color, description=_("Cannot start a thread with a bot."), + color=self.bot.error_color, description="Cannot start a thread with a bot." ) return await ctx.send(embed=embed) @@ -934,9 +902,8 @@ async def contact( if exists: embed = discord.Embed( color=self.bot.error_color, - description=_("A thread for this user already " "exists in {mention}.").format( - mention=exists.channel.mention - ), + description="A thread for this user already " + f"exists in {exists.channel.mention}.", ) await ctx.channel.send(embed=embed) @@ -946,15 +913,13 @@ async def contact( logger.info("Contacting user %s when Modmail DM is disabled.", user) embed = discord.Embed( - title=_("Created Thread"), - description=_("Thread started by {author_mention} " "for {user_mention}.").format( - author_mention=ctx.author.mention, user_mention=user.mention - ), + title="Created Thread", + description=f"Thread started by {ctx.author.mention} for {user.mention}.", color=self.bot.main_color, ) await thread.wait_until_ready() await thread.channel.send(embed=embed) - sent_emoji, x = await self.bot.retrieve_emoji() + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) await asyncio.sleep(3) await ctx.message.delete() @@ -965,9 +930,7 @@ async def contact( async def blocked(self, ctx): """Retrieve a list of blocked users.""" - embeds = [ - discord.Embed(title=_("Blocked Users"), color=self.bot.main_color, description="") - ] + embeds = [discord.Embed(title="Blocked Users", color=self.bot.main_color, description="")] users = [] @@ -986,10 +949,10 @@ async def blocked(self, ctx): embed = embeds[0] for mention, reason in users: - line = mention + f" - {reason or _('No Reason Provided')}\n" + line = mention + f" - {reason or 'No Reason Provided'}\n" if len(embed.description) + len(line) > 2048: embed = discord.Embed( - title=_("Blocked Users") + " " + _("(Continued)"), + title="Blocked Users (Continued)", color=self.bot.main_color, description=line, ) @@ -997,7 +960,7 @@ async def blocked(self, ctx): else: embed.description += line else: - embeds[0].description = _("Currently there are no blocked users.") + embeds[0].description = "Currently there are no blocked users." session = EmbedPaginatorSession(ctx, *embeds) await session.run() @@ -1023,8 +986,8 @@ async def blocked_whitelist(self, ctx, *, user: User = None): if str(user.id) in self.bot.blocked_whitelisted_users: embed = discord.Embed( - title=_("Success"), - description=_("{mention} is no longer whitelisted.").format(mention=mention), + title="Success", + description=f"{mention} is no longer whitelisted.", color=self.bot.main_color, ) self.bot.blocked_whitelisted_users.remove(str(user.id)) @@ -1044,10 +1007,8 @@ async def blocked_whitelist(self, ctx, *, user: User = None): reason = msg[16:].strip().rstrip(".") embed = discord.Embed( title="Success", - description=_( - "{mention} was previously blocked internally for " - '"{reason}". {mention} is now whitelisted.' - ).format(mention=mention, reason=reason), + description=f"{mention} was previously blocked internally for " + f'"{reason}". {mention} is now whitelisted.', color=self.bot.main_color, ) else: @@ -1087,10 +1048,8 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi if str(user.id) in self.bot.blocked_whitelisted_users: embed = discord.Embed( - title=_("Error"), - description=_("Cannot block {mention}, user is whitelisted.").format( - mention=mention - ), + title="Error", + description=f"Cannot block {mention}, user is whitelisted.", color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -1114,20 +1073,16 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi if str(user.id) in self.bot.blocked_users and msg: old_reason = msg.strip().rstrip(".") embed = discord.Embed( - title=_("Success"), - description=_( - "{mention} was previously blocked {old_reason}.\n" - "{mention} is now blocked {reason}" - ).format(mention=mention, old_reason=old_reason, reason=reason), + title="Success", + description=f"{mention} was previously blocked {old_reason}.\n" + f"{mention} is now blocked {reason}", color=self.bot.main_color, ) else: embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_("{mention} is now blocked {reason}").format( - mention=mention, reason=reason - ), + description=f"{mention} is now blocked {reason}", ) self.bot.blocked_users[str(user.id)] = reason await self.bot.config.update() @@ -1166,30 +1121,24 @@ async def unblock(self, ctx, *, user: User = None): reason = msg[16:].strip().rstrip(".") or "no reason" embed = discord.Embed( title="Success", - description=_( - "{mention} was previously blocked internally " - "{reason}.\n{mention} is no longer blocked." - ).format(mention=mention, reason=reason), + description=f"{mention} was previously blocked internally {reason}.\n" + f"{mention} is no longer blocked.", color=self.bot.main_color, ) embed.set_footer( - text=_( - "However, if the original system block reason still applies, " - "{name} will be automatically blocked again. Use " - '"{self.bot.prefix}blocked whitelist {user.id}" to whitelist the user.' - ).format(name=name, prefix=self.bot.prefix, user_id=user.id) + text="However, if the original system block reason still applies, " + f"{name} will be automatically blocked again. " + f'Use "{self.bot.prefix}blocked whitelist {user.id}" to whitelist the user.' ) else: embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_("{mention} is no longer blocked.").format(mention=mention), + description=f"{mention} is no longer blocked.", ) else: embed = discord.Embed( - title=_("Error"), - description=_("{mention} is not blocked.").format(mention=mention), - color=self.bot.error_color, + title="Error", description=f"{mention} is not blocked.", color=self.bot.error_color ) return await ctx.send(embed=embed) @@ -1209,17 +1158,18 @@ async def delete(self, ctx, message_id: int = None): thread = ctx.thread try: - await thread.delete_message(message_id) - except ValueError: + await thread.delete_message(message_id, note=True) + except ValueError as e: + logger.warning("Failed to delete message: %s.", e) return await ctx.send( embed=discord.Embed( - title=_("Failed"), - description=_("Cannot find a message to delete."), + title="Failed", + description="Cannot find a message to delete.", color=self.bot.error_color, ) ) - sent_emoji, x = await self.bot.retrieve_emoji() + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @commands.command() @@ -1341,20 +1291,15 @@ async def enable(self, ctx): Undo's the `{prefix}disable` command, all DM will be relayed after running this command. """ + embed = discord.Embed( + title="Success", + description="Modmail will now accept all DM messages.", + color=self.bot.main_color, + ) if self.bot.config["dm_disabled"] != 0: - embed = discord.Embed( - title=_("Success"), - description=_("Modmail will now accept **all** DM messages."), - color=self.bot.main_color, - ) self.bot.config["dm_disabled"] = 0 await self.bot.config.update() - else: - embed = discord.Embed( - description=_("Modmail is already accepting all DM messages."), - color=self.bot.error_color, - ) return await ctx.send(embed=embed) @@ -1378,27 +1323,12 @@ async def disable_new(self, ctx): No new threads can be created through DM. """ + embed = discord.Embed( + title="Success", + description="Modmail will not create any new threads.", + color=self.bot.main_color, + ) if self.bot.config["dm_disabled"] < 1: - embed = discord.Embed( - title=_("Success"), - description=_("Modmail will not create any **new** threads."), - color=self.bot.main_color, - ) - self.bot.config["dm_disabled"] = 1 - await self.bot.config.update() - elif self.bot.config["dm_disabled"] == 1: - embed = discord.Embed( - description=_("Modmail is already not creating any new threads."), - color=self.bot.error_color, - ) - else: - embed = discord.Embed( - title=_("Success"), - description=_( - "Modmail will not create **new** threads, but existing threads will now be functioning." - ), - color=self.bot.main_color, - ) self.bot.config["dm_disabled"] = 1 await self.bot.config.update() @@ -1412,20 +1342,15 @@ async def disable_all(self, ctx): No new threads can be created through DM nor no further DM messages will be relayed. """ + embed = discord.Embed( + title="Success", + description="Modmail will not accept any DM messages.", + color=self.bot.main_color, + ) - if self.bot.config["dm_disabled"] < 2: - embed = discord.Embed( - title=_("Success"), - description=_("Modmail will not accept **any** DM messages."), - color=self.bot.main_color, - ) + if self.bot.config["dm_disabled"] != 2: self.bot.config["dm_disabled"] = 2 await self.bot.config.update() - else: - embed = discord.Embed( - description=_("Modmail is already not accepting any DM messages."), - color=self.bot.error_color, - ) return await ctx.send(embed=embed) @@ -1438,22 +1363,20 @@ async def isenable(self, ctx): if self.bot.config["dm_disabled"] == 1: embed = discord.Embed( - title=_("New Threads Disabled"), - description=_("Modmail is not creating new threads."), + title="New Threads Disabled", + description="Modmail is not creating new threads.", color=self.bot.error_color, ) elif self.bot.config["dm_disabled"] == 2: embed = discord.Embed( - title=_("All DM Disabled"), - description=_( - "Modmail is not accepting any DM messages for new and existing threads." - ), + title="All DM Disabled", + description="Modmail is not accepting any DM messages for new and existing threads.", color=self.bot.error_color, ) else: embed = discord.Embed( - title=_("Enabled"), - description=_("Modmail is accepting all DM messages."), + title="Enabled", + description="Modmail now is accepting all DM messages.", color=self.bot.main_color, ) diff --git a/cogs/plugins.py b/cogs/plugins.py index 4d335607e1..227cfc8270 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -104,7 +104,7 @@ def __init__(self, bot): self.bot.loop.create_task(self.populate_registry()) - if getattr(self.bot, "config", None) and self.bot.config.get("enable_plugins"): + if self.bot.config.get("enable_plugins"): self.bot.loop.create_task(self.initial_load_plugins()) else: logger.info("Plugins not loaded since ENABLE_PLUGINS=false.") @@ -136,7 +136,12 @@ async def initial_load_plugins(self): await self.download_plugin(plugin) await self.load_plugin(plugin) except Exception: - logger.error("Error when loading plugin %s.", plugin, exc_info=True) + self.bot.config["plugins"].remove(plugin_name) + logger.error( + "Error when loading plugin %s. Plugin removed from config.", + plugin, + exc_info=True, + ) continue logger.debug("Finished loading all plugins.") @@ -152,11 +157,26 @@ async def download_plugin(self, plugin, force=False): if plugin.cache_path.exists() and not force: plugin_io = plugin.cache_path.open("rb") logger.debug("Loading cached %s.", plugin.cache_path) - else: - async with self.bot.session.get(plugin.url) as resp: + headers = {} + github_token = self.bot.config["github_token"] + if github_token is not None: + headers["Authorization"] = f"token {github_token}" + + async with self.bot.session.get(plugin.url, headers=headers) as resp: logger.debug("Downloading %s.", plugin.url) raw = await resp.read() + + try: + raw = await resp.text() + except UnicodeDecodeError: + pass + else: + if raw == 'Not Found': + raise InvalidPluginError('Plugin not found') + else: + raise InvalidPluginError('Invalid download recieved, non-bytes object') + plugin_io = io.BytesIO(raw) if not plugin.cache_path.parent.exists(): plugin.cache_path.parent.mkdir(parents=True) @@ -187,10 +207,10 @@ async def load_plugin(self, plugin): if req_txt.exists(): # Install PIP requirements - venv = hasattr(sys, "real_prefix") # in a virtual env + venv = hasattr(sys, "real_prefix") or hasattr(sys, "base_prefix") # in a virtual env user_install = " --user" if not venv else "" proc = await asyncio.create_subprocess_shell( - f"{sys.executable} -m pip install --upgrade{user_install} -r {req_txt} -q -q", + f'"{sys.executable}" -m pip install --upgrade{user_install} -r {req_txt} -q -q', stderr=PIPE, stdout=PIPE, ) @@ -227,7 +247,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if not self._ready_event.is_set(): embed = discord.Embed( - description=_("Plugins are still loading, please try again later."), + description="Plugins are still loading, please try again later.", color=self.bot.main_color, ) await ctx.send(embed=embed) @@ -243,10 +263,8 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if required_version and self.bot.version < parse_version(required_version): embed = discord.Embed( - description=_( - "Your bot's version is too low. " - "This plugin requires version `{required_version}`." - ).format(required_version=required_version), + description="Your bot's version is too low. " + f"This plugin requires version `{required_version}`.", color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -259,11 +277,9 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): plugin = Plugin.from_string(plugin_name) except InvalidPluginError: embed = discord.Embed( - description=_( - "Invalid plugin name, double check the plugin name " - "or use one of the following formats: " - "username/repo/plugin, username/repo/plugin@branch." - ), + description="Invalid plugin name, double check the plugin name " + "or use one of the following formats: " + "username/repo/plugin, username/repo/plugin@branch.", color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -296,33 +312,31 @@ async def plugins_add(self, ctx, *, plugin_name: str): if str(plugin) in self.bot.config["plugins"]: embed = discord.Embed( - description=_("This plugin is already installed."), color=self.bot.error_color, + description="This plugin is already installed.", color=self.bot.error_color ) return await ctx.send(embed=embed) if plugin.name in self.bot.cogs: # another class with the same name embed = discord.Embed( - description=_("Cannot install this plugin (dupe cog name)."), + description="Cannot install this plugin (dupe cog name).", color=self.bot.error_color, ) return await ctx.send(embed=embed) embed = discord.Embed( - description=_("Starting to download plugin from {plugin_link}...").format( - plugin_link=plugin.link - ), + description=f"Starting to download plugin from {plugin.link}...", color=self.bot.main_color, ) msg = await ctx.send(embed=embed) try: await self.download_plugin(plugin, force=True) - except Exception: + except Exception as e: logger.warning("Unable to download plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description=_("Failed to download plugin, check logs for error."), + description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", color=self.bot.error_color, ) @@ -337,35 +351,28 @@ async def plugins_add(self, ctx, *, plugin_name: str): try: await self.load_plugin(plugin) - except Exception: + except Exception as e: logger.warning("Unable to load plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description=_("Failed to download plugin, check logs for error."), + description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", color=self.bot.error_color, ) else: embed = discord.Embed( - description=_( - "Successfully installed plugin.\n" - "*Friendly reminder, plugins have absolute control over your bot. " - "Please only install plugins from developers you trust.*" - ), + description="Successfully installed plugin.\n" + "*Friendly reminder, plugins have absolute control over your bot. " + "Please only install plugins from developers you trust.*", color=self.bot.main_color, ) else: embed = discord.Embed( - description=_( - "Successfully installed plugin.\n" - "*Friendly reminder, plugins have absolute control over your bot. " - "Please only install plugins from developers you trust.*" - ) - + "\n\n" - + _( - "This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, " - "to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot." - ), + description="Successfully installed plugin.\n" + "*Friendly reminder, plugins have absolute control over your bot. " + "Please only install plugins from developers you trust.*\n\n" + "This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, " + "to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot.", color=self.bot.main_color, ) return await msg.edit(embed=embed) @@ -385,7 +392,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): if str(plugin) not in self.bot.config["plugins"]: embed = discord.Embed( - description=_("Plugin is not installed."), color=self.bot.error_color + description="Plugin is not installed.", color=self.bot.error_color ) return await ctx.send(embed=embed) @@ -411,7 +418,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): pass # dir not empty embed = discord.Embed( - description=_("The plugin is successfully uninstalled."), color=self.bot.main_color, + description="The plugin is successfully uninstalled.", color=self.bot.main_color ) await ctx.send(embed=embed) @@ -423,25 +430,33 @@ async def update_plugin(self, ctx, plugin_name): if str(plugin) not in self.bot.config["plugins"]: embed = discord.Embed( - description=_("Plugin is not installed."), color=self.bot.error_color + description="Plugin is not installed.", color=self.bot.error_color ) return await ctx.send(embed=embed) async with ctx.typing(): + embed = discord.Embed( + description=f"Successfully updated {plugin.name}.", color=self.bot.main_color + ) await self.download_plugin(plugin, force=True) if self.bot.config.get("enable_plugins"): try: self.bot.unload_extension(plugin.ext_string) except commands.ExtensionError: logger.warning("Plugin unload fail.", exc_info=True) - await self.load_plugin(plugin) - logger.debug("Updated %s.", plugin_name) - embed = discord.Embed( - description=_("Successfully updated {plugin_name}.").format( - plugin_name=plugin.name - ), - color=self.bot.main_color, - ) + try: + await self.load_plugin(plugin) + except Exception: + embed = discord.Embed( + description=f"Failed to update {plugin.name}. This plugin will now be removed from your bot.", + color=self.bot.error_color, + ) + self.bot.config["plugins"].remove(plugin_name) + logger.debug("Failed to update %s. Removed plugin from config.", plugin_name) + else: + logger.debug("Updated %s.", plugin_name) + else: + logger.debug("Updated %s.", plugin_name) return await ctx.send(embed=embed) @plugins.command(name="update") @@ -458,11 +473,45 @@ async def plugins_update(self, ctx, *, plugin_name: str = None): if plugin_name is None: # pylint: disable=redefined-argument-from-local - for plugin_name in self.bot.config["plugins"]: + for plugin_name in list(self.bot.config["plugins"]): await self.update_plugin(ctx, plugin_name) else: await self.update_plugin(ctx, plugin_name) + @plugins.command(name="reset") + @checks.has_permissions(PermissionLevel.OWNER) + async def plugins_reset(self, ctx): + """ + Reset all plugins for the bot. + + Deletes all cache and plugins from config and unloads from the bot. + """ + logger.warning("Purging plugins.") + for ext in list(self.bot.extensions): + if not ext.startswith("plugins."): + continue + try: + logger.error("Unloading plugin: %s.", ext) + self.bot.unload_extension(ext) + except Exception: + logger.error("Failed to unload plugin: %s.", ext) + self.bot.config["plugins"].clear() + + cache_path = Path(__file__).absolute().parent.parent / "temp" / "plugins-cache" + if cache_path.exists(): + logger.warning("Removing cache path.") + shutil.rmtree(cache_path) + + for entry in os.scandir(Path(__file__).absolute().parent.parent / "plugins"): + if entry.is_dir(): + shutil.rmtree(entry.path) + logger.warning("Removing %s.", entry.name) + + embed = discord.Embed( + description="Successfully purged all plugins from the bot.", color=self.bot.main_color + ) + return await ctx.send(embed=embed) + @plugins.command(name="loaded", aliases=["enabled", "installed"]) @checks.has_permissions(PermissionLevel.OWNER) async def plugins_loaded(self, ctx): @@ -472,25 +521,22 @@ async def plugins_loaded(self, ctx): if not self.bot.config.get("enable_plugins"): embed = discord.Embed( - description=_( - "No plugins are loaded due to `ENABLE_PLUGINS=false`, " - "to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot." - ), + description="No plugins are loaded due to `ENABLE_PLUGINS=false`, " + "to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot.", color=self.bot.error_color, ) return await ctx.send(embed=embed) if not self._ready_event.is_set(): embed = discord.Embed( - description=_("Plugins are still loading, please try again later."), + description="Plugins are still loading, please try again later.", color=self.bot.main_color, ) return await ctx.send(embed=embed) if not self.loaded_plugins: embed = discord.Embed( - description=_("There are no plugins currently loaded."), - color=self.bot.error_color, + description="There are no plugins currently loaded.", color=self.bot.error_color ) return await ctx.send(embed=embed) @@ -510,7 +556,7 @@ async def plugins_loaded(self, ctx): embeds = [] for page in pages: embed = discord.Embed( - title=_("Loaded plugins:"), description=page, color=self.bot.main_color + title="Loaded plugins:", description=page, color=self.bot.main_color ) embeds.append(embed) paginator = EmbedPaginatorSession(ctx, *embeds) @@ -546,16 +592,14 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N if not index and plugin_name is not None: embed = discord.Embed( color=self.bot.error_color, - description=_( - 'Could not find a plugin with name "{plugin_name}" within the registry.' - ).format(plugin_name=plugin_name), + description=f'Could not find a plugin with name "{plugin_name}" within the registry.', ) matches = get_close_matches(plugin_name, self.registry.keys()) if matches: embed.add_field( - name=_("Perhaps you meant:"), value="\n".join(f"`{m}`" for m in matches), + name="Perhaps you meant:", value="\n".join(f"`{m}`" for m in matches) ) return await ctx.send(embed=embed) @@ -575,7 +619,7 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N ) embed.add_field( - name=_("Installation"), value=f"```{self.bot.prefix}plugins add {plugin_name}```", + name="Installation", value=f"```{self.bot.prefix}plugins add {name}```" ) embed.set_author( @@ -594,13 +638,11 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N required_version = details.get("bot_version", False) if required_version and self.bot.version < parse_version(required_version): embed.set_footer( - text=_( - "Your bot is unable to install this plugin, " - "minimum required version is v{required_version}." - ).format(required_version=required_version) + text="Your bot is unable to install this plugin, " + f"minimum required version is v{required_version}." ) else: - embed.set_footer(text=_("Your bot is able to install this plugin.")) + embed.set_footer(text="Your bot is able to install this plugin.") embeds.append(embed) @@ -655,7 +697,7 @@ async def plugins_registry_compact(self, ctx): for page in pages: embed = discord.Embed(color=self.bot.main_color, description=page) - embed.set_author(name=_("Plugin Registry"), icon_url=self.bot.user.avatar_url) + embed.set_author(name="Plugin Registry", icon_url=self.bot.user.avatar_url) embeds.append(embed) paginator = EmbedPaginatorSession(ctx, *embeds) diff --git a/cogs/utility.py b/cogs/utility.py index 9974deb803..b0d96ea094 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -47,7 +47,7 @@ async def format_cog_help(self, cog, *, no_cog=False): else: format_ = f"`[{perm_level}] {prefix + cmd.qualified_name}` " - format_ += f"- {_(cmd.short_doc)}\n" + format_ += f"- {cmd.short_doc}\n" if cmd.short_doc else "- *No description.*\n" if not format_.strip(): continue if len(format_) + len(formats[-1]) >= 1024: @@ -58,26 +58,21 @@ async def format_cog_help(self, cog, *, no_cog=False): embeds = [] for format_ in formats: description = ( - _(cog.description) or _("No description.") + cog.description or "No description." if not no_cog - else _("Miscellaneous commands without a category.") + else "Miscellaneous commands without a category." ) embed = discord.Embed(description=f"*{description}*", color=bot.main_color) - embed.add_field(name=_("Commands"), value=format_ or _("No commands.")) + embed.add_field(name="Commands", value=format_ or "No commands.") - continued = " " + _("(Continued)") if embeds else "" - name = ( - cog.qualified_name + " - " + _("Help") - if not no_cog - else _("Miscellaneous Commands") - ) + continued = " (Continued)" if embeds else "" + name = cog.qualified_name + " - Help" if not no_cog else "Miscellaneous Commands" embed.set_author(name=name + continued, icon_url=bot.user.avatar_url) embed.set_footer( - text=_( - 'Type "{prefix}{command} command" ' "for more info on a specific command." - ).format(prefix=prefix, command=self.command_attrs["name"]) + text=f'Type "{prefix}{self.command_attrs["name"]} command" ' + "for more info on a specific command." ) embeds.append(embed) return embeds @@ -117,19 +112,19 @@ async def _get_help_embed(self, topic): if perm_level is not PermissionLevel.INVALID: perm_level = f"{perm_level.name} [{perm_level}]" else: - perm_level = _("NONE") + perm_level = "NONE" embed = discord.Embed( title=f"`{self.get_command_signature(topic)}`", color=self.context.bot.main_color, - description=self.process_help_msg(_(topic.help)), + description=self.process_help_msg(topic.help), ) return embed, perm_level async def send_command_help(self, command): topic = await self._get_help_embed(command) if topic is not None: - topic[0].set_footer(text=_("Permission level: {level}").format(level=topic[1])) + topic[0].set_footer(text=f"Permission level: {topic[1]}") await self.get_destination().send(embed=topic[0]) async def send_group_help(self, group): @@ -137,7 +132,7 @@ async def send_group_help(self, group): if topic is None: return embed = topic[0] - embed.add_field(name=_("Permission Level"), value=topic[1], inline=False) + embed.add_field(name="Permission Level", value=topic[1], inline=False) format_ = "" length = len(group.commands) @@ -151,13 +146,12 @@ async def send_group_help(self, group): branch = "└─" else: branch = "├─" - format_ += f"`{branch} {command.name}` - {_(command.short_doc)}\n" + format_ += f"`{branch} {command.name}` - {command.short_doc}\n" - embed.add_field(name=_("Sub Command(s)"), value=format_[:1024], inline=False) + embed.add_field(name="Sub Command(s)", value=format_[:1024], inline=False) embed.set_footer( - text=_('Type "{prefix}{command} command" ' "for more info on a command.").format( - prefix=self.clean_prefix, command=self.command_attrs["name"] - ) + text=f'Type "{self.clean_prefix}{self.command_attrs["name"]} command" ' + "for more info on a command." ) await self.get_destination().send(embed=embed) @@ -167,8 +161,7 @@ async def send_error_message(self, error): val = self.context.bot.snippets.get(command) if val is not None: embed = discord.Embed( - title=_("{command} is a snippet.").format(command=command), - color=self.context.bot.main_color, + title=f"{command} is a snippet.", color=self.context.bot.main_color ) embed.add_field(name=f"`{command}` will send:", value=val) return await self.get_destination().send(embed=embed) @@ -179,12 +172,10 @@ async def send_error_message(self, error): if not values: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.context.bot.error_color, - description=_( - "Alias `{command}` is invalid, this alias will now be deleted." - "This alias will now be deleted." - ).format(command=command), + description=f"Alias `{command}` is invalid, this alias will now be deleted." + "This alias will now be deleted.", ) embed.add_field(name=f"{command}` used to be:", value=val) self.context.bot.aliases.pop(command) @@ -192,34 +183,28 @@ async def send_error_message(self, error): else: if len(values) == 1: embed = discord.Embed( - title=_("{command} is an alias.").format(command=command), - color=self.context.bot.main_color, - ) - embed.add_field( - name=_("`{command}` points to:").format(command=command), value=values[0] + title=f"{command} is an alias.", color=self.context.bot.main_color ) + embed.add_field(name=f"`{command}` points to:", value=values[0]) else: embed = discord.Embed( - title=_("{command} is an alias.").format(command=command), + title=f"{command} is an alias.", color=self.context.bot.main_color, - description=_("**`{command}` points to the following steps:**").format( - command=command - ), + description=f"**`{command}` points to the following steps:**", ) for i, val in enumerate(values, start=1): - embed.add_field(name=_("Step") + f" {i}:", value=val) + embed.add_field(name=f"Step {i}:", value=val) embed.set_footer( - text=_('Type "{prefix}{command} alias" ' "for more details on aliases.").format( - prefix=self.clean_prefix, command=self.command_attrs["name"] - ) + text=f'Type "{self.clean_prefix}{self.command_attrs["name"]} alias" ' + "for more details on aliases." ) return await self.get_destination().send(embed=embed) logger.warning("CommandNotFound: %s", error) embed = discord.Embed(color=self.context.bot.error_color) - embed.set_footer(text=_('Command/Category "{command}" not found.').format(command=command)) + embed.set_footer(text=f'Command/Category "{command}" not found.') choices = set() @@ -229,15 +214,12 @@ async def send_error_message(self, error): closest = get_close_matches(command, choices) if closest: - embed.add_field( - name=_("Perhaps you meant:"), value="\n".join(f"`{x}`" for x in closest) - ) + embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) else: - embed.title = _("Cannot find command or category") + embed.title = "Cannot find command or category" embed.set_footer( - text=_('Type "{prefix}{command}" ' "for a list of all available commands.").format( - prefix=self.clean_prefix, command=self.command_attrs["name"] - ) + text=f'Type "{self.clean_prefix}{self.command_attrs["name"]}" ' + "for a list of all available commands." ) await self.get_destination().send(embed=embed) @@ -251,12 +233,15 @@ def __init__(self, bot): self.bot.help_command = ModmailHelpCommand( verify_checks=False, command_attrs={ - "help": _("Shows this help message."), + "help": "Shows this help message.", "checks": [checks.has_permissions_predicate(PermissionLevel.REGULAR)], }, ) self.bot.help_command.cog = self self.loop_presence.start() # pylint: disable=no-member + if not self.bot.config.get("enable_eval"): + self.eval_.enabled = False + logger.info("Eval disabled. enable_eval=False") def cog_unload(self): self.bot.help_command = self._original_help_command @@ -275,9 +260,7 @@ async def changelog(self, ctx, version: str.lower = ""): return await ctx.send( embed=discord.Embed( color=self.bot.error_color, - description=_("The specified version `{version}` could not be found.").format( - version=version - ), + description=f"The specified version `{version}` could not be found.", ) ) @@ -293,9 +276,7 @@ async def changelog(self, ctx, version: str.lower = ""): finally: logger.warning("Failed to display changelog.", exc_info=True) await ctx.send( - _("View the changelog here: {url}").format( - url=f"{changelog.latest_version.changelog_url}#v{version[::2]}" - ) + f"View the changelog here: {changelog.latest_version.changelog_url}#v{version[::2]}" ) @commands.command(aliases=["info"]) @@ -305,23 +286,21 @@ async def about(self, ctx): """Shows information about this bot.""" embed = discord.Embed(color=self.bot.main_color, timestamp=datetime.utcnow()) embed.set_author( - name=_("Modmail - About"), + name="Modmail - About", icon_url=self.bot.user.avatar_url, url="https://discord.gg/F34cRU8", ) embed.set_thumbnail(url=self.bot.user.avatar_url) - desc = _( - "This is an open source Discord bot that serves as a means for " - "members to easily communicate with server administrators in " - "an organised manner." - ) + desc = "This is an open source Discord bot that serves as a means for " + desc += "members to easily communicate with server administrators in " + desc += "an organised manner." embed.description = desc - embed.add_field(name=_("Uptime"), value=self.bot.uptime) - embed.add_field(name=_("Latency"), value=f"{self.bot.latency * 1000:.2f} ms") - embed.add_field(name=_("Version"), value=f"`{self.bot.version}`") - embed.add_field(name=_("Authors"), value="`kyb3r`, `Taki`, `fourjr`") + embed.add_field(name="Uptime", value=self.bot.uptime) + embed.add_field(name="Latency", value=f"{self.bot.latency * 1000:.2f} ms") + embed.add_field(name="Version", value=f"`{self.bot.version}`") + embed.add_field(name="Authors", value="`kyb3r`, `Taki`, `fourjr`") changelog = await Changelog.from_url(self.bot) latest = changelog.latest_version @@ -330,30 +309,26 @@ async def about(self, ctx): stable = next( filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions) ) - footer = _( - "You are on the prerelease version • the latest version is v{version}." - ).format(version=stable.version) + footer = ( + f"You are on the prerelease version • the latest version is v{stable.version}." + ) elif self.bot.version < parse_version(latest.version): - footer = _("A newer version is available v{version}.").format(version=latest.version) + footer = f"A newer version is available v{latest.version}." else: - footer = _("You are up to date with the latest version.") + footer = "You are up to date with the latest version." embed.add_field( - name=_("Want Modmail in Your Server?"), - value=_( - "Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " - "and join our [Discord server](https://discord.gg/F34cRU8/)!" - ), + name="Want Modmail in Your Server?", + value="Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " + "and join our [Discord server](https://discord.gg/F34cRU8/)!", inline=False, ) embed.add_field( - name=_("Support the Developers"), - value=_( - "This bot is completely free for everyone. We rely on kind individuals " - "like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) " - "to keep this bot free forever!" - ), + name="Support the Developers", + value="This bot is completely free for everyone. We rely on kind individuals " + "like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) " + "to keep this bot free forever!", inline=False, ) @@ -400,10 +375,10 @@ async def debug(self, ctx): if not logs: embed = discord.Embed( color=self.bot.main_color, - title=_("Debug Logs:"), - description=_("You don't have any logs at the moment."), + title="Debug Logs:", + description="You don't have any logs at the moment.", ) - embed.set_footer(text=_("Go to Heroku to see your logs.")) + embed.set_footer(text="Go to Heroku to see your logs.") return await ctx.send(embed=embed) messages = [] @@ -429,7 +404,7 @@ async def debug(self, ctx): messages.append(msg) embed = discord.Embed(color=self.bot.main_color) - embed.set_footer(text=_("Debug logs - Navigate using the reactions below.")) + embed.set_footer(text="Debug logs - Navigate using the reactions below.") session = MessagePaginatorSession(ctx, *messages, embed=embed) session.current = len(messages) - 1 @@ -461,7 +436,7 @@ async def debug_hastebin(self, ctx): logger.error(data["message"]) raise embed = discord.Embed( - title=_("Debug Logs"), + title="Debug Logs", color=self.bot.main_color, description=f"{haste_url}/" + key, ) @@ -469,9 +444,9 @@ async def debug_hastebin(self, ctx): embed = discord.Embed( title="Debug Logs", color=self.bot.main_color, - description=_("Something's wrong. We're unable to upload your logs to hastebin."), + description="Something's wrong. We're unable to upload your logs to hastebin.", ) - embed.set_footer(text=_("Go to Heroku to see your logs.")) + embed.set_footer(text="Go to Heroku to see your logs.") await ctx.send(embed=embed) @debug.command(name="clear", aliases=["wipe"]) @@ -491,7 +466,7 @@ async def debug_clear(self, ctx): pass await ctx.send( embed=discord.Embed( - color=self.bot.main_color, description=_("Cached logs are now cleared.") + color=self.bot.main_color, description="Cached logs are now cleared." ) ) @@ -522,7 +497,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): self.bot.config.remove("activity_message") await self.bot.config.update() await self.set_presence() - embed = discord.Embed(title=_("Activity Removed"), color=self.bot.main_color) + embed = discord.Embed(title="Activity Removed", color=self.bot.main_color) return await ctx.send(embed=embed) if not message: @@ -533,7 +508,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): except KeyError: raise commands.MissingRequiredArgument(SimpleNamespace(name="activity")) - activity, x = await self.set_presence( + activity, _ = await self.set_presence( activity_type=activity_type, activity_message=message ) @@ -541,15 +516,13 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): self.bot.config["activity_message"] = activity.name await self.bot.config.update() - msg = _("Activity set to: {name} ").format(name=activity.type.name.capitalize()) + msg = f"Activity set to: {activity.type.name.capitalize()} " if activity.type == ActivityType.listening: - msg += _("to {name}.").format(name=activity.name) + msg += f"to {activity.name}." else: msg += f"{activity.name}." - embed = discord.Embed( - title=_("Activity Changed"), description=msg, color=self.bot.main_color - ) + embed = discord.Embed(title="Activity Changed", description=msg, color=self.bot.main_color) return await ctx.send(embed=embed) @commands.command() @@ -571,7 +544,7 @@ async def status(self, ctx, *, status_type: str.lower): self.bot.config.remove("status") await self.bot.config.update() await self.set_presence() - embed = discord.Embed(title=_("Status Removed"), color=self.bot.main_color) + embed = discord.Embed(title="Status Removed", color=self.bot.main_color) return await ctx.send(embed=embed) status_type = status_type.replace(" ", "_") @@ -580,15 +553,13 @@ async def status(self, ctx, *, status_type: str.lower): except KeyError: raise commands.MissingRequiredArgument(SimpleNamespace(name="status")) - x, status = await self.set_presence(status=status) + _, status = await self.set_presence(status=status) self.bot.config["status"] = status.value await self.bot.config.update() - msg = _("Status set to: {value}.").format(value=status.value) - embed = discord.Embed( - title=_("Status Changed"), description=msg, color=self.bot.main_color - ) + msg = f"Status set to: {status.value}." + embed = discord.Embed(title="Status Changed", description=msg, color=self.bot.main_color) return await ctx.send(embed=embed) async def set_presence(self, *, status=None, activity_type=None, activity_message=None): @@ -659,7 +630,7 @@ async def before_loop_presence(self): async def ping(self, ctx): """Pong! Returns your websocket latency.""" embed = discord.Embed( - title=_("Pong! Websocket Latency:"), + title="Pong! Websocket Latency:", description=f"{self.bot.ws.latency * 1000:.4f} ms", color=self.bot.main_color, ) @@ -667,7 +638,7 @@ async def ping(self, ctx): @commands.command() @checks.has_permissions(PermissionLevel.ADMINISTRATOR) - async def mention(self, ctx, *, mention: str = None): + async def mention(self, ctx, *mention: Union[discord.Role, discord.Member]): """ Change what the bot mentions at the start of each thread. @@ -676,16 +647,15 @@ async def mention(self, ctx, *, mention: str = None): # TODO: ability to disable mention. current = self.bot.config["mention"] - if mention is None: + if not mention: embed = discord.Embed( - title=_("Current mention:"), color=self.bot.main_color, description=str(current), + title="Current mention:", color=self.bot.main_color, description=str(current) ) else: + mention = " ".join(i.mention for i in mention) embed = discord.Embed( - title=_("Changed mention!"), - description=_('On thread creation the bot now says "{mention}".').format( - mention=mention - ), + title="Changed mention!", + description=f'On thread creation the bot now says "{mention}".', color=self.bot.main_color, ) self.bot.config["mention"] = mention @@ -704,14 +674,14 @@ async def prefix(self, ctx, *, prefix=None): current = self.bot.prefix embed = discord.Embed( - title=_("Current prefix"), color=self.bot.main_color, description=f"{current}" + title="Current prefix", color=self.bot.main_color, description=f"{current}" ) if prefix is None: await ctx.send(embed=embed) else: - embed.title = _("Changed prefix!") - embed.description = _("Set prefix to `{prefix}`").format(prefix=prefix) + embed.title = "Changed prefix!" + embed.description = f"Set prefix to `{prefix}`" self.bot.config["prefix"] = prefix await self.bot.config.update() await ctx.send(embed=embed) @@ -746,7 +716,7 @@ async def config_options(self, ctx): f"`{name}`" for name in takewhile(lambda x: x is not None, names) ) embed = discord.Embed( - title=_("Available configuration keys:"), + title="Available configuration keys:", color=self.bot.main_color, description=description, ) @@ -767,22 +737,18 @@ async def config_set(self, ctx, key: str.lower, *, value: str): self.bot.config.set(key, value) await self.bot.config.update() embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_("Set `{key}` to `{value}`.").format( - key=key, value=self.bot.config[key] - ), + description=f"Set `{key}` to `{self.bot.config[key]}`.", ) except InvalidConfigError as exc: embed = exc.embed else: embed = discord.Embed( - title=_("Error"), - color=self.bot.error_color, - description=_("{key} is an invalid key.").format(key=key), + title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." ) valid_keys = [f"`{k}`" for k in sorted(keys)] - embed.add_field(name=_("Valid keys"), value=", ".join(valid_keys)) + embed.add_field(name="Valid keys", value=", ".join(valid_keys)) return await ctx.send(embed=embed) @@ -795,18 +761,16 @@ async def config_remove(self, ctx, *, key: str.lower): self.bot.config.remove(key) await self.bot.config.update() embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_("`{key}` had been reset to default.").format(key=key), + description=f"`{key}` had been reset to default.", ) else: embed = discord.Embed( - title=_("Error"), - color=self.bot.error_color, - description=_("{key} is an invalid key.").format(key=key), + title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." ) valid_keys = [f"`{k}`" for k in sorted(keys)] - embed.add_field(name=_("Valid keys"), value=", ".join(valid_keys)) + embed.add_field(name="Valid keys", value=", ".join(valid_keys)) return await ctx.send(embed=embed) @@ -822,28 +786,25 @@ async def config_get(self, ctx, *, key: str.lower = None): if key: if key in keys: - desc = _("`{key}` is set to `{value}`").format(key=key, value=self.bot.config[key]) + desc = f"`{key}` is set to `{self.bot.config[key]}`" embed = discord.Embed(color=self.bot.main_color, description=desc) - embed.set_author(name=_("Config variable"), icon_url=self.bot.user.avatar_url) + embed.set_author(name="Config variable", icon_url=self.bot.user.avatar_url) else: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("`{key}` is an invalid key.").format(key=key), + description=f"`{key}` is an invalid key.", ) embed.set_footer( - text=_('Type "{prefix}config options" for a list of config variables.').format( - prefix=self.bot.prefix - ) + text=f'Type "{self.bot.prefix}config options" for a list of config variables.' ) else: embed = discord.Embed( color=self.bot.main_color, - description=_("Here is a list of currently " "set configuration variable(s)."), + description="Here is a list of currently set configuration variable(s).", ) - embed.set_author(name=_("Current config(s):"), icon_url=self.bot.user.avatar_url) embed.set_author(name="Current config(s):", icon_url=self.bot.user.avatar_url) config = self.bot.config.filter_default(self.bot.config) @@ -866,9 +827,9 @@ async def config_help(self, ctx, key: str.lower = None): key, {**self.bot.config.public_keys, **self.bot.config.protected_keys} ) embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("`{key}` is an invalid key.").format(key=key), + description=f"`{key}` is an invalid key.", ) if closest: embed.add_field( @@ -880,9 +841,9 @@ async def config_help(self, ctx, key: str.lower = None): if key is not None and key not in config_help: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("No help details found for `{key}`.").format(key=key), + description=f"No help details found for `{key}`.", ) return await ctx.send(embed=embed) @@ -895,24 +856,21 @@ def fmt(val): if current_key == key: index = i embed = discord.Embed( - title=_("Configuration description on {current_key}:").format( - current_key=current_key - ), - color=self.bot.main_color, + title=f"Configuration description on {current_key}:", color=self.bot.main_color ) embed.add_field(name="Default:", value=fmt(info["default"]), inline=False) - embed.add_field(name=_("Information:"), value=fmt(info["description"]), inline=False) + embed.add_field(name="Information:", value=fmt(info["description"]), inline=False) if info["examples"]: example_text = "" for example in info["examples"]: example_text += f"- {fmt(example)}\n" - embed.add_field(name=_("Example(s):"), value=example_text, inline=False) + embed.add_field(name="Example(s):", value=example_text, inline=False) note_text = "" for note in info["notes"]: note_text += f"- {fmt(note)}\n" if note_text: - embed.add_field(name=_("Note(s):"), value=note_text, inline=False) + embed.add_field(name="Note(s):", value=note_text, inline=False) if info.get("image") is not None: embed.set_image(url=fmt(info["image"])) @@ -957,12 +915,10 @@ async def alias(self, ctx, *, name: str.lower = None): if not values: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_( - "Alias `{name}` is invalid, it used to be `{value}`. " - "This alias will now be deleted." - ).format(name=name, value=escape_markdown(val)), + description=f"Alias `{name}` is invalid, this alias will now be deleted." + "This alias will now be deleted.", ) embed.add_field(name=f"{name}` used to be:", value=utils.truncate(val, 1024)) self.bot.aliases.pop(name) @@ -971,9 +927,7 @@ async def alias(self, ctx, *, name: str.lower = None): if len(values) == 1: embed = discord.Embed( - title=_("Alias") + f' - "{name}":', - description=values[0], - color=self.bot.main_color, + title=f'Alias - "{name}":', description=values[0], color=self.bot.main_color ) return await ctx.send(embed=embed) @@ -991,13 +945,10 @@ async def alias(self, ctx, *, name: str.lower = None): if not self.bot.aliases: embed = discord.Embed( - color=self.bot.error_color, - description=_("You dont have any aliases at the moment."), - ) - embed.set_footer( - text=_("Do {prefix}help alias for more commands.").format(prefix=self.bot.prefix) + color=self.bot.error_color, description="You dont have any aliases at the moment." ) - embed.set_author(name=_("Aliases"), icon_url=ctx.guild.icon_url) + embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') + embed.set_author(name="Aliases", icon_url=ctx.guild.icon_url) return await ctx.send(embed=embed) embeds = [] @@ -1005,7 +956,7 @@ async def alias(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.aliases)),) * 15)): description = utils.format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name=_("Command Aliases"), icon_url=ctx.guild.icon_url) + embed.set_author(name="Command Aliases", icon_url=ctx.guild.icon_url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1033,9 +984,9 @@ async def make_alias(self, name, value, action): values = utils.parse_alias(value) if not values: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("Invalid multi-step alias, try wrapping each steps in quotes."), + description="Invalid multi-step alias, try wrapping each steps in quotes.", ) embed.set_footer(text=f'See "{self.bot.prefix}alias add" for more details.') return embed @@ -1050,15 +1001,12 @@ async def make_alias(self, name, value, action): multiple_alias = len(values) > 1 - embed = discord.Embed(title=_("{action} alias").format(action), color=self.bot.main_color) + embed = discord.Embed(title=f"{action} alias", color=self.bot.main_color) if not multiple_alias: - embed.add_field( - name=_("`{name}` points to:").format(name=name), - value=utils.truncate(values[0], 1024), - ) + embed.add_field(name=f"`{name}` points to:", value=utils.truncate(values[0], 1024)) else: - embed.description = _("`{name}` now points to the following steps:").format(name=name) + embed.description = f"`{name}` now points to the following steps:" for i, val in enumerate(values, start=1): view = StringView(val) @@ -1073,21 +1021,21 @@ async def make_alias(self, name, value, action): embed = discord.Embed(title="Error", color=self.bot.error_color) if multiple_alias: - embed.description = _( + embed.description = ( "The command you are attempting to point " - "to does not exist: `{command}`." - ).format(command=linked_command) + f"to does not exist: `{linked_command}`." + ) else: - embed.description = _( + embed.description = ( "The command you are attempting to point " - "to on step {number} does not exist: `{command}`." - ).format(number=i, command=linked_command) + f"to on step {i} does not exist: `{linked_command}`." + ) return embed else: save_aliases.append(val) if multiple_alias: - embed.add_field(name=_("Step") + f" {i}:", value=utils.truncate(val, 1024)) + embed.add_field(name=f"Step {i}:", value=utils.truncate(val, 1024)) self.bot.aliases[name] = " && ".join(f'"{a}"' for a in save_aliases) await self.bot.config.update() @@ -1112,36 +1060,30 @@ async def alias_add(self, ctx, name: str.lower, *, value): embed = None if self.bot.get_command(name): embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("A command with the same name already exists: `{name}`.").format( - name=name - ), + description=f"A command with the same name already exists: `{name}`.", ) elif name in self.bot.aliases: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("Another alias with the same name already exists: `{name}`.").format( - name=name - ), + description=f"Another alias with the same name already exists: `{name}`.", ) elif name in self.bot.snippets: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("A snippet with the same name already exists: `{name}`.").format( - name=name - ), + description=f"A snippet with the same name already exists: `{name}`.", ) elif len(name) > 120: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("Alias names cannot be longer than 120 characters."), + description="Alias names cannot be longer than 120 characters.", ) if embed is None: @@ -1158,9 +1100,9 @@ async def alias_remove(self, ctx, *, name: str.lower): await self.bot.config.update() embed = discord.Embed( - title=_("Removed alias"), + title="Removed alias", color=self.bot.main_color, - description=_("Successfully deleted `{name}`.").format(name=name), + description=f"Successfully deleted `{name}`.", ) else: embed = utils.create_not_found_embed(name, self.bot.aliases.keys(), "Alias") @@ -1264,11 +1206,9 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name level = self._parse_level(level_name) if level is PermissionLevel.INVALID: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("The referenced level does not exist: `{level}`.").format( - level=level_name - ), + description=f"The referenced level does not exist: `{level_name}`.", ) else: logger.info( @@ -1280,11 +1220,10 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name await self.bot.config.update() embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_( - "Successfully set command permission level for " "`{command}` to `{level}`." - ).format(command=command.qualified_name, level=level.name), + description="Successfully set command permission level for " + f"`{command.qualified_name}` to `{level.name}`.", ) return await ctx.send(embed=embed) @@ -1327,11 +1266,9 @@ async def permissions_add( if not check: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("The referenced {type} does not exist: `{name}`.").format( - type=type_, name=name - ), + description=f"The referenced {type_} does not exist: `{name}`.", ) return await ctx.send(embed=embed) @@ -1354,9 +1291,9 @@ async def permissions_add( await self.bot.main_category.set_permissions(key, read_messages=True) embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_("Permission for `{name}` was successfully updated.").format(name=name), + description=f"Permission for `{name}` was successfully updated.", ) return await ctx.send(embed=embed) @@ -1405,12 +1342,10 @@ async def permissions_remove( if level is None: perm = self.bot.command_perm(name) embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_( - "The command permission level was never overridden: `{name}`, " - "current permission level is {perm_name}." - ).format(name=name, perm_name=perm.name), + description=f"The command permission level was never overridden: `{name}`, " + f"current permission level is {perm.name}.", ) else: logger.info("Restored command permission level for `%s`.", name) @@ -1418,11 +1353,9 @@ async def permissions_remove( await self.bot.config.update() perm = self.bot.command_perm(name) embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_( - "Command permission level for `{name}` was successfully restored to {perm_name}." - ).format(name=name, perm_name=perm.name), + description=f"Command permission level for `{name}` was successfully restored to {perm.name}.", ) return await ctx.send(embed=embed) @@ -1434,11 +1367,9 @@ async def permissions_remove( level = self._parse_level(name) if level is PermissionLevel.INVALID: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_("The referenced level does not exist: `{name}`.").format( - name=name - ), + description=f"The referenced level does not exist: `{name}`.", ) return await ctx.send(embed=embed) name = level.name @@ -1463,9 +1394,9 @@ async def permissions_remove( await self.bot.main_category.set_permissions(member, overwrite=None) embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_("Permission for `{name}` was successfully updated.").format(name=name), + description=f"Permission for `{name}` was successfully updated.", ) return await ctx.send(embed=embed) @@ -1476,8 +1407,8 @@ def _get_perm(self, ctx, name, type_): permissions = self.bot.config["level_permissions"].get(name, []) if not permissions: embed = discord.Embed( - title=_("Permission entries for {type} `{name}`:").format(type=type_, name=name), - description=_("No permission entries found."), + title=f"Permission entries for {type_} `{name}`:", + description="No permission entries found.", color=self.bot.main_color, ) else: @@ -1501,7 +1432,7 @@ def _get_perm(self, ctx, name, type_): values.append(str(perm)) embed = discord.Embed( - title=_("Permission entries for {type} `{name}`:").format(type=type_, name=name), + title=f"Permission entries for {type_} `{name}`:", description=", ".join(values), color=self.bot.main_color, ) @@ -1564,26 +1495,22 @@ async def permissions_get( desc_cmd = ( ", ".join(map(lambda x: f"`{x}`", cmds)) if cmds - else _("No permission entries found.") + else "No permission entries found." ) desc_level = ( ", ".join(map(lambda x: f"`{x}`", levels)) if levels - else _("No permission entries found.") + else "No permission entries found." ) embeds = [ discord.Embed( - title=_("{mention} has permission with the following commands:").format( - mention=mention - ), + title=f"{mention} has permission with the following commands:", description=desc_cmd, color=self.bot.main_color, ), discord.Embed( - title=_( - "{mention} has permission with the following permission levels:" - ).format(mention=mention), + title=f"{mention} has permission with the following permission levels:", description=desc_level, color=self.bot.main_color, ), @@ -1608,10 +1535,8 @@ async def permissions_get( if not overrides: embeds.append( discord.Embed( - title=_("Permission Overrides"), - description=_( - "You don't have any command level overrides at the moment." - ), + title="Permission Overrides", + description="You don't have any command level overrides at the moment.", color=self.bot.error_color, ) ) @@ -1625,7 +1550,7 @@ async def permissions_get( color=self.bot.main_color, description=description ) embed.set_author( - name=_("Permission Overrides"), icon_url=ctx.guild.icon_url + name="Permission Overrides", icon_url=ctx.guild.icon_url ) embeds.append(embed) @@ -1638,20 +1563,16 @@ async def permissions_get( perm = self.bot.command_perm(name) if level is None: embed = discord.Embed( - title=_("Error"), + title="Error", color=self.bot.error_color, - description=_( - "The command permission level was never overridden: `{name}`, " - "current permission level is {perm_name}." - ).format(name=name, perm_name=perm.name), + description=f"The command permission level was never overridden: `{name}`, " + f"current permission level is {perm.name}.", ) else: embed = discord.Embed( - title=_("Success"), + title="Success", color=self.bot.main_color, - description=_( - 'Permission override for command "{name}" is "{perm_name}".' - ).format(name=name, perm_name=perm.name), + description=f'Permission override for command "{name}" is "{perm.name}".', ) return await ctx.send(embed=embed) @@ -1727,19 +1648,14 @@ async def oauth_whitelist(self, ctx, target: Union[discord.Role, utils.User]): await self.bot.config.update() embed = discord.Embed(color=self.bot.main_color) - embed.title = _("Success") + embed.title = "Success" if not hasattr(target, "mention"): target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role(target.id) - if removed: - embed.description = _("Un-whitelisted {target_mention} to view logs.").format( - target_mention=target.mention - ) - else: - embed.description = _("Whitelisted {target_mention} to view logs.").format( - target_mention=target.mention - ) + embed.description = ( + f"{'Un-w' if removed else 'W'}hitelisted {target.mention} to view logs." + ) await ctx.send(embed=embed) @@ -1761,9 +1677,9 @@ async def oauth_show(self, ctx): roles.append(role) embed = discord.Embed(color=self.bot.main_color) - embed.title = _("Oauth Whitelist") + embed.title = "Oauth Whitelist" - embed.add_field(name=_("Users"), value=" ".join(u.mention for u in users) or _("None")) + embed.add_field(name="Users", value=" ".join(u.mention for u in users) or "None") embed.add_field(name="Roles", value=" ".join(r.mention for r in roles) or "None") await ctx.send(embed=embed) diff --git a/core/clients.py b/core/clients.py index 54cc28c9be..03921d5a17 100644 --- a/core/clients.py +++ b/core/clients.py @@ -1,18 +1,21 @@ import secrets +import sys from datetime import datetime from json import JSONDecodeError -from typing import Union +from typing import Union, Optional from discord import Member, DMChannel, TextChannel, Message from aiohttp import ClientResponseError, ClientResponse +from motor.motor_asyncio import AsyncIOMotorClient +from pymongo.errors import ConfigurationError from core.models import getLogger logger = getLogger(__name__) -class RequestClient: +class ApiClient: """ This class represents the general request class for all type of clients. @@ -29,8 +32,9 @@ class RequestClient: The bot's current running `ClientSession`. """ - def __init__(self, bot): + def __init__(self, bot, db): self.bot = bot + self.db = db self.session = bot.session async def request( @@ -74,16 +78,152 @@ async def request( except (JSONDecodeError, ClientResponseError): return await resp.text() - -class ApiClient(RequestClient): - @property - def db(self): - return self.bot.db - @property def logs(self): return self.db.logs + async def setup_indexes(self): + return NotImplemented + + async def validate_database_connection(self): + return NotImplemented + + async def get_user_logs(self, user_id: Union[str, int]) -> list: + return NotImplemented + + async def get_latest_user_logs(self, user_id: Union[str, int]): + return NotImplemented + + async def get_responded_logs(self, user_id: Union[str, int]) -> list: + return NotImplemented + + async def get_open_logs(self) -> list: + return NotImplemented + + async def get_log(self, channel_id: Union[str, int]) -> dict: + return NotImplemented + + async def get_log_link(self, channel_id: Union[str, int]) -> str: + return NotImplemented + + async def create_log_entry( + self, recipient: Member, channel: TextChannel, creator: Member + ) -> str: + return NotImplemented + + async def delete_log_entry(self, key: str) -> bool: + return NotImplemented + + async def get_config(self) -> dict: + return NotImplemented + + async def update_config(self, data: dict): + return NotImplemented + + async def edit_message(self, message_id: Union[int, str], new_content: str) -> None: + return NotImplemented + + async def append_log( + self, + message: Message, + *, + message_id: str = "", + channel_id: str = "", + type_: str = "thread_message", + ) -> dict: + return NotImplemented + + async def post_log(self, channel_id: Union[int, str], data: dict) -> dict: + return NotImplemented + + async def search_closed_by(self, user_id: Union[int, str]): + return NotImplemented + + async def search_by_text(self, text: str, limit: Optional[int]): + return NotImplemented + + def get_plugin_partition(self, cog): + return NotImplemented + + +class MongoDBClient(ApiClient): + def __init__(self, bot): + mongo_uri = bot.config["connection_uri"] + if mongo_uri is None: + mongo_uri = bot.config["mongo_uri"] + if mongo_uri is not None: + logger.warning( + "You're using the old config MONGO_URI, " + "consider switching to the new CONNECTION_URI config." + ) + else: + logger.critical("A Mongo URI is necessary for the bot to function.") + raise RuntimeError + + try: + db = AsyncIOMotorClient(mongo_uri).modmail_bot + except ConfigurationError as e: + logger.critical( + "Your MongoDB CONNECTION_URI might be copied wrong, try re-copying from the source again. " + "Otherwise noted in the following message:" + ) + logger.critical(e) + sys.exit(0) + + super().__init__(bot, db) + + async def setup_indexes(self): + """Setup text indexes so we can use the $search operator""" + coll = self.db.logs + index_name = "messages.content_text_messages.author.name_text_key_text" + + index_info = await coll.index_information() + + # Backwards compatibility + old_index = "messages.content_text_messages.author.name_text" + if old_index in index_info: + logger.info("Dropping old index: %s", old_index) + await coll.drop_index(old_index) + + if index_name not in index_info: + logger.info('Creating "text" index for logs collection.') + logger.info("Name: %s", index_name) + await coll.create_index( + [("messages.content", "text"), ("messages.author.name", "text"), ("key", "text")] + ) + logger.debug("Successfully configured and verified database indexes.") + + async def validate_database_connection(self): + try: + await self.db.command("buildinfo") + except Exception as exc: + logger.critical("Something went wrong while connecting to the database.") + message = f"{type(exc).__name__}: {str(exc)}" + logger.critical(message) + + if "ServerSelectionTimeoutError" in message: + logger.critical( + "This may have been caused by not whitelisting " + "IPs correctly. Make sure to whitelist all " + "IPs (0.0.0.0/0) https://i.imgur.com/mILuQ5U.png" + ) + + if "OperationFailure" in message: + logger.critical( + "This is due to having invalid credentials in your MongoDB CONNECTION_URI. " + "Remember you need to substitute `` with your actual password." + ) + logger.critical( + "Be sure to URL encode your username and password (not the entire URL!!), " + "https://www.urlencoder.io/, if this issue persists, try changing your username and password " + "to only include alphanumeric characters, no symbols." + "" + ) + raise + else: + logger.debug("Successfully connected to the database.") + logger.line("debug") + async def get_user_logs(self, user_id: Union[str, int]) -> list: query = {"recipient.id": str(user_id), "guild_id": str(self.bot.guild_id)} projection = {"messages": {"$slice": 5}} @@ -245,6 +385,26 @@ async def post_log(self, channel_id: Union[int, str], data: dict) -> dict: {"channel_id": str(channel_id)}, {"$set": data}, return_document=True ) + async def search_closed_by(self, user_id: Union[int, str]): + return await self.logs.find( + {"guild_id": str(self.bot.guild_id), "open": False, "closer.id": str(user_id)}, + {"messages": {"$slice": 5}}, + ).to_list(None) + + async def search_by_text(self, text: str, limit: Optional[int]): + return await self.bot.db.logs.find( + { + "guild_id": str(self.bot.guild_id), + "open": False, + "$text": {"$search": f'"{text}"'}, + }, + {"messages": {"$slice": 5}}, + ).to_list(limit) + + def get_plugin_partition(self, cog): + cls_name = cog.__class__.__name__ + return self.db.plugins[cls_name] + class PluginDatabaseClient: def __init__(self, bot): @@ -252,4 +412,4 @@ def __init__(self, bot): def get_partition(self, cog): cls_name = cog.__class__.__name__ - return self.bot.db.plugins[cls_name] + return self.bot.api.db.plugins[cls_name] diff --git a/core/config.py b/core/config.py index a0eda4a2dc..f2bb54a5c8 100644 --- a/core/config.py +++ b/core/config.py @@ -57,6 +57,7 @@ class ConfigManager: "thread_close_title": "Thread Closed", "thread_close_response": "{closer.mention} has closed this Modmail thread.", "thread_self_close_response": "You have closed this Modmail thread.", + "thread_move_title": "Thread Moved", "thread_move_notify": False, "thread_move_response": "This thread has been moved.", "disabled_new_thread_title": "Not Delivered", @@ -81,7 +82,7 @@ class ConfigManager: "activity_type": None, "status": None, # dm_disabled 0 = none, 1 = new threads, 2 = all threads - # TODO: use emum + # TODO: use enum "dm_disabled": 0, "oauth_whitelist": [], # moderation @@ -107,12 +108,17 @@ class ConfigManager: "log_url": "https://example.com/", "log_url_prefix": "/logs", "mongo_uri": None, + "database_type": "mongodb", + "connection_uri": None, # replace mongo uri in the future "owners": None, # bot "token": None, + "enable_plugins": True, + "enable_eval": True, + # github access token for private repositories + "github_token": None, # Logging "log_level": "INFO", - "enable_plugins": True, } colors = {"mod_color", "recipient_color", "main_color", "error_color"} @@ -128,6 +134,7 @@ class ConfigManager: "thread_auto_close_silently", "thread_move_notify", "enable_plugins", + "enable_eval", } special_types = {"status", "activity_type"} diff --git a/core/config_help.json b/core/config_help.json index db9218d2b3..9778f49f8c 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -350,6 +350,16 @@ "See also: `thread_close_title`, `thread_close_footer`, `thread_close_response`." ] }, + "thread_move_title": { + "default": "Thread Moved", + "description": "The title of the message embed when a thread is moved.", + "examples": [ + "`{prefix}config set thread_move_title Thread transferred to another channel!" + ], + "notes": [ + "See also: `thread_move_notify`, `thread_move_response`." + ] + }, "thread_move_notify": { "default": "No", "description": "Notify the recipient if the thread was moved.", @@ -358,7 +368,7 @@ "`{prefix}config set thread_move_notify no`" ], "notes": [ - "See also: `thread_move_response`." + "See also: `thread_move_title`, `thread_move_response`." ] }, "thread_move_response": { @@ -369,7 +379,7 @@ ], "notes": [ "Only has an effect when `thread_move_notify` is on.", - "See also: `thread_move_notify`." + "See also: `thread_move_title`, `thread_move_notify`." ] }, "disabled_new_thread_title": { diff --git a/core/paginator.py b/core/paginator.py index 45c059f844..7ba1c98b60 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -176,7 +176,7 @@ async def close(self, delete: bool = True) -> typing.Optional[Message]: """ self.running = False - sent_emoji, x = await self.ctx.bot.retrieve_emoji() + sent_emoji, _ = await self.ctx.bot.retrieve_emoji() await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) if delete: diff --git a/core/thread.py b/core/thread.py index 0926a0acd0..9c388389e0 100644 --- a/core/thread.py +++ b/core/thread.py @@ -72,15 +72,13 @@ def ready(self) -> bool: def ready(self, flag: bool): if flag: self._ready_event.set() - self.bot.dispatch("thread_ready", self) + self.bot.dispatch("thread_create", self) else: self._ready_event.clear() async def setup(self, *, creator=None, category=None): """Create the thread channel and other io related initialisation tasks""" - - self.bot.dispatch("thread_create", self) - + self.bot.dispatch("thread_initiate", self) recipient = self.recipient # in case it creates a channel outside of category @@ -175,6 +173,7 @@ async def send_recipient_genesis_message(): await self.bot.add_reaction(msg, close_emoji) await asyncio.gather(send_genesis_message(), send_recipient_genesis_message()) + self.bot.dispatch("thread_ready", self) def _format_info_embed(self, user, log_url, log_count, color): """Get information about a member of a server @@ -317,6 +316,7 @@ async def _close( { "open": False, "closed_at": str(datetime.utcnow()), + "nsfw": self.channel.nsfw, "close_message": message if not silent else None, "closer": { "id": str(closer.id), @@ -340,7 +340,12 @@ async def _close( else: sneak_peak = "No content" - desc = f"[`{log_data['key']}`]({log_url}): " + if self.channel.nsfw: + _nsfw = "NSFW-" + else: + _nsfw = "" + + desc = f"[`{_nsfw}{log_data['key']}`]({log_url}): " desc += truncate(sneak_peak, max=75 - 13) else: desc = "Could not resolve log url." @@ -362,7 +367,7 @@ async def _close( event = "Thread Closed as Scheduled" if scheduled else "Thread Closed" # embed.set_author(name=f"Event: {event}", url=log_url) - embed.set_footer(text=f"{event} by {_closer}") + embed.set_footer(text=f"{event} by {_closer}", icon_url=closer.avatar_url) embed.timestamp = datetime.utcnow() tasks = [self.bot.config.update()] @@ -457,9 +462,14 @@ async def find_linked_messages( message_id: typing.Optional[int] = None, either_direction: bool = False, message1: discord.Message = None, + note: bool = True, ) -> typing.Tuple[discord.Message, typing.Optional[discord.Message]]: if message1 is not None: - if not message1.embeds or not message1.embeds[0].author.url: + if ( + not message1.embeds + or not message1.embeds[0].author.url + or message1.author != self.bot.user + ): raise ValueError("Malformed thread message.") elif message_id is not None: @@ -469,13 +479,18 @@ async def find_linked_messages( raise ValueError("Thread message not found.") if not ( - message1.embeds and message1.embeds[0].author.url and message1.embeds[0].color + message1.embeds + and message1.embeds[0].author.url + and message1.embeds[0].color + and message1.author == self.bot.user ): raise ValueError("Thread message not found.") if message1.embeds[0].color.value == self.bot.main_color and message1.embeds[ 0 ].author.name.startswith("Note"): + if not note: + raise ValueError("Thread message not found.") return message1, None if message1.embeds[0].color.value != self.bot.mod_color and not ( @@ -495,6 +510,8 @@ async def find_linked_messages( and message1.embeds[0].color.value == self.bot.recipient_color ) ) + and message1.embeds[0].author.url.split("#")[-1].isdigit() + and message1.author == self.bot.user ): break else: @@ -516,7 +533,7 @@ async def find_linked_messages( if int(msg.embeds[0].author.url.split("#")[-1]) == joint_id: return message1, msg except ValueError: - raise ValueError("DM message not found.") + continue raise ValueError("DM message not found.") async def edit_message(self, message_id: typing.Optional[int], message: str) -> None: @@ -537,16 +554,13 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> await asyncio.gather(*tasks) - async def delete_message(self, message: typing.Union[int, discord.Message] = None) -> None: - try: - if isinstance(message, discord.Message): - message1, message2 = await self.find_linked_messages(message1=message) - else: - message1, message2 = await self.find_linked_messages(message) - except ValueError as e: - logger.warning("Failed to delete message: %s.", e) - raise - + async def delete_message( + self, message: typing.Union[int, discord.Message] = None, note: bool = True + ) -> None: + if isinstance(message, discord.Message): + message1, message2 = await self.find_linked_messages(message1=message, note=note) + else: + message1, message2 = await self.find_linked_messages(message, note=note) tasks = [] if not isinstance(message, discord.Message): tasks += [message1.delete()] @@ -571,12 +585,12 @@ async def find_linked_message_from_dm(self, message, either_direction=False): return linked_message msg_id = url.split("#")[-1] - try: - if int(msg_id) == message.id: - return linked_message - except ValueError: - raise ValueError("Malformed dm channel message.") - raise ValueError("DM channel message not found.") + if not msg_id.isdigit(): + continue + msg_id = int(msg_id) + if int(msg_id) == message.id: + return linked_message + raise ValueError("Thread channel message not found.") async def edit_dm_message(self, message: discord.Message, content: str) -> None: try: diff --git a/core/time.py b/core/time.py index cc30d84f30..331e26349f 100644 --- a/core/time.py +++ b/core/time.py @@ -134,7 +134,7 @@ def convert(self, ctx, argument): # foo date time # first the first two cases: - dt, status, begin, end, x = elements[0] + dt, status, begin, end, _ = elements[0] if not status.hasDateOrTime: return self.check_constraints(self.now, argument) diff --git a/core/translations.py b/core/translations.py deleted file mode 100644 index 98a3327386..0000000000 --- a/core/translations.py +++ /dev/null @@ -1,25 +0,0 @@ -import builtins -import csv -import os - - -class Translator: - def __init__(self): - self.language = os.getenv("language", "en") - self.texts = {} - self.generate_texts() - - def generate_texts(self): - with open(f"languages/{self.language}.csv", encoding="utf8") as f: - reader = csv.reader(f, dialect="unix") - - for n, row in enumerate(reader): - if n != 0: - self.texts[row[0]] = row[1] - - def translate(self, identifier): - return self.texts.get(identifier, identifier) - - -def init(): - builtins._ = Translator().translate diff --git a/languages/en.csv b/languages/en.csv deleted file mode 100644 index 388091bab5..0000000000 --- a/languages/en.csv +++ /dev/null @@ -1,1172 +0,0 @@ -"Identifier","English","Context" -"You can only setup in the Modmail guild: {guild_name}.","You can only setup in the Modmail guild: {guild_name}.","File: cogs\modmail.py/L44" -"{guild_name} is already set up.","{guild_name} is already set up.","File: cogs\modmail.py/L49" -"Error","Error","File: cogs\modmail.py/L53/L217/L225/L233/L712/L1059/L1151 cogs\utility.py/L168/L748/L774/L802/L822/L892/L979/L1045/L1085/L1092/L1099/L1125/L1245/L1316/L1378/L1559" -"Modmail functioning guild not found.","Modmail functioning guild not found.","File: cogs\modmail.py/L54" -"Friendly Reminder","Friendly Reminder","File: cogs\modmail.py/L91" -"You may use the `{prefix}config set log_channel_id ` command to set up a custom log channel, then you can delete this default {log_channel} log channel.","You may use the `{prefix}config set log_channel_id ` command to set up a custom log channel, then you can delete this default {log_channel} log channel.","File: cogs\modmail.py/L92" -"Thanks for using the bot!","Thanks for using the bot!","File: cogs\modmail.py/L99" -"If you like what you see, consider giving the [repo a star](https://github.com/kyb3r/modmail) :star: or if you are feeling generous, check us out on [Patreon](https://patreon.com/kyber)!","If you like what you see, consider giving the [repo a star](https://github.com/kyb3r/modmail) :star: or if you are feeling generous, check us out on [Patreon](https://patreon.com/kyber)!","File: cogs\modmail.py/L100" -"Type ""{prefix}help"" for a complete list of commands.","Type ""{prefix}help"" for a complete list of commands.","File: cogs\modmail.py/L106" -"**Successfully set up server.**\nConsider setting permission levels to give access to roles or users the ability to use Modmail.\n\nType:\n- `{prefix}permissions` and `{prefix}permissions add` for more info on setting permissions.\n- `{prefix}config help` for a list of available customizations.","**Successfully set up server.**\nConsider setting permission levels to give access to roles or users the ability to use Modmail.\n\nType:\n- `{prefix}permissions` and `{prefix}permissions add` for more info on setting permissions.\n- `{prefix}config help` for a list of available customizations.","File: cogs\modmail.py/L115" -"Snippets","Snippets","File: cogs\modmail.py/L175" -"Snippet `{name}` already exists.","Snippet `{name}` already exists.","File: cogs\modmail.py/L219" -"An alias with the same name already exists: `{name}`.","An alias with the same name already exists: `{name}`.","File: cogs\modmail.py/L227" -"Snippet names cannot be longer than 120 characters.","Snippet names cannot be longer than 120 characters.","File: cogs\modmail.py/L235" -"Removed snippet","Removed snippet","File: cogs\modmail.py/L256" -"Snippet `{name}` is now deleted.","Snippet `{name}` is now deleted.","File: cogs\modmail.py/L258" -"Edited snippet","Edited snippet","File: cogs\modmail.py/L281" -"Thread Moved","Thread Moved","File: cogs\modmail.py/L310" -"Scheduled close","Scheduled close","File: cogs\modmail.py/L325" -"This thread will close {silent}in {time}.","This thread will close {silent}in {time}.","File: cogs\modmail.py/L326" -"Message","Message","File: cogs\modmail.py/L331" -"Closing will be cancelled if a thread message is sent.","Closing will be cancelled if a thread message is sent.","File: cogs\modmail.py/L334" -"silent","silent","File: cogs\modmail.py/L369" -"silently","silently","File: cogs\modmail.py/L369" -"cancel","cancel","File: cogs\modmail.py/L370" -"Scheduled close has been cancelled.","Scheduled close has been cancelled.","File: cogs\modmail.py/L378" -"This thread has not already been scheduled to close.","This thread has not already been scheduled to close.","File: cogs\modmail.py/L383" -"{mention} is already going to be mentioned.","{mention} is already going to be mentioned.","File: cogs\modmail.py/L433" -"{mention} will be mentioned on the next message received.","{mention} will be mentioned on the next message received.","File: cogs\modmail.py/L440" -"{mention} does not have a pending notification.","{mention} does not have a pending notification.","File: cogs\modmail.py/L472" -"{mention} will no longer be notified.","{mention} will no longer be notified.","File: cogs\modmail.py/L479" -"{mention} is already subscribed to this thread.","{mention} is already subscribed to this thread.","File: cogs\modmail.py/L512" -"{mention} will now be notified of all messages received.","{mention} will now be notified of all messages received.","File: cogs\modmail.py/L519" -"{mention} is not already subscribed to this thread.","{mention} is not already subscribed to this thread.","File: cogs\modmail.py/L551" -"{mention} is now unsubscribed to this thread.","{mention} is now unsubscribed to this thread.","File: cogs\modmail.py/L558" -"Unknown","Unknown","File: cogs\modmail.py/L610" -"Closed By","Closed By","File: cogs\modmail.py/L613" -"Created by","Created by","File: cogs\modmail.py/L616" -"Preview","Preview","File: cogs\modmail.py/L619" -"Link","Link","File: cogs\modmail.py/L624" -"Log Key","Log Key","File: cogs\modmail.py/L627" -"Recipient ID","Recipient ID","File: cogs\modmail.py/L629" -"This user does not have any previous logs.","This user does not have any previous logs.","File: cogs\modmail.py/L660" -"No log entries have been found for that query","No log entries have been found for that query","File: cogs\modmail.py/L693" -"Log entry `{key}` not found.","Log entry `{key}` not found.","File: cogs\modmail.py/L713" -"Log entry `{key}` successfully deleted.","Log entry `{key}` successfully deleted.","File: cogs\modmail.py/L719" -"{mention} has not responded to any threads.","{mention} has not responded to any threads.","File: cogs\modmail.py/L743" -"No log entries have been found for that query.","No log entries have been found for that query.","File: cogs\modmail.py/L776" -"Failed","Failed","File: cogs\modmail.py/L869/L1177" -"Cannot find a message to edit.","Cannot find a message to edit.","File: cogs\modmail.py/L870" -"Cannot start a thread with a bot.","Cannot start a thread with a bot.","File: cogs\modmail.py/L900" -"A thread for this user already exists in {mention}.","A thread for this user already exists in {mention}.","File: cogs\modmail.py/L908" -"Created Thread","Created Thread","File: cogs\modmail.py/L919" -"Thread started by {author_mention} for {user_mention}.","Thread started by {author_mention} for {user_mention}.","File: cogs\modmail.py/L920" -"Blocked Users","Blocked Users","File: cogs\modmail.py/L939/L960" -"No Reason Provided","No Reason Provided","File: cogs\modmail.py/L960" -"(Continued)","(Continued)","File: cogs\modmail.py/L963 cogs\utility.py/L67" -"Currently there are no blocked users.","Currently there are no blocked users.","File: cogs\modmail.py/L971" -"Success","Success","File: cogs\modmail.py/L997/L1084/L1091/L1308/L1344/L1357/L1377/L1358 cogs\utility.py/L725/L759/L1231/L1291/L1367/L1392/L1559/L1595" -"{mention} is no longer whitelisted.","{mention} is no longer whitelisted.","File: cogs\modmail.py/L998" -"{mention} was previously blocked internally for ","{mention} was previously blocked internally for ","File: cogs\modmail.py/L1018" -"Cannot block {mention}, user is whitelisted.","Cannot block {mention}, user is whitelisted.","File: cogs\modmail.py/L1060" -"{mention} was previously blocked {old_reason}.\n{mention} is now blocked {reason}","{mention} was previously blocked {old_reason}.\n{mention} is now blocked {reason}","File: cogs\modmail.py/L1085" -"{mention} is now blocked {reason}","{mention} is now blocked {reason}","File: cogs\modmail.py/L1093" -"{mention} was previously blocked internally {reason}.\n{mention} is no longer blocked.","{mention} was previously blocked internally {reason}.\n{mention} is no longer blocked.","File: cogs\modmail.py/L1132" -"However, if the original system block reason still applies, {name} will be automatically blocked again. Use ","However, if the original system block reason still applies, {name} will be automatically blocked again. Use ","File: cogs\modmail.py/L1137" -"{mention} is no longer blocked.","{mention} is no longer blocked.","File: cogs\modmail.py/L1147" -"{mention} is not blocked.","{mention} is not blocked.","File: cogs\modmail.py/L1152" -"Cannot find a message to delete.","Cannot find a message to delete.","File: cogs\modmail.py/L1178" -"Modmail will now accept **all** DM messages.","Modmail will now accept **all** DM messages.","File: cogs\modmail.py/L1309" -"Modmail is already accepting all DM messages.","Modmail is already accepting all DM messages.","File: cogs\modmail.py/L1316" -"Modmail will not create any **new** threads.","Modmail will not create any **new** threads.","File: cogs\modmail.py/L1345" -"Modmail is already not creating any new threads.","Modmail is already not creating any new threads.","File: cogs\modmail.py/L1352" -"Modmail will not create **new** threads, but existing threads will now be functioning.","Modmail will not create **new** threads, but existing threads will now be functioning.","File: cogs\modmail.py/L1358" -"Modmail will not accept **any** DM messages.","Modmail will not accept **any** DM messages.","File: cogs\modmail.py/L1378" -"Modmail is already not accepting any DM messages.","Modmail is already not accepting any DM messages.","File: cogs\modmail.py/L1385" -"New Threads Disabled","New Threads Disabled","File: cogs\modmail.py/L1400" -"Modmail is not creating new threads.","Modmail is not creating new threads.","File: cogs\modmail.py/L1401" -"All DM Disabled","All DM Disabled","File: cogs\modmail.py/L1406" -"Modmail is not accepting any DM messages for new and existing threads.","Modmail is not accepting any DM messages for new and existing threads.","File: cogs\modmail.py/L1407" -"Enabled","Enabled","File: cogs\modmail.py/L1412" -"Modmail is accepting all DM messages.","Modmail is accepting all DM messages.","File: cogs\modmail.py/L1413" -"Plugins are still loading, please try again later.","Plugins are still loading, please try again later.","File: cogs\plugins.py/L230/L470" -"Your bot's version is too low. This plugin requires version `{required_version}`.","Your bot's version is too low. This plugin requires version `{required_version}`.","File: cogs\plugins.py/L246" -"Invalid plugin name, double check the plugin name or use one of the following formats: username/repo/plugin, username/repo/plugin@branch.","Invalid plugin name, double check the plugin name or use one of the following formats: username/repo/plugin, username/repo/plugin@branch.","File: cogs\plugins.py/L260" -"This plugin is already installed.","This plugin is already installed.","File: cogs\plugins.py/L295" -"Cannot install this plugin (dupe cog name).","Cannot install this plugin (dupe cog name).","File: cogs\plugins.py/L303" -"Starting to download plugin from {plugin_link}...","Starting to download plugin from {plugin_link}...","File: cogs\plugins.py/L309" -"Failed to download plugin, check logs for error.","Failed to download plugin, check logs for error.","File: cogs\plugins.py/L320" -"Successfully installed plugin.\n*Friendly reminder, plugins have absolute control over your bot. Please only install plugins from developers you trust.*","Successfully installed plugin.\n*Friendly reminder, plugins have absolute control over your bot. Please only install plugins from developers you trust.*","File: cogs\plugins.py/L345" -"This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot.","This plugin is currently not enabled due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or change `ENABLE_PLUGINS=true` and restart your bot.","File: cogs\plugins.py/L355" -"Plugin is not installed.","Plugin is not installed.","File: cogs\plugins.py/L376/L415" -"The plugin is successfully uninstalled.","The plugin is successfully uninstalled.","File: cogs\plugins.py/L402" -"Successfully updated {plugin_name}.","Successfully updated {plugin_name}.","File: cogs\plugins.py/L429" -"No plugins are loaded due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot.","No plugins are loaded due to `ENABLE_PLUGINS=false`, to re-enable plugins, remove or set `ENABLE_PLUGINS=true` and restart your bot.","File: cogs\plugins.py/L462" -"There are no plugins currently loaded.","There are no plugins currently loaded.","File: cogs\plugins.py/L477" -"Loaded plugins:","Loaded plugins:","File: cogs\plugins.py/L498" -"Could not find a plugin with name ""{plugin_name}"" within the registry.","Could not find a plugin with name ""{plugin_name}"" within the registry.","File: cogs\plugins.py/L534" -"Perhaps you meant:","Perhaps you meant:","File: cogs\plugins.py/L541 cogs\utility.py/L211" -"Installation","Installation","File: cogs\plugins.py/L562" -"Your bot is unable to install this plugin, minimum required version is v{required_version}.","Your bot is unable to install this plugin, minimum required version is v{required_version}.","File: cogs\plugins.py/L582" -"Your bot is able to install this plugin.","Your bot is able to install this plugin.","File: cogs\plugins.py/L586" -"Plugin Registry","Plugin Registry","File: cogs\plugins.py/L641" -" - if not format_.strip(): - continue - if len(format_) + len(formats[-1]) >= 1024: - formats.append(format_) - else: - formats[-1] += format_ - - embeds = [] - for format_ in formats: - description = ( - _(cog.description) or _()"," - if not format_.strip(): - continue - if len(format_) + len(formats[-1]) >= 1024: - formats.append(format_) - else: - formats[-1] += format_ - - embeds = [] - for format_ in formats: - description = ( - _(cog.description) or _()","File: cogs\utility.py/L50" -"Miscellaneous commands without a category.","Miscellaneous commands without a category.","File: cogs\utility.py/L63" -"Commands","Commands","File: cogs\utility.py/L67" -"No commands.","No commands.","File: cogs\utility.py/L67" -"Help","Help","File: cogs\utility.py/L71" -"Miscellaneous Commands","Miscellaneous Commands","File: cogs\utility.py/L73" -"Type ""{prefix}{command} command"" ","Type ""{prefix}{command} command"" ","File: cogs\utility.py/L78/L153" -"NONE","NONE","File: cogs\utility.py/L119" -"","","File: cogs\utility.py/L124" -"Permission Level","Permission Level","File: cogs\utility.py/L139" -" - - embed.add_field(name=_()"," - - embed.add_field(name=_()","File: cogs\utility.py/L153" -"{command} is a snippet.","{command} is a snippet.","File: cogs\utility.py/L168" -"Alias `{command}` is invalid, this alias will now be deleted.This alias will now be deleted.","Alias `{command}` is invalid, this alias will now be deleted.This alias will now be deleted.","File: cogs\utility.py/L181" -"{command} is an alias.","{command} is an alias.","File: cogs\utility.py/L190/L192" -"`{command}` points to:","`{command}` points to:","File: cogs\utility.py/L192" -"**`{command}` points to the following steps:**","**`{command}` points to the following steps:**","File: cogs\utility.py/L197" -"Step","Step","File: cogs\utility.py/L200/L1045" -"Type ""{prefix}{command} alias"" ","Type ""{prefix}{command} alias"" ","File: cogs\utility.py/L203" -"Command/Category ""{command}"" not found.","Command/Category ""{command}"" not found.","File: cogs\utility.py/L211" -"Cannot find command or category","Cannot find command or category","File: cogs\utility.py/L225" -"Type ""{prefix}{command}"" ","Type ""{prefix}{command}"" ","File: cogs\utility.py/L227" -"Shows this help message.","Shows this help message.","File: cogs\utility.py/L242" -"The specified version `{version}` could not be found.","The specified version `{version}` could not be found.","File: cogs\utility.py/L266" -"View the changelog here: {url}","View the changelog here: {url}","File: cogs\utility.py/L282" -"Modmail - About","Modmail - About","File: cogs\utility.py/L292" -"This is an open source Discord bot that serves as a means for members to easily communicate with server administrators in an organised manner.","This is an open source Discord bot that serves as a means for members to easily communicate with server administrators in an organised manner.","File: cogs\utility.py/L298" -"Uptime","Uptime","File: cogs\utility.py/L303" -"Latency","Latency","File: cogs\utility.py/L304" -"Version","Version","File: cogs\utility.py/L305" -"Authors","Authors","File: cogs\utility.py/L306" -"You are on the prerelease version • the latest version is v{version}.","You are on the prerelease version • the latest version is v{version}.","File: cogs\utility.py/L315" -"A newer version is available v{version}.","A newer version is available v{version}.","File: cogs\utility.py/L317" -"You are up to date with the latest version.","You are up to date with the latest version.","File: cogs\utility.py/L319" -"Want Modmail in Your Server?","Want Modmail in Your Server?","File: cogs\utility.py/L322" -"Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) and join our [Discord server](https://discord.gg/F34cRU8/)!","Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) and join our [Discord server](https://discord.gg/F34cRU8/)!","File: cogs\utility.py/L323" -"Support the Developers","Support the Developers","File: cogs\utility.py/L329" -"This bot is completely free for everyone. We rely on kind individuals like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) to keep this bot free forever!","This bot is completely free for everyone. We rely on kind individuals like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) to keep this bot free forever!","File: cogs\utility.py/L330" -"Debug Logs:","Debug Logs:","File: cogs\utility.py/L379" -"You don't have any logs at the moment.","You don't have any logs at the moment.","File: cogs\utility.py/L380" -"Go to Heroku to see your logs.","Go to Heroku to see your logs.","File: cogs\utility.py/L382/L450" -"Debug logs - Navigate using the reactions below.","Debug logs - Navigate using the reactions below.","File: cogs\utility.py/L408" -"Debug Logs","Debug Logs","File: cogs\utility.py/L440" -"Something's wrong. We're unable to upload your logs to hastebin.","Something's wrong. We're unable to upload your logs to hastebin.","File: cogs\utility.py/L448" -"Cached logs are now cleared.","Cached logs are now cleared.","File: cogs\utility.py/L470" -"Activity Removed","Activity Removed","File: cogs\utility.py/L501" -"Activity set to: {name} ","Activity set to: {name} ","File: cogs\utility.py/L520" -"to {name}.","to {name}.","File: cogs\utility.py/L522" -"Activity Changed","Activity Changed","File: cogs\utility.py/L527" -"Status Removed","Status Removed","File: cogs\utility.py/L550" -"Status set to: {value}.","Status set to: {value}.","File: cogs\utility.py/L564" -"Status Changed","Status Changed","File: cogs\utility.py/L566" -"Pong! Websocket Latency:","Pong! Websocket Latency:","File: cogs\utility.py/L638" -"Current mention:","Current mention:","File: cogs\utility.py/L657" -"Changed mention!","Changed mention!","File: cogs\utility.py/L663" -"On thread creation the bot now says ""{mention}"".","On thread creation the bot now says ""{mention}"".","File: cogs\utility.py/L664" -"Current prefix","Current prefix","File: cogs\utility.py/L683" -"Changed prefix!","Changed prefix!","File: cogs\utility.py/L689" -"Set prefix to `{prefix}`","Set prefix to `{prefix}`","File: cogs\utility.py/L690" -"Available configuration keys:","Available configuration keys:","File: cogs\utility.py/L725" -"Set `{key}` to `{value}`.","Set `{key}` to `{value}`.","File: cogs\utility.py/L748" -"{key} is an invalid key.","{key} is an invalid key.","File: cogs\utility.py/L756/L780" -"Valid keys","Valid keys","File: cogs\utility.py/L759/L783" -"`{key}` had been reset to default.","`{key}` had been reset to default.","File: cogs\utility.py/L774" -"`{key}` is set to `{value}`","`{key}` is set to `{value}`","File: cogs\utility.py/L799" -"Config variable","Config variable","File: cogs\utility.py/L802" -"`{key}` is an invalid key.","`{key}` is an invalid key.","File: cogs\utility.py/L809/L822" -"Type ""{prefix}config options"" for a list of config variables.","Type ""{prefix}config options"" for a list of config variables.","File: cogs\utility.py/L812" -"Here is a list of currently set configuration variable(s).","Here is a list of currently set configuration variable(s).","File: cogs\utility.py/L818" -"Current config(s):","Current config(s):","File: cogs\utility.py/L822" -"No help details found for `{key}`.","No help details found for `{key}`.","File: cogs\utility.py/L862" -"Configuration description on {current_key}:","Configuration description on {current_key}:","File: cogs\utility.py/L875" -"Information:","Information:","File: cogs\utility.py/L880" -"Example(s):","Example(s):","File: cogs\utility.py/L886" -"Note(s):","Note(s):","File: cogs\utility.py/L892" -"Alias `{name}` is invalid, it used to be `{value}`. This alias will now be deleted.","Alias `{name}` is invalid, it used to be `{value}`. This alias will now be deleted.","File: cogs\utility.py/L939" -"Alias","Alias","File: cogs\utility.py/L949" -"You dont have any aliases at the moment.","You dont have any aliases at the moment.","File: cogs\utility.py/L968" -"Do {prefix}help alias for more commands.","Do {prefix}help alias for more commands.","File: cogs\utility.py/L970" -"Aliases","Aliases","File: cogs\utility.py/L971" -"Command Aliases","Command Aliases","File: cogs\utility.py/L979" -"Invalid multi-step alias, try wrapping each steps in quotes.","Invalid multi-step alias, try wrapping each steps in quotes.","File: cogs\utility.py/L1009" -"{action} alias","{action} alias","File: cogs\utility.py/L1024" -"`{name}` points to:","`{name}` points to:","File: cogs\utility.py/L1027" -"`{name}` now points to the following steps:","`{name}` now points to the following steps:","File: cogs\utility.py/L1029" -"The command you are attempting to point to does not exist: `{command}`.","The command you are attempting to point to does not exist: `{command}`.","File: cogs\utility.py/L1045" -"The command you are attempting to point to on step {number} does not exist: `{command}`.","The command you are attempting to point to on step {number} does not exist: `{command}`.","File: cogs\utility.py/L1045" -"A command with the same name already exists: `{name}`.","A command with the same name already exists: `{name}`.","File: cogs\utility.py/L1085" -"Another alias with the same name already exists: `{name}`.","Another alias with the same name already exists: `{name}`.","File: cogs\utility.py/L1092" -"A snippet with the same name already exists: `{name}`.","A snippet with the same name already exists: `{name}`.","File: cogs\utility.py/L1099" -"Alias names cannot be longer than 120 characters.","Alias names cannot be longer than 120 characters.","File: cogs\utility.py/L1106" -"Removed alias","Removed alias","File: cogs\utility.py/L1123" -"Successfully deleted `{name}`.","Successfully deleted `{name}`.","File: cogs\utility.py/L1125" -"The referenced level does not exist: `{level}`.","The referenced level does not exist: `{level}`.","File: cogs\utility.py/L1231" -"Successfully set command permission level for `{command}` to `{level}`.","Successfully set command permission level for `{command}` to `{level}`.","File: cogs\utility.py/L1245" -"The referenced {type} does not exist: `{name}`.","The referenced {type} does not exist: `{name}`.","File: cogs\utility.py/L1291" -"Permission for `{name}` was successfully updated.","Permission for `{name}` was successfully updated.","File: cogs\utility.py/L1316/L1419" -"The command permission level was never overridden: `{name}`, current permission level is {perm_name}.","The command permission level was never overridden: `{name}`, current permission level is {perm_name}.","File: cogs\utility.py/L1367/L1559" -"Command permission level for `{name}` was successfully restored to {perm_name}.","Command permission level for `{name}` was successfully restored to {perm_name}.","File: cogs\utility.py/L1378" -"The referenced level does not exist: `{name}`.","The referenced level does not exist: `{name}`.","File: cogs\utility.py/L1392" -"Permission entries for {type} `{name}`:","Permission entries for {type} `{name}`:","File: cogs\utility.py/L1430/L1455" -"No permission entries found.","No permission entries found.","File: cogs\utility.py/L1431/L1523" -"{mention} has permission with the following commands:","{mention} has permission with the following commands:","File: cogs\utility.py/L1528" -"{mention} has permission with the following permission levels:","{mention} has permission with the following permission levels:","File: cogs\utility.py/L1533" -"Permission Overrides","Permission Overrides","File: cogs\utility.py/L1558/L1559" -"You don't have any command level overrides at the moment.","You don't have any command level overrides at the moment.","File: cogs\utility.py/L1559" -"Permission override for command ""{name}"" is ""{perm_name}"".","Permission override for command ""{name}"" is ""{perm_name}"".","File: cogs\utility.py/L1595" -"Un-whitelisted {target_mention} to view logs.","Un-whitelisted {target_mention} to view logs.","File: cogs\utility.py/L1678" -"Whitelisted {target_mention} to view logs.","Whitelisted {target_mention} to view logs.","File: cogs\utility.py/L1682" -"Oauth Whitelist","Oauth Whitelist","File: cogs\utility.py/L1705" -"Users","Users","File: cogs\utility.py/L1708" -"None","None","File: cogs\utility.py/L1708" -"Channel has been deleted, no closer found.","Channel has been deleted, no closer found.","File: bot.py/L472" -"System Message: New Account. Required to wait for {time}.","System Message: New Account. Required to wait for {time}.","File: bot.py/L552" -"Commands directly related to Modmail functionality.","Commands directly related to Modmail functionality.","Cog: Modmail" -"Sets up a server for Modmail.","Sets up a server for Modmail.","Cog: Modmail -Command: setup" -"Sets up a server for Modmail. - -You only need to run this command -once after configuring Modmail.","Sets up a server for Modmail. - -You only need to run this command -once after configuring Modmail.","Cog: Modmail -Command: setup" -"Create pre-defined messages for use in threads.","Create pre-defined messages for use in threads.","Cog: Modmail -Command: snippet" -"Create pre-defined messages for use in threads. - -When `{prefix}snippet` is used by itself, this will retrieve -a list of snippets that are currently set. `{prefix}snippet-name` will show what the -snippet point to. - -To create a snippet: -- `{prefix}snippet add snippet-name A pre-defined text.` - -You can use your snippet in a thread channel -with `{prefix}snippet-name`, the message ""A pre-defined text."" -will be sent to the recipient. - -Currently, there is not a built-in anonymous snippet command; however, a workaround -is available using `{prefix}alias`. Here is how: -- `{prefix}alias add snippet-name anonreply A pre-defined anonymous text.` - -See also `{prefix}alias`.","Create pre-defined messages for use in threads. - -When `{prefix}snippet` is used by itself, this will retrieve -a list of snippets that are currently set. `{prefix}snippet-name` will show what the -snippet point to. - -To create a snippet: -- `{prefix}snippet add snippet-name A pre-defined text.` - -You can use your snippet in a thread channel -with `{prefix}snippet-name`, the message ""A pre-defined text."" -will be sent to the recipient. - -Currently, there is not a built-in anonymous snippet command; however, a workaround -is available using `{prefix}alias`. Here is how: -- `{prefix}alias add snippet-name anonreply A pre-defined anonymous text.` - -See also `{prefix}alias`.","Cog: Modmail -Command: snippet" -"View the raw content of a snippet.","View the raw content of a snippet.","Cog: Modmail -Command: snippet raw" -"View the raw content of a snippet.","View the raw content of a snippet.","Cog: Modmail -Command: snippet raw" -"Add a snippet.","Add a snippet.","Cog: Modmail -Command: snippet add" -"Add a snippet. - -Simply to add a snippet, do: ``` -{prefix}snippet add hey hello there :) -``` -then when you type `{prefix}hey`, ""hello there :)"" will get sent to the recipient. - -To add a multi-word snippet name, use quotes: ``` -{prefix}snippet add ""two word"" this is a two word snippet. -```","Add a snippet. - -Simply to add a snippet, do: ``` -{prefix}snippet add hey hello there :) -``` -then when you type `{prefix}hey`, ""hello there :)"" will get sent to the recipient. - -To add a multi-word snippet name, use quotes: ``` -{prefix}snippet add ""two word"" this is a two word snippet. -```","Cog: Modmail -Command: snippet add" -"Remove a snippet.","Remove a snippet.","Cog: Modmail -Command: snippet remove" -"Remove a snippet.","Remove a snippet.","Cog: Modmail -Command: snippet remove" -"Edit a snippet.","Edit a snippet.","Cog: Modmail -Command: snippet edit" -"Edit a snippet. - -To edit a multi-word snippet name, use quotes: ``` -{prefix}snippet edit ""two word"" this is a new two word snippet. -```","Edit a snippet. - -To edit a multi-word snippet name, use quotes: ``` -{prefix}snippet edit ""two word"" this is a new two word snippet. -```","Cog: Modmail -Command: snippet edit" -"Move a thread to another category.","Move a thread to another category.","Cog: Modmail -Command: move" -"Move a thread to another category. - -`category` may be a category ID, mention, or name. -`specifics` is a string which takes in arguments on how to perform the move. Ex: ""silently""","Move a thread to another category. - -`category` may be a category ID, mention, or name. -`specifics` is a string which takes in arguments on how to perform the move. Ex: ""silently""","Cog: Modmail -Command: move" -"Close the current thread.","Close the current thread.","Cog: Modmail -Command: close" -"Close the current thread. - -Close after a period of time: -- `{prefix}close in 5 hours` -- `{prefix}close 2m30s` - -Custom close messages: -- `{prefix}close 2 hours The issue has been resolved.` -- `{prefix}close We will contact you once we find out more.` - -Silently close a thread (no message) -- `{prefix}close silently` -- `{prefix}close in 10m silently` - -Stop a thread from closing: -- `{prefix}close cancel`","Close the current thread. - -Close after a period of time: -- `{prefix}close in 5 hours` -- `{prefix}close 2m30s` - -Custom close messages: -- `{prefix}close 2 hours The issue has been resolved.` -- `{prefix}close We will contact you once we find out more.` - -Silently close a thread (no message) -- `{prefix}close silently` -- `{prefix}close in 10m silently` - -Stop a thread from closing: -- `{prefix}close cancel`","Cog: Modmail -Command: close" -"Notify a user or role when the next thread message received.","Notify a user or role when the next thread message received.","Cog: Modmail -Command: notify" -"Notify a user or role when the next thread message received. - -Once a thread message is received, `user_or_role` will be pinged once. - -Leave `user_or_role` empty to notify yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name. role ID, mention, name, ""everyone"", or ""here"".","Notify a user or role when the next thread message received. - -Once a thread message is received, `user_or_role` will be pinged once. - -Leave `user_or_role` empty to notify yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name. role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail -Command: notify" -"Un-notify a user, role, or yourself from a thread.","Un-notify a user, role, or yourself from a thread.","Cog: Modmail -Command: unnotify" -"Un-notify a user, role, or yourself from a thread. - -Leave `user_or_role` empty to un-notify yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Un-notify a user, role, or yourself from a thread. - -Leave `user_or_role` empty to un-notify yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail -Command: unnotify" -"Notify a user, role, or yourself for every thread message received.","Notify a user, role, or yourself for every thread message received.","Cog: Modmail -Command: subscribe" -"Notify a user, role, or yourself for every thread message received. - -You will be pinged for every thread message received until you unsubscribe. - -Leave `user_or_role` empty to subscribe yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Notify a user, role, or yourself for every thread message received. - -You will be pinged for every thread message received until you unsubscribe. - -Leave `user_or_role` empty to subscribe yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail -Command: subscribe" -"Unsubscribe a user, role, or yourself from a thread.","Unsubscribe a user, role, or yourself from a thread.","Cog: Modmail -Command: unsubscribe" -"Unsubscribe a user, role, or yourself from a thread. - -Leave `user_or_role` empty to unsubscribe yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Unsubscribe a user, role, or yourself from a thread. - -Leave `user_or_role` empty to unsubscribe yourself. -`@here` and `@everyone` can be substituted with `here` and `everyone`. -`user_or_role` may be a user ID, mention, name, role ID, mention, name, ""everyone"", or ""here"".","Cog: Modmail -Command: unsubscribe" -"Flags a Modmail thread as NSFW (not safe for work).","Flags a Modmail thread as NSFW (not safe for work).","Cog: Modmail -Command: nsfw" -"Flags a Modmail thread as NSFW (not safe for work).","Flags a Modmail thread as NSFW (not safe for work).","Cog: Modmail -Command: nsfw" -"Flags a Modmail thread as SFW (safe for work).","Flags a Modmail thread as SFW (safe for work).","Cog: Modmail -Command: sfw" -"Flags a Modmail thread as SFW (safe for work).","Flags a Modmail thread as SFW (safe for work).","Cog: Modmail -Command: sfw" -"Retrieves the link to the current thread's logs.","Retrieves the link to the current thread's logs.","Cog: Modmail -Command: loglink" -"Retrieves the link to the current thread's logs.","Retrieves the link to the current thread's logs.","Cog: Modmail -Command: loglink" -"Get previous Modmail thread logs of a member.","Get previous Modmail thread logs of a member.","Cog: Modmail -Command: logs" -"Get previous Modmail thread logs of a member. - -Leave `user` blank when this command is used within a -thread channel to show logs for the current recipient. -`user` may be a user ID, mention, or name.","Get previous Modmail thread logs of a member. - -Leave `user` blank when this command is used within a -thread channel to show logs for the current recipient. -`user` may be a user ID, mention, or name.","Cog: Modmail -Command: logs" -"Get all logs closed by the specified user.","Get all logs closed by the specified user.","Cog: Modmail -Command: logs closed-by" -"Get all logs closed by the specified user. - -If no `user` is provided, the user will be the person who sent this command. -`user` may be a user ID, mention, or name.","Get all logs closed by the specified user. - -If no `user` is provided, the user will be the person who sent this command. -`user` may be a user ID, mention, or name.","Cog: Modmail -Command: logs closed-by" -"Wipe a log entry from the database.","Wipe a log entry from the database.","Cog: Modmail -Command: logs delete" -"Wipe a log entry from the database.","Wipe a log entry from the database.","Cog: Modmail -Command: logs delete" -"Get all logs where the specified user has responded at least once.","Get all logs where the specified user has responded at least once.","Cog: Modmail -Command: logs responded" -"Get all logs where the specified user has responded at least once. - -If no `user` is provided, the user will be the person who sent this command. -`user` may be a user ID, mention, or name.","Get all logs where the specified user has responded at least once. - -If no `user` is provided, the user will be the person who sent this command. -`user` may be a user ID, mention, or name.","Cog: Modmail -Command: logs responded" -"Retrieve all logs that contain messages with your query.","Retrieve all logs that contain messages with your query.","Cog: Modmail -Command: logs search" -"Retrieve all logs that contain messages with your query. - -Provide a `limit` to specify the maximum number of logs the bot should find.","Retrieve all logs that contain messages with your query. - -Provide a `limit` to specify the maximum number of logs the bot should find.","Cog: Modmail -Command: logs search" -"Reply to a Modmail thread.","Reply to a Modmail thread.","Cog: Modmail -Command: reply" -"Reply to a Modmail thread. - -Supports attachments and images as well as -automatically embedding image URLs.","Reply to a Modmail thread. - -Supports attachments and images as well as -automatically embedding image URLs.","Cog: Modmail -Command: reply" -"Reply to a Modmail thread with variables.","Reply to a Modmail thread with variables.","Cog: Modmail -Command: freply" -"Reply to a Modmail thread with variables. - -Works just like `{prefix}reply`, however with the addition of three variables: - - `{{channel}}` - the `discord.TextChannel` object - - `{{recipient}}` - the `discord.User` object of the recipient - - `{{author}}` - the `discord.User` object of the author - -Supports attachments and images as well as -automatically embedding image URLs.","Reply to a Modmail thread with variables. - -Works just like `{prefix}reply`, however with the addition of three variables: - - `{{channel}}` - the `discord.TextChannel` object - - `{{recipient}}` - the `discord.User` object of the recipient - - `{{author}}` - the `discord.User` object of the author - -Supports attachments and images as well as -automatically embedding image URLs.","Cog: Modmail -Command: freply" -"Reply to a thread anonymously.","Reply to a thread anonymously.","Cog: Modmail -Command: areply" -"Reply to a thread anonymously. - -You can edit the anonymous user's name, -avatar and tag using the config command. - -Edit the `anon_username`, `anon_avatar_url` -and `anon_tag` config variables to do so.","Reply to a thread anonymously. - -You can edit the anonymous user's name, -avatar and tag using the config command. - -Edit the `anon_username`, `anon_avatar_url` -and `anon_tag` config variables to do so.","Cog: Modmail -Command: areply" -"Take a note about the current thread.","Take a note about the current thread.","Cog: Modmail -Command: note" -"Take a note about the current thread. - -Useful for noting context.","Take a note about the current thread. - -Useful for noting context.","Cog: Modmail -Command: note" -"Edit a message that was sent using the reply or anonreply command.","Edit a message that was sent using the reply or anonreply command.","Cog: Modmail -Command: edit" -"Edit a message that was sent using the reply or anonreply command. - -If no `message_id` is provided, -the last message sent by a staff will be edited. - -Note: attachments **cannot** be edited.","Edit a message that was sent using the reply or anonreply command. - -If no `message_id` is provided, -the last message sent by a staff will be edited. - -Note: attachments **cannot** be edited.","Cog: Modmail -Command: edit" -"Create a thread with a specified member.","Create a thread with a specified member.","Cog: Modmail -Command: contact" -"Create a thread with a specified member. - -If `category` is specified, the thread -will be created in that specified category. - -`category`, if specified, may be a category ID, mention, or name. -`user` may be a user ID, mention, or name.","Create a thread with a specified member. - -If `category` is specified, the thread -will be created in that specified category. - -`category`, if specified, may be a category ID, mention, or name. -`user` may be a user ID, mention, or name.","Cog: Modmail -Command: contact" -"Retrieve a list of blocked users.","Retrieve a list of blocked users.","Cog: Modmail -Command: blocked" -"Retrieve a list of blocked users.","Retrieve a list of blocked users.","Cog: Modmail -Command: blocked" -"Whitelist or un-whitelist a user from getting blocked.","Whitelist or un-whitelist a user from getting blocked.","Cog: Modmail -Command: blocked whitelist" -"Whitelist or un-whitelist a user from getting blocked. - -Useful for preventing users from getting blocked by account_age/guild_age restrictions.","Whitelist or un-whitelist a user from getting blocked. - -Useful for preventing users from getting blocked by account_age/guild_age restrictions.","Cog: Modmail -Command: blocked whitelist" -"Block a user from using Modmail.","Block a user from using Modmail.","Cog: Modmail -Command: block" -"Block a user from using Modmail. - -You may choose to set a time as to when the user will automatically be unblocked. - -Leave `user` blank when this command is used within a -thread channel to block the current recipient. -`user` may be a user ID, mention, or name. -`duration` may be a simple ""human-readable"" time text. See `{prefix}help close` for examples.","Block a user from using Modmail. - -You may choose to set a time as to when the user will automatically be unblocked. - -Leave `user` blank when this command is used within a -thread channel to block the current recipient. -`user` may be a user ID, mention, or name. -`duration` may be a simple ""human-readable"" time text. See `{prefix}help close` for examples.","Cog: Modmail -Command: block" -"Unblock a user from using Modmail.","Unblock a user from using Modmail.","Cog: Modmail -Command: unblock" -"Unblock a user from using Modmail. - -Leave `user` blank when this command is used within a -thread channel to unblock the current recipient. -`user` may be a user ID, mention, or name.","Unblock a user from using Modmail. - -Leave `user` blank when this command is used within a -thread channel to unblock the current recipient. -`user` may be a user ID, mention, or name.","Cog: Modmail -Command: unblock" -"Delete a message that was sent using the reply command or a note.","Delete a message that was sent using the reply command or a note.","Cog: Modmail -Command: delete" -"Delete a message that was sent using the reply command or a note. - -Deletes the previous message, unless a message ID is provided, -which in that case, deletes the message with that message ID. - -Notes can only be deleted when a note ID is provided.","Delete a message that was sent using the reply command or a note. - -Deletes the previous message, unless a message ID is provided, -which in that case, deletes the message with that message ID. - -Notes can only be deleted when a note ID is provided.","Cog: Modmail -Command: delete" -"Repair a thread broken by Discord.","Repair a thread broken by Discord.","Cog: Modmail -Command: repair" -"Repair a thread broken by Discord.","Repair a thread broken by Discord.","Cog: Modmail -Command: repair" -"Re-enables DM functionalities of Modmail.","Re-enables DM functionalities of Modmail.","Cog: Modmail -Command: enable" -"Re-enables DM functionalities of Modmail. - -Undo's the `{prefix}disable` command, all DM will be relayed after running this command.","Re-enables DM functionalities of Modmail. - -Undo's the `{prefix}disable` command, all DM will be relayed after running this command.","Cog: Modmail -Command: enable" -"Disable partial or full Modmail thread functions.","Disable partial or full Modmail thread functions.","Cog: Modmail -Command: disable" -"Disable partial or full Modmail thread functions. - -To stop all new threads from being created, do `{prefix}disable new`. -To stop all existing threads from DMing Modmail, do `{prefix}disable all`. -To check if the DM function for Modmail is enabled, do `{prefix}isenable`.","Disable partial or full Modmail thread functions. - -To stop all new threads from being created, do `{prefix}disable new`. -To stop all existing threads from DMing Modmail, do `{prefix}disable all`. -To check if the DM function for Modmail is enabled, do `{prefix}isenable`.","Cog: Modmail -Command: disable" -"Stop accepting new Modmail threads.","Stop accepting new Modmail threads.","Cog: Modmail -Command: disable new" -"Stop accepting new Modmail threads. - -No new threads can be created through DM.","Stop accepting new Modmail threads. - -No new threads can be created through DM.","Cog: Modmail -Command: disable new" -"Disables all DM functionalities of Modmail.","Disables all DM functionalities of Modmail.","Cog: Modmail -Command: disable all" -"Disables all DM functionalities of Modmail. - -No new threads can be created through DM nor no further DM messages will be relayed.","Disables all DM functionalities of Modmail. - -No new threads can be created through DM nor no further DM messages will be relayed.","Cog: Modmail -Command: disable all" -"Check if the DM functionalities of Modmail is enabled.","Check if the DM functionalities of Modmail is enabled.","Cog: Modmail -Command: isenable" -"Check if the DM functionalities of Modmail is enabled.","Check if the DM functionalities of Modmail is enabled.","Cog: Modmail -Command: isenable" -"Plugins expand Modmail functionality by allowing third-party addons. - -These addons could have a range of features from moderation to simply -making your life as a moderator easier! -Learn how to create a plugin yourself here: -https://github.com/kyb3r/modmail/wiki/Plugins","Plugins expand Modmail functionality by allowing third-party addons. - -These addons could have a range of features from moderation to simply -making your life as a moderator easier! -Learn how to create a plugin yourself here: -https://github.com/kyb3r/modmail/wiki/Plugins","Cog: Plugins" -"Manage plugins for Modmail.","Manage plugins for Modmail.","Cog: Plugins -Command: plugins" -"Manage plugins for Modmail.","Manage plugins for Modmail.","Cog: Plugins -Command: plugins" -"Install a new plugin for the bot.","Install a new plugin for the bot.","Cog: Plugins -Command: plugins add" -"Install a new plugin for the bot. - -`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, -or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Install a new plugin for the bot. - -`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, -or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Cog: Plugins -Command: plugins add" -"Remove an installed plugin of the bot.","Remove an installed plugin of the bot.","Cog: Plugins -Command: plugins remove" -"Remove an installed plugin of the bot. - -`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference -to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Remove an installed plugin of the bot. - -`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference -to a GitHub hosted plugin (in the format `user/repo/name[@branch]`).","Cog: Plugins -Command: plugins remove" -"Update a plugin for the bot.","Update a plugin for the bot.","Cog: Plugins -Command: plugins update" -"Update a plugin for the bot. - -`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference -to a GitHub hosted plugin (in the format `user/repo/name[@branch]`). - -To update all plugins, do `{prefix}plugins update`.","Update a plugin for the bot. - -`plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference -to a GitHub hosted plugin (in the format `user/repo/name[@branch]`). - -To update all plugins, do `{prefix}plugins update`.","Cog: Plugins -Command: plugins update" -"Show a list of currently loaded plugins.","Show a list of currently loaded plugins.","Cog: Plugins -Command: plugins loaded" -"Show a list of currently loaded plugins.","Show a list of currently loaded plugins.","Cog: Plugins -Command: plugins loaded" -"Shows a list of all approved plugins.","Shows a list of all approved plugins.","Cog: Plugins -Command: plugins registry" -"Shows a list of all approved plugins. - -Usage: -`{prefix}plugin registry` Details about all plugins. -`{prefix}plugin registry plugin-name` Details about the indicated plugin. -`{prefix}plugin registry page-number` Jump to a page in the registry.","Shows a list of all approved plugins. - -Usage: -`{prefix}plugin registry` Details about all plugins. -`{prefix}plugin registry plugin-name` Details about the indicated plugin. -`{prefix}plugin registry page-number` Jump to a page in the registry.","Cog: Plugins -Command: plugins registry" -"Shows a compact view of all plugins within the registry.","Shows a compact view of all plugins within the registry.","Cog: Plugins -Command: plugins registry compact" -"Shows a compact view of all plugins within the registry.","Shows a compact view of all plugins within the registry.","Cog: Plugins -Command: plugins registry compact" -"General commands that provide utility.","General commands that provide utility.","Cog: Utility" -"Shows the changelog of the Modmail.","Shows the changelog of the Modmail.","Cog: Utility -Command: changelog" -"Shows the changelog of the Modmail.","Shows the changelog of the Modmail.","Cog: Utility -Command: changelog" -"Shows information about this bot.","Shows information about this bot.","Cog: Utility -Command: about" -"Shows information about this bot.","Shows information about this bot.","Cog: Utility -Command: about" -"Shows a list of sponsors.","Shows a list of sponsors.","Cog: Utility -Command: sponsors" -"Shows a list of sponsors.","Shows a list of sponsors.","Cog: Utility -Command: sponsors" -"Shows the recent application logs of the bot.","Shows the recent application logs of the bot.","Cog: Utility -Command: debug" -"Shows the recent application logs of the bot.","Shows the recent application logs of the bot.","Cog: Utility -Command: debug" -"Posts application-logs to Hastebin.","Posts application-logs to Hastebin.","Cog: Utility -Command: debug hastebin" -"Posts application-logs to Hastebin.","Posts application-logs to Hastebin.","Cog: Utility -Command: debug hastebin" -"Clears the locally cached logs.","Clears the locally cached logs.","Cog: Utility -Command: debug clear" -"Clears the locally cached logs.","Clears the locally cached logs.","Cog: Utility -Command: debug clear" -"Set an activity status for the bot.","Set an activity status for the bot.","Cog: Utility -Command: activity" -"Set an activity status for the bot. - -Possible activity types: - - `playing` - - `streaming` - - `listening` - - `watching` - -When activity type is set to `listening`, -it must be followed by a ""to"": ""listening to..."" - -When activity type is set to `streaming`, you can set -the linked twitch page: -- `{prefix}config set twitch_url https://www.twitch.tv/somechannel/` - -To remove the current activity status: -- `{prefix}activity clear`","Set an activity status for the bot. - -Possible activity types: - - `playing` - - `streaming` - - `listening` - - `watching` - -When activity type is set to `listening`, -it must be followed by a ""to"": ""listening to..."" - -When activity type is set to `streaming`, you can set -the linked twitch page: -- `{prefix}config set twitch_url https://www.twitch.tv/somechannel/` - -To remove the current activity status: -- `{prefix}activity clear`","Cog: Utility -Command: activity" -"Set a status for the bot.","Set a status for the bot.","Cog: Utility -Command: status" -"Set a status for the bot. - -Possible status types: - - `online` - - `idle` - - `dnd` or `do not disturb` - - `invisible` or `offline` - -To remove the current status: -- `{prefix}status clear`","Set a status for the bot. - -Possible status types: - - `online` - - `idle` - - `dnd` or `do not disturb` - - `invisible` or `offline` - -To remove the current status: -- `{prefix}status clear`","Cog: Utility -Command: status" -"Pong! Returns your websocket latency.","Pong! Returns your websocket latency.","Cog: Utility -Command: ping" -"Pong! Returns your websocket latency.","Pong! Returns your websocket latency.","Cog: Utility -Command: ping" -"Change what the bot mentions at the start of each thread.","Change what the bot mentions at the start of each thread.","Cog: Utility -Command: mention" -"Change what the bot mentions at the start of each thread. - -Type only `{prefix}mention` to retrieve your current ""mention"" message.","Change what the bot mentions at the start of each thread. - -Type only `{prefix}mention` to retrieve your current ""mention"" message.","Cog: Utility -Command: mention" -"Change the prefix of the bot.","Change the prefix of the bot.","Cog: Utility -Command: prefix" -"Change the prefix of the bot. - -Type only `{prefix}prefix` to retrieve your current bot prefix.","Change the prefix of the bot. - -Type only `{prefix}prefix` to retrieve your current bot prefix.","Cog: Utility -Command: prefix" -"Modify changeable configuration variables for this bot.","Modify changeable configuration variables for this bot.","Cog: Utility -Command: config" -"Modify changeable configuration variables for this bot. - -Type `{prefix}config options` to view a list -of valid configuration variables. - -Type `{prefix}config help config-name` for info - on a config. - -To set a configuration variable: -- `{prefix}config set config-name value here` - -To remove a configuration variable: -- `{prefix}config remove config-name`","Modify changeable configuration variables for this bot. - -Type `{prefix}config options` to view a list -of valid configuration variables. - -Type `{prefix}config help config-name` for info - on a config. - -To set a configuration variable: -- `{prefix}config set config-name value here` - -To remove a configuration variable: -- `{prefix}config remove config-name`","Cog: Utility -Command: config" -"Return a list of valid configuration names you can change.","Return a list of valid configuration names you can change.","Cog: Utility -Command: config options" -"Return a list of valid configuration names you can change.","Return a list of valid configuration names you can change.","Cog: Utility -Command: config options" -"Set a configuration variable and its value.","Set a configuration variable and its value.","Cog: Utility -Command: config set" -"Set a configuration variable and its value.","Set a configuration variable and its value.","Cog: Utility -Command: config set" -"Delete a set configuration variable.","Delete a set configuration variable.","Cog: Utility -Command: config remove" -"Delete a set configuration variable.","Delete a set configuration variable.","Cog: Utility -Command: config remove" -"Show the configuration variables that are currently set.","Show the configuration variables that are currently set.","Cog: Utility -Command: config get" -"Show the configuration variables that are currently set. - -Leave `key` empty to show all currently set configuration variables.","Show the configuration variables that are currently set. - -Leave `key` empty to show all currently set configuration variables.","Cog: Utility -Command: config get" -"Show information on a specified configuration.","Show information on a specified configuration.","Cog: Utility -Command: config help" -"Show information on a specified configuration.","Show information on a specified configuration.","Cog: Utility -Command: config help" -"Create shortcuts to bot commands.","Create shortcuts to bot commands.","Cog: Utility -Command: alias" -"Create shortcuts to bot commands. - -When `{prefix}alias` is used by itself, this will retrieve -a list of alias that are currently set. `{prefix}alias-name` will show what the -alias point to. - -To use alias: - -First create an alias using: -- `{prefix}alias add alias-name other-command` - -For example: -- `{prefix}alias add r reply` -- Now you can use `{prefix}r` as an replacement for `{prefix}reply`. - -See also `{prefix}snippet`.","Create shortcuts to bot commands. - -When `{prefix}alias` is used by itself, this will retrieve -a list of alias that are currently set. `{prefix}alias-name` will show what the -alias point to. - -To use alias: - -First create an alias using: -- `{prefix}alias add alias-name other-command` - -For example: -- `{prefix}alias add r reply` -- Now you can use `{prefix}r` as an replacement for `{prefix}reply`. - -See also `{prefix}snippet`.","Cog: Utility -Command: alias" -"View the raw content of an alias.","View the raw content of an alias.","Cog: Utility -Command: alias raw" -"View the raw content of an alias.","View the raw content of an alias.","Cog: Utility -Command: alias raw" -"Add an alias.","Add an alias.","Cog: Utility -Command: alias add" -"Add an alias. - -Alias also supports multi-step aliases, to create a multi-step alias use quotes -to wrap each step and separate each step with `&&`. For example: - -- `{prefix}alias add movenreply ""move admin-category"" && ""reply Thanks for reaching out to the admins""` - -However, if you run into problems, try wrapping the command with quotes. For example: - -- This will fail: `{prefix}alias add reply You'll need to type && to work` -- Correct method: `{prefix}alias add reply ""You'll need to type && to work""`","Add an alias. - -Alias also supports multi-step aliases, to create a multi-step alias use quotes -to wrap each step and separate each step with `&&`. For example: - -- `{prefix}alias add movenreply ""move admin-category"" && ""reply Thanks for reaching out to the admins""` - -However, if you run into problems, try wrapping the command with quotes. For example: - -- This will fail: `{prefix}alias add reply You'll need to type && to work` -- Correct method: `{prefix}alias add reply ""You'll need to type && to work""`","Cog: Utility -Command: alias add" -"Remove an alias.","Remove an alias.","Cog: Utility -Command: alias remove" -"Remove an alias.","Remove an alias.","Cog: Utility -Command: alias remove" -"Edit an alias.","Edit an alias.","Cog: Utility -Command: alias edit" -"Edit an alias.","Edit an alias.","Cog: Utility -Command: alias edit" -"Set the permissions for Modmail commands.","Set the permissions for Modmail commands.","Cog: Utility -Command: permissions" -"Set the permissions for Modmail commands. - -You may set permissions based on individual command names, or permission -levels. - -Acceptable permission levels are: - - **Owner** [5] (absolute control over the bot) - - **Administrator** [4] (administrative powers such as setting activities) - - **Moderator** [3] (ability to block) - - **Supporter** [2] (access to core Modmail supporting functions) - - **Regular** [1] (most basic interactions such as help and about) - -By default, owner is set to the absolute bot owner and regular is `@everyone`. - -To set permissions, see `{prefix}help permissions add`; and to change permission level for specific -commands see `{prefix}help permissions override`. - -Note: You will still have to manually give/take permission to the Modmail -category to users/roles.","Set the permissions for Modmail commands. - -You may set permissions based on individual command names, or permission -levels. - -Acceptable permission levels are: - - **Owner** [5] (absolute control over the bot) - - **Administrator** [4] (administrative powers such as setting activities) - - **Moderator** [3] (ability to block) - - **Supporter** [2] (access to core Modmail supporting functions) - - **Regular** [1] (most basic interactions such as help and about) - -By default, owner is set to the absolute bot owner and regular is `@everyone`. - -To set permissions, see `{prefix}help permissions add`; and to change permission level for specific -commands see `{prefix}help permissions override`. - -Note: You will still have to manually give/take permission to the Modmail -category to users/roles.","Cog: Utility -Command: permissions" -"Change a permission level for a specific command.","Change a permission level for a specific command.","Cog: Utility -Command: permissions override" -"Change a permission level for a specific command. - -Examples: -- `{prefix}perms override reply administrator` -- `{prefix}perms override ""plugin enabled"" moderator` - -To undo a permission override, see `{prefix}help permissions remove`. - -Example: -- `{prefix}perms remove override reply` -- `{prefix}perms remove override plugin enabled` - -You can retrieve a single or all command level override(s), see`{prefix}help permissions get`.","Change a permission level for a specific command. - -Examples: -- `{prefix}perms override reply administrator` -- `{prefix}perms override ""plugin enabled"" moderator` - -To undo a permission override, see `{prefix}help permissions remove`. - -Example: -- `{prefix}perms remove override reply` -- `{prefix}perms remove override plugin enabled` - -You can retrieve a single or all command level override(s), see`{prefix}help permissions get`.","Cog: Utility -Command: permissions override" -"Add a permission to a command or a permission level.","Add a permission to a command or a permission level.","Cog: Utility -Command: permissions add" -"Add a permission to a command or a permission level. - -For sub commands, wrap the complete command name with quotes. -To find a list of permission levels, see `{prefix}help perms`. - -Examples: -- `{prefix}perms add level REGULAR everyone` -- `{prefix}perms add command reply @user` -- `{prefix}perms add command ""plugin enabled"" @role` -- `{prefix}perms add command help 984301093849028` - -Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Add a permission to a command or a permission level. - -For sub commands, wrap the complete command name with quotes. -To find a list of permission levels, see `{prefix}help perms`. - -Examples: -- `{prefix}perms add level REGULAR everyone` -- `{prefix}perms add command reply @user` -- `{prefix}perms add command ""plugin enabled"" @role` -- `{prefix}perms add command help 984301093849028` - -Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Cog: Utility -Command: permissions add" -"Remove permission to use a command, permission level, or command level override.","Remove permission to use a command, permission level, or command level override.","Cog: Utility -Command: permissions remove" -"Remove permission to use a command, permission level, or command level override. - -For sub commands, wrap the complete command name with quotes. -To find a list of permission levels, see `{prefix}help perms`. - -Examples: -- `{prefix}perms remove level REGULAR everyone` -- `{prefix}perms remove command reply @user` -- `{prefix}perms remove command ""plugin enabled"" @role` -- `{prefix}perms remove command help 984301093849028` -- `{prefix}perms remove override block` -- `{prefix}perms remove override ""snippet add""` - -Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Remove permission to use a command, permission level, or command level override. - -For sub commands, wrap the complete command name with quotes. -To find a list of permission levels, see `{prefix}help perms`. - -Examples: -- `{prefix}perms remove level REGULAR everyone` -- `{prefix}perms remove command reply @user` -- `{prefix}perms remove command ""plugin enabled"" @role` -- `{prefix}perms remove command help 984301093849028` -- `{prefix}perms remove override block` -- `{prefix}perms remove override ""snippet add""` - -Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Cog: Utility -Command: permissions remove" -"View the currently-set permissions.","View the currently-set permissions.","Cog: Utility -Command: permissions get" -"View the currently-set permissions. - -To find a list of permission levels, see `{prefix}help perms`. - -To view all command and level permissions: - -Examples: -- `{prefix}perms get @user` -- `{prefix}perms get 984301093849028` - -To view all users and roles of a command or level permission: - -Examples: -- `{prefix}perms get command reply` -- `{prefix}perms get command plugin remove` -- `{prefix}perms get level SUPPORTER` - -To view command level overrides: - -Examples: -- `{prefix}perms get override block` -- `{prefix}perms get override permissions add` - -Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","View the currently-set permissions. - -To find a list of permission levels, see `{prefix}help perms`. - -To view all command and level permissions: - -Examples: -- `{prefix}perms get @user` -- `{prefix}perms get 984301093849028` - -To view all users and roles of a command or level permission: - -Examples: -- `{prefix}perms get command reply` -- `{prefix}perms get command plugin remove` -- `{prefix}perms get level SUPPORTER` - -To view command level overrides: - -Examples: -- `{prefix}perms get override block` -- `{prefix}perms get override permissions add` - -Do not ping `@everyone` for granting permission to everyone, use ""everyone"" or ""all"" instead.","Cog: Utility -Command: permissions get" -"Commands relating to logviewer oauth2 login authentication.","Commands relating to logviewer oauth2 login authentication.","Cog: Utility -Command: oauth" -"Commands relating to logviewer oauth2 login authentication. - -This functionality on your logviewer site is a [**Patron**](https://patreon.com/kyber) only feature.","Commands relating to logviewer oauth2 login authentication. - -This functionality on your logviewer site is a [**Patron**](https://patreon.com/kyber) only feature.","Cog: Utility -Command: oauth" -"Whitelist or un-whitelist a user or role to have access to logs.","Whitelist or un-whitelist a user or role to have access to logs.","Cog: Utility -Command: oauth whitelist" -"Whitelist or un-whitelist a user or role to have access to logs. - -`target` may be a role ID, name, mention, user ID, name, or mention.","Whitelist or un-whitelist a user or role to have access to logs. - -`target` may be a role ID, name, mention, user ID, name, or mention.","Cog: Utility -Command: oauth whitelist" -"Shows a list of users and roles that are whitelisted to view logs.","Shows a list of users and roles that are whitelisted to view logs.","Cog: Utility -Command: oauth show" -"Shows a list of users and roles that are whitelisted to view logs.","Shows a list of users and roles that are whitelisted to view logs.","Cog: Utility -Command: oauth show" -"Evaluates Python code.","Evaluates Python code.","Cog: Utility -Command: eval" -"Evaluates Python code.","Evaluates Python code.","Cog: Utility -Command: eval" -"Shows this help message.","Shows this help message.","Cog: Utility -Command: help" -"Shows this help message.","Shows this help message.","Cog: Utility -Command: help" diff --git a/modmail.sh b/modmail.sh new file mode 100644 index 0000000000..4f29170f0a --- /dev/null +++ b/modmail.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +pipenv run python3 bot.py \ No newline at end of file diff --git a/plugins/registry.json b/plugins/registry.json index 1c268d89be..5c343ebcff 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -8,6 +8,15 @@ "icon_url": "https://i.imgur.com/951szZ3.jpg", "thumbnail_url": "https://i.imgur.com/951szZ3.jpg" }, + "music": { + "repository": "lorenzo132/modmail-plugins", + "branch": "master", + "description": "Play your favourite music on your bot! Note: Only works on VPS follow this guide: https://gist.github.com/lorenzo132/5ef328e5dfcfaec19cb81dc7a63eaffa", + "bot_version": "2.20.1", + "title": "Music", + "icon_url": "https://i.imgur.com/R2olclk.png", + "thumbnail_url": "https://i.imgur.com/xuoQjPu.gif" + }, "dragory-migrate": { "repository": "kyb3r/modmail-plugins", "branch": "master", @@ -17,58 +26,22 @@ "icon_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png", "thumbnail_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png" }, - "autorole": { - "repository": "papiersnipper/modmail-plugins", + "media-only": { + "repository": "lorenzo132/modmail-plugins", "branch": "master", - "description": "Easily auto-assign a role to a user when they join your server.", + "description": "Make a channel mediaonly, only the following mediatypes will be accepted `.png` / `.gif` / `.jpg` / `.mp4`/ `.jpeg`", "bot_version": "2.20.1", - "title": "Autorole Plugin", - "icon_url": "https://i.imgur.com/67bEi82.png", - "thumbnail_url": "https://i.imgur.com/67bEi82.png" + "title": "Media-only", + "icon_url": "https://i.imgur.com/ussAoIi.png", + "thumbnail_url": "https://i.imgur.com/ussAoIi.png" }, "anti-steal-close": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Don't let anyone steal ya close.", - "title": "Anti Steal Close", - "icon_url": "https://i.imgur.com/LovxyV3.png", - "thumbnail_url": "https://i.imgur.com/LovxyV3.png" - }, - "embedder": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "Easily make embeds for a nicer presence.", - "bot_version": "2.20.1", - "title": "Embedder Plugin", - "icon_url": "https://i.imgur.com/l3uzJwD.png", - "thumbnail_url": "https://i.imgur.com/l3uzJwD.png" - }, - "leveling": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "A leveling system for your server: see who's active and who's not.", - "bot_version": "2.20.1", - "title": "Leveling Plugin", - "icon_url": "https://i.imgur.com/VuZ60QX.png", - "thumbnail_url": "https://i.imgur.com/VuZ60QX.png" - }, - "purger": { - "repository": "papiersnipper/modmail-plugins", + "repository": "officialpiyush/modmail-plugins", "branch": "master", - "description": "Delete multiple messages at a time.", - "bot_version": "2.20.1", - "title": "Purger Plugin", - "icon_url": "https://i.imgur.com/HnC42jM.png", - "thumbnail_url": "https://i.imgur.com/HnC42jM.png" - }, - "supporters": { - "repository": "papiersnipper/modmail-plugins", - "branch": "master", - "description": "Let your users know who is part of the support team.", - "bot_version": "2.20.1", - "title": "Supporters Plugin", - "icon_url": "https://i.imgur.com/1QXRutA.png", - "thumbnail_url": "https://i.imgur.com/1QXRutA.png" + "description": "Don't let anyone steal ya close.", + "title": "Anti Steal Close", + "icon_url": "https://i.imgur.com/LovxyV3.png", + "thumbnail_url": "https://i.imgur.com/LovxyV3.png" }, "announcement": { "repository": "officialpiyush/modmail-plugins", @@ -115,15 +88,6 @@ "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" }, - "translator": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "You can auto translate thread msgs using this plugin or translate text fromm any language to English!", - "bot_version": "2.20.1", - "title": "Translator Plugin", - "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", - "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" - }, "welcomer": { "repository": "fourjr/modmail-plugins", "branch": "master", @@ -150,7 +114,7 @@ "title": "Backup Database (backupdb)", "icon_url": "https://images.ionadev.ml/b/nKAlOC4.jpg", "thumbnail_url": "https://images.ionadev.ml/b/nKAlOC4.jpg" - }, + }, "colors": { "repository": "Taaku18/modmail-plugins", "branch": "master", @@ -160,7 +124,7 @@ "icon_url": "https://cdn1.iconfinder.com/data/icons/weather-19/32/rainbow-512.png", "thumbnail_url": "https://i.imgur.com/fSxnc9W.jpg" }, - "fun": { + "fun": { "repository": "TheKinG2149/modmail-plugins", "branch": "master", "description": "Some fun commands like 8ball, dadjokes", @@ -168,9 +132,9 @@ "title": "Fun", "icon_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png", "thumbnail_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png" - }, + }, "stats": { - "repository": "MiTonder/modmail-plugins", + "repository": "KarateWumpus/modmail-plugins", "branch": "master", "description": "Get useful stats directly in an embed about either the Modmail bot, a user or the server.", "bot_version": "2.24.1", @@ -190,10 +154,55 @@ "serverstats": { "repository": "dazvise/modmail-plugins", "branch": "master", - "description": "Interesting and accurate statistics about your server.", + "description": "Voice channels containing interesting and accurate statistics about your server such as Member Count.", "bot_version": "2.20.1", "title": "Server Stats", "icon_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png", "thumbnail_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png" + }, + "suggest": { + "repository": "realcyguy/modmail-plugins", + "branch": "master", + "description": "Send suggestions to a selected server! It even has moderation...", + "bot_version": "3.4.1", + "title": "Suggest stuff.", + "icon_url": "https://i.imgur.com/qtE7AH8.png", + "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" + }, + "githubstats": { + "repository": "mischievousdev/modmail-plugins", + "branch": "master", + "description": "Github statistics in discord", + "bot_version": "2.20.1", + "title": "Github Stats", + "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", + "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" + }, + "slowmode": { + "repository": "teen1/modmail-plugins", + "branch": "master", + "description": "Configure slow mode for your channels with Modmail!", + "bot_version": "2.20.1", + "title": "Slow Mode", + "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", + "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" + }, + "publish": { + "repository": "codeinteger6/modmail-plugins", + "branch": "master", + "description": "Publish messages sent in announcement channels.", + "bot_version": "3.5.0", + "title": "Publish", + "icon_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png", + "thumbnail_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png" + }, + "translate": { + "repository": "WebKide/modmail-plugins", + "branch": "master", + "description": "(∩`-´)⊃━☆゚.*・。゚ translate text from one language to another (defaults to English)\n\nGet full list of available languages at: https://github.com/WebKide/modmail-plugins/blob/master/translate/langs.json\n\nThis command conflicts with Translator-plugin", + "bot_version": "3.5.0", + "title": "Translate", + "icon_url": "https://i.imgur.com/yeHFKgl.png", + "thumbnail_url": "https://i.imgur.com/yeHFKgl.png" } -} +} \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 1841d893a1..4aa8248546 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4,13 +4,13 @@ description = "Async http client/server framework (asyncio)" name = "aiohttp" optional = false python-versions = ">=3.5.3" -version = "3.5.4" +version = "3.6.2" [package.dependencies] async-timeout = ">=3.0,<4.0" attrs = ">=17.3.0" chardet = ">=2.0,<4.0" -multidict = ">=4.0,<5.0" +multidict = ">=4.5,<5.0" yarl = ">=1.0,<2.0" [[package]] @@ -19,20 +19,20 @@ description = "A small Python module for determining appropriate platform-specif name = "appdirs" optional = false python-versions = "*" -version = "1.4.3" +version = "1.4.4" [[package]] category = "dev" description = "An abstract syntax tree for Python with inference support." name = "astroid" optional = false -python-versions = ">=3.5.*" -version = "2.3.3" +python-versions = ">=3.5" +version = "2.4.1" [package.dependencies] lazy-object-proxy = ">=1.4.0,<1.5.0" six = ">=1.12,<2.0" -wrapt = ">=1.11.0,<1.12.0" +wrapt = ">=1.11,<2.0" [package.dependencies.typed-ast] python = "<3.8" @@ -75,13 +75,16 @@ description = "The uncompromising code formatter." name = "black" optional = false python-versions = ">=3.6" -version = "19.3b0" +version = "19.10b0" [package.dependencies] appdirs = "*" attrs = ">=18.1.0" click = ">=6.5" +pathspec = ">=0.6,<1" +regex = "*" toml = ">=0.9.4" +typed-ast = ">=1.4.0" [[package]] category = "main" @@ -96,8 +99,8 @@ category = "dev" description = "Composable command line interface toolkit" name = "click" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "7.0" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "7.1.2" [[package]] category = "main" @@ -109,15 +112,15 @@ version = "0.4.3" [[package]] category = "main" -description = "A python wrapper for the Discord API" +description = "A Python wrapper for the Discord API" name = "discord.py" optional = false python-versions = ">=3.5.3" -version = "1.2.5" +version = "1.3.3" [package.dependencies] -aiohttp = ">=3.3.0,<3.6.0" -websockets = ">=6.0,<7.0" +aiohttp = ">=3.6.0,<3.7.0" +websockets = ">=6.0,<7.0 || >7.0,<8.0 || >8.0,<8.0.1 || >8.0.1,<9.0" [[package]] category = "main" @@ -146,24 +149,24 @@ version = "3.1.1" [[package]] category = "dev" description = "Git Object Database" -name = "gitdb2" +name = "gitdb" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.0.6" +python-versions = ">=3.4" +version = "4.0.5" [package.dependencies] -smmap2 = ">=2.0.0" +smmap = ">=3.0.1,<4" [[package]] category = "dev" description = "Python Git Library" name = "gitpython" optional = false -python-versions = ">=3.0, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.0.5" +python-versions = ">=3.4" +version = "3.1.3" [package.dependencies] -gitdb2 = ">=2.0.0" +gitdb = ">=4.0.1,<5" [[package]] category = "main" @@ -171,7 +174,7 @@ description = "Internationalized Domain Names in Applications (IDNA)" name = "idna" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.8" +version = "2.9" [[package]] category = "main" @@ -226,7 +229,7 @@ description = "multidict implementation" name = "multidict" optional = false python-versions = ">=3.5" -version = "4.7.1" +version = "4.7.6" [[package]] category = "main" @@ -245,7 +248,15 @@ description = "Parse human-readable date/time text." name = "parsedatetime" optional = false python-versions = "*" -version = "2.5" +version = "2.6" + +[[package]] +category = "dev" +description = "Utility library for gitignore style pattern matching of file paths." +name = "pathspec" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.8.0" [[package]] category = "dev" @@ -253,7 +264,7 @@ description = "Python Build Reasonableness" name = "pbr" optional = false python-versions = "*" -version = "5.4.4" +version = "5.4.5" [[package]] category = "dev" @@ -261,13 +272,14 @@ description = "python code static checker" name = "pylint" optional = false python-versions = ">=3.5.*" -version = "2.4.4" +version = "2.5.2" [package.dependencies] -astroid = ">=2.3.0,<2.4" +astroid = ">=2.4.0,<=2.5" colorama = "*" isort = ">=4.2.5,<5" mccabe = ">=0.6,<0.7" +toml = ">=0.7.1" [[package]] category = "main" @@ -275,7 +287,7 @@ description = "Python driver for MongoDB " name = "pymongo" optional = true python-versions = "*" -version = "3.10.0" +version = "3.10.1" [[package]] category = "main" @@ -294,43 +306,50 @@ description = "Add .env support to your django/flask apps in development and dep name = "python-dotenv" optional = false python-versions = "*" -version = "0.10.3" +version = "0.10.5" [[package]] category = "dev" description = "YAML parser and emitter for Python" name = "pyyaml" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "5.2" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "5.3.1" + +[[package]] +category = "dev" +description = "Alternative regular expression module, to replace re." +name = "regex" +optional = false +python-versions = "*" +version = "2020.6.7" [[package]] category = "main" description = "Python 2 and 3 compatibility utilities" name = "six" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "1.13.0" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.15.0" [[package]] category = "dev" description = "A pure Python implementation of a sliding window memory map manager" -name = "smmap2" +name = "smmap" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.0.5" +version = "3.0.4" [[package]] category = "dev" description = "Manage dynamic plugins for Python applications" name = "stevedore" optional = false -python-versions = "*" -version = "1.31.0" +python-versions = ">=3.6" +version = "2.0.0" [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" -six = ">=1.10.0" [[package]] category = "dev" @@ -338,16 +357,15 @@ description = "Python Library for Tom's Obvious, Minimal Language" name = "toml" optional = false python-versions = "*" -version = "0.10.0" +version = "0.10.1" [[package]] category = "dev" description = "a fork of Python 2 and 3 ast modules with type comment support" -marker = "implementation_name == \"cpython\" and python_version < \"3.8\"" name = "typed-ast" optional = false python-versions = "*" -version = "1.4.0" +version = "1.4.1" [[package]] category = "main" @@ -362,8 +380,8 @@ category = "main" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" name = "websockets" optional = false -python-versions = ">=3.4" -version = "6.0" +python-versions = ">=3.6.1" +version = "8.1" [[package]] category = "dev" @@ -371,7 +389,7 @@ description = "Module for decorators, wrappers and monkey patching." name = "wrapt" optional = false python-versions = "*" -version = "1.11.2" +version = "1.12.1" [[package]] category = "main" @@ -385,48 +403,53 @@ version = "1.4.2" idna = ">=2.0" multidict = ">=4.0" +[extras] +mongodb = ["motor"] + [metadata] -content-hash = "fbe9e329f33e482854cff5bf05b006de9830c2d46bf3874e2ee4f8a8da0b1797" +content-hash = "68d5c15e62c4bf5f65fd3b0a9a2586b15557f724c3de5b756534bacd52cbfe40" python-versions = "^3.7" [metadata.hashes] -aiohttp = ["00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55", "0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed", "09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10", "199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5", "296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1", "368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939", "40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390", "629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa", "6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc", "87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5", "9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d", "9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf", "9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6", "a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72", "a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12", "a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366", "acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4", "b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300", "c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d", "cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303", "d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6", "e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889"] -appdirs = ["9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", "d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"] -astroid = ["71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", "840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"] +aiohttp = ["1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", "259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", "2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", "32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", "344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", "460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", "4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", "50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", "6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", "65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", "ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", "b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965"] +appdirs = ["7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", "a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"] +astroid = ["4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1", "d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38"] async-timeout = ["0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"] attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] bandit = ["336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952", "41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"] -black = ["09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", "68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"] +black = ["1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", "c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"] chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] -click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] +click = ["d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"] colorama = ["7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", "e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"] -"discord.py" = ["7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d"] +"discord.py" = ["406871b06d86c3dc49fba63238519f28628dac946fef8a0e22988ff58ec05580", "ad00e34c72d2faa8db2157b651d05f3c415d7d05078e7e41dc9e8dc240051beb"] dnspython = ["36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", "f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"] emoji = ["60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"] futures = ["3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b", "51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd", "c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"] -gitdb2 = ["1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350", "96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b"] -gitpython = ["9c2398ffc3dcb3c40b27324b316f08a4f93ad646d5a6328cafbb871aa79f5e42", "c155c6a2653593ccb300462f6ef533583a913e17857cfef8fc617c246b6dc245"] -idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] +gitdb = ["91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"] +gitpython = ["e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a", "ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac"] +idna = ["7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", "a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"] isodate = ["2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", "aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"] isort = ["54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", "6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"] lazy-object-proxy = ["0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", "194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", "1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", "4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", "48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", "5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", "59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", "8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", "9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", "9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", "97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", "9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", "a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", "a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", "ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", "cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", "d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", "d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", "eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", "efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"] mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] motor = ["599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", "756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", "97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"] -multidict = ["09c19f642e055550c9319d5123221b7e07fc79bda58122aa93910e52f2ab2f29", "0c1a5d5f7aa7189f7b83c4411c2af8f1d38d69c4360d5de3eea129c65d8d7ce2", "12f22980e7ed0972a969520fb1e55682c9fca89a68b21b49ec43132e680be812", "258660e9d6b52de1a75097944e12718d3aa59adc611b703361e3577d69167aaf", "3374a23e707848f27b3438500db0c69eca82929337656fce556bd70031fbda74", "503b7fce0054c73aa631cc910a470052df33d599f3401f3b77e54d31182525d5", "6ce55f2c45ffc90239aab625bb1b4864eef33f73ea88487ef968291fbf09fb3f", "725496dde5730f4ad0a627e1a58e2620c1bde0ad1c8080aae15d583eb23344ce", "a3721078beff247d0cd4fb19d915c2c25f90907cf8d6cd49d0413a24915577c6", "ba566518550f81daca649eded8b5c7dd09210a854637c82351410aa15c49324a", "c42362750a51a15dc905cb891658f822ee5021bfbea898c03aa1ed833e2248a5", "cf14aaf2ab067ca10bca0b14d5cbd751dd249e65d371734bc0e47ddd8fafc175", "cf24e15986762f0e75a622eb19cfe39a042e952b8afba3e7408835b9af2be4fb", "d7b6da08538302c5245cd3103f333655ba7f274915f1f5121c4f4b5fbdb3febe", "e27e13b9ff0a914a6b8fb7e4947d4ac6be8e4f61ede17edffabd088817df9e26", "e53b205f8afd76fc6c942ef39e8ee7c519c775d336291d32874082a87802c67c", "ec804fc5f68695d91c24d716020278fcffd50890492690a7e1fef2e741f7172c"] +multidict = ["1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", "275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", "3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", "4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", "5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", "51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", "5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", "6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", "7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", "9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", "c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", "d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", "e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", "f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", "fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", "fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d"] natural = ["18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"] -parsedatetime = ["3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1", "d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667"] -pbr = ["139d2625547dbfa5fb0b81daebb39601c478c21956dc57e2e07b74450a8c506b", "61aa52a0f18b71c5cc58232d2cf8f8d09cd67fcad60b742a60124cb8d6951488"] -pylint = ["3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", "886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"] -pymongo = ["0369136c6e79c5edc16aa5de2b48a1b1c1fe5e6f7fc5915a2deaa98bd6e9dad5", "08364e1bea1507c516b18b826ec790cb90433aec2f235033ec5eecfd1011633b", "0af1d2bc8cc9503bf92ec3669a77ec3a6d7938193b583fb867b7e9696eed52e8", "0cfd1aeeb8c0a634646ab3ebeb4ce6828b94b2e33553a69ff7e6c07c250bf201", "15bbd2b5397f7d22498e2f2769fd698a8a247b9cc1a630ee8dabf647fb333480", "1b4a13dff15641e58620524db15d7a323d60572b2b187261c5cb58c36d74778d", "22fbdb908257f9aaaa372a7684f3e094a05ca52eb84f8f381c8b1827c49556fd", "264272fd1c95fc48002ad85d5e41270831777b4180f2500943e45e12b2a3ab43", "3372e98eebbfd05ebf020388003f8a4438bed41e0fef1ef696d2c13633c416c8", "339d24ecdc42745d2dc09b26fda8151988e806ca81134a7bd10513c4031d91e1", "38281855fc3961ba5510fbb503b8d16cc1fcb326e9f7ba0dd096ed4eb72a7084", "4acdd2e16392472bfd49ca49038845c95e5254b5af862b55f7f2cc79aa258886", "4e0c006bc6e98e861b678432e05bf64ba3eb889b6ab7e7bf1ebaecf9f1ba0e58", "4e4284bcbe4b7be1b37f9641509085b715c478e7fbf8f820358362b5dd359379", "4e5e94a5f9823f0bd0c56012a57650bc6772636c29d83d253260c26b908fcfd9", "4e61f30800a40f1770b2ec56bbf5dc0f0e3f7e9250eb05fa4feb9ccb7bbe39ca", "53577cf57ba9d93b58ab41d45250277828ff83c5286dde14f855e4b17ec19976", "681cb31e8631882804a6cc3c8cc8f54a74ff3a82261a78e50f20c5eec05ac855", "6dfc2710f43dd1d66991a0f160d196356732ccc8aa9dbc6875aeba78388fa142", "72218201b13d8169be5736417987e9a0a3b10d4349e40e4db7a6a5ac670c7ef2", "7247fbcdbf7ab574eb70743461b3cfc14d9cfae3f27a9afb6ce14d87f67dd0b5", "72651f4b4adf50201891580506c8cca465d94d38f26ed92abfc56440662c723c", "87b3aaf12ad6a9b5570b12d2a4b8802757cb3588a903aafd3c25f07f9caf07e3", "87c28b7b37617c5a01eb396487f7d3b61a453e1fa0475a175ab87712d6f5d52f", "88efe627b628f36ef53f09abb218d4630f83d8ebde7028689439559475c43dae", "89bfbca22266f12df7fb80092b7c876734751d02b93789580b68957ad4a8bf56", "908a3caf348a672b28b8a06fe7b4a27c2fdcf7f873df671e4027d48bcd7f971f", "9128e7bea85f3a3041306fa14a7aa82a24b47881918500e1b8396dd1c933b5a6", "9737d6d688a15b8d5c0bfa909638b79261e195be817b9f1be79c722bbb23cd76", "98a8305da158f46e99e7e51db49a2f8b5fcdd7683ea7083988ccb9c4450507a6", "99285cd44c756f0900cbdb5fe75f567c0a76a273b7e0467f23cb76f47e60aac0", "9ed568f8026ffeb00ce31e5351e0d09d704cc19a29549ba4da0ac145d2a26fdf", "a006162035032021dfd00a879643dc06863dac275f9210d843278566c719eebc", "a03cb336bc8d25a11ff33b94967478a9775b0d2b23b39e952d9cc6cb93b75d69", "a863ceb67be163060d1099b7e89b6dd83d6dd50077c7ceae31ac844c4c2baff9", "b82628eaf0a16c1f50e1c205fd1dd406d7874037dd84643da89e91b5043b5e82", "bc6446a41fb7eeaf2c808bab961b9bac81db0f5de69eab74eebe1b8b072399f7", "c42d290ed54096355838421cf9d2a56e150cb533304d2439ef1adf612a986eaf", "c43879fe427ea6aa6e84dae9fbdc5aa14428a4cfe613fe0fee2cc004bf3f307c", "c566cbdd1863ba3ccf838656a1403c3c81fdb57cbe3fdd3515be7c9616763d33", "c5b7a0d7e6ca986de32b269b6dbbd5162c1a776ece72936f55decb4d1b197ee9", "ca109fe9f74da4930590bb589eb8fdf80e5d19f5cd9f337815cac9309bbd0a76", "d0260ba68f9bafd8775b2988b5aeace6e69a37593ec256e23e150c808160c05c", "d12d86e771fc3072a0e6bdbf4e417c63fec85ee47cb052ba7ad239403bf5e154", "d2ce33501149b373118fcfec88a292a87ef0b333fb30c7c6aac72fe64700bdf6", "d582ea8496e2a0e124e927a67dca55c8833f0dbfbc2c84aaf0e5949a2dd30c51", "d68b9ab0a900582a345fb279675b0ad4fac07d6a8c2678f12910d55083b7240d", "dbf1fa571db6006907aeaf6473580aaa76041f4f3cd1ff8a0039fd0f40b83f6d", "e032437a7d2b89dab880c79379d88059cee8019da0ff475d924c4ccab52db88f", "e0f5798f3ad60695465a093e3d002f609c41fef3dcb97fcefae355d24d3274cf", "e756355704a2cf91a7f4a649aa0bbf3bbd263018b9ed08f60198c262f4ee24b6", "e824b4b87bd88cbeb25c8babeadbbaaaf06f02bbb95a93462b7c6193a064974e", "ea1171470b52487152ed8bf27713cc2480dc8b0cd58e282a1bff742541efbfb8", "fa19aef44d5ed8f798a8136ff981aedfa508edac3b1bed481eca5dde5f14fd3d", "faf83d20c041637cb277e5fdb59abc217c40ab3202dd87cc95d6fbd9ce5ffd9b", "fceb6ae5a149a42766efb8344b0df6cfb21b55c55f360170abaddb11d43af0f1"] +parsedatetime = ["4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455", "cb96edd7016872f58479e35879294258c71437195760746faffedb692aef000b"] +pathspec = ["7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", "da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"] +pbr = ["07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c", "579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"] +pylint = ["b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c", "dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b"] +pymongo = ["01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", "0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", "1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", "18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", "19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", "20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", "26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", "26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", "2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", "2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", "316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", "31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", "334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", "358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", "3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", "444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", "47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", "4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", "4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", "53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", "568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", "56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", "5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", "61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", "619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", "6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", "63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", "6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", "7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", "7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", "80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", "95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", "993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", "9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", "a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", "a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", "a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", "a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", "a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", "ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", "ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", "b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", "b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", "bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", "bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", "c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", "c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", "c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", "c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", "da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", "dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", "e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", "e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", "e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", "f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", "f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606"] python-dateutil = ["73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"] -python-dotenv = ["debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", "f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544"] -pyyaml = ["0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc", "2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803", "35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc", "38a4f0d114101c58c0f3a88aeaa44d63efd588845c5a2df5290b73db8f246d15", "483eb6a33b671408c8529106df3707270bfacb2447bf8ad856a4b4f57f6e3075", "4b6be5edb9f6bb73680f5bf4ee08ff25416d1400fbd4535fe0069b2994da07cd", "7f38e35c00e160db592091751d385cd7b3046d6d51f578b29943225178257b31", "8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f", "c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c", "e4c015484ff0ff197564917b4b4246ca03f411b9bd7f16e02a2f586eb48b6d04", "ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4"] -six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] -smmap2 = ["0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde", "29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a"] -stevedore = ["01d9f4beecf0fbd070ddb18e5efb10567801ba7ef3ddab0074f54e3cd4e91730", "e0739f9739a681c7a1fda76a102b65295e96a144ccdb552f2ae03c5f0abe8a14"] -toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"] -typed-ast = ["1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", "48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", "7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", "838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", "fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"] +python-dotenv = ["440c7c23d53b7d352f9c94d6f70860242c2f071cf5c029dd661ccb22d64ae42b", "f254bfd0c970d64ccbb6c9ebef3667ab301a71473569c991253a481f1c98dddc"] +pyyaml = ["06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", "240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", "4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", "69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", "73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", "74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", "7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", "95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", "b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", "cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", "d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"] +regex = ["150125da109fccdcc8fec3b0b386b2a5d6ca7cff076f8b622486d1ca868b0c10", "163bc0805e46acfa098dfc8c0b07f371577d505f603e48afc425ff475cdac3a5", "20c513893ff80bdbe4b4ce11ea2e93d49481f05b270595d82af69ffc402010a6", "21fc17cb868c4264f0813f992f46f9ae6fc8c309d4741091de4153bd1f6a6176", "2c928bc8e0c453d73dffa3193a6e37ee752ea36df0dd4601e21024d98274dfad", "2d9beca70e36f9c60d679e108c5fe49f3d4da79d13a13f91e5e759443bd954f9", "5735f26cacdb50b3d6d35ebf8fdeb504bd8b381e2d079d2d9f12ce534fc14ecd", "6edc5c190248d3b612f2cca45448cf8ebc3621d41afcd1c5708853cbb1dbb3b3", "7606dba82435429641efe4fbc580574942f89cf2b9c5c1f8bc1eab2bacbf7e8b", "8d1ee3796795e609ef7a3a5a35eaf4728038d986aa12c06b3fd1b92ee81911f4", "8d9bb2d90e23c51aacbc58c1a11320f49b335cd67a91986cdbebcc3e843e4de8", "97d414c41f19fd2362e493810caa8445c05e0a2d63a14081c972aad66284a8d2", "9e37502817225ee99d91d8418f5119e98c380b00e772d06915690c05290f32ee", "af7209b2fcc79ee2b0ad4ea080d70bb748450ec4f282cc9e864861e469b1072e", "c0849b0864ff451f04c8afb5fc28e9ed592262e03debdd227cf0f53e04a55dcd", "c4ac9215650688e78dea29b46adbdafb7b85058eebe92ef6ea848e14466c915f", "dcda6d4e1bbfc939b177c237aee41c9678eaaf71df482688f8986e8251e12345", "dd8501b8d9ea1aba53c4bc7d47bc72933f9b4213d534cf400f16c1431f51c8ba", "ec0e509ed1877ff1cbc6f0864689bb60384a303502c4d72d9a635f8a4676fd3f", "f6c8c3f56fef719180464855346e6e80971b86dfd9e5a0e356664b5baca53072", "ffd4f80602490a309064cf2b203e220d581c51660e01055c64bf5da450485ee6"] +six = ["30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"] +smmap = ["54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"] +stevedore = ["001e90cd704be6470d46cc9076434e2d0d566c1379187e7013eb296d3a6032d9", "471c920412265cc809540ae6fb01f3f02aba89c79bbc7091372f4745a50f9691"] +toml = ["926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", "bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"] +typed-ast = ["0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", "0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", "249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", "24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", "269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", "4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", "498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", "4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", "6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", "715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", "73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", "8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", "8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", "aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", "bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", "c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", "d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", "d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", "d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", "fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", "fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"] uvloop = ["08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", "123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", "4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", "4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", "afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", "b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", "bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", "e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"] -websockets = ["0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136", "2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6", "5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1", "5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538", "669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4", "695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908", "6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0", "79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d", "7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c", "82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d", "8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c", "91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb", "952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf", "99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e", "9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96", "a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584", "cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484", "e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d", "e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559", "ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff", "f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"] -wrapt = ["565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"] +websockets = ["0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", "1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", "20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", "295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", "2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", "3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", "3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", "3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", "4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", "5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", "5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", "751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", "7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", "965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", "9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", "9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", "c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", "c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", "ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", "d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", "e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", "f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"] +wrapt = ["b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"] yarl = ["0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", "0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", "2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", "25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", "26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", "308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", "3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", "58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", "5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", "6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", "944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", "a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", "a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", "c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", "c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", "d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", "e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"] diff --git a/pyproject.toml b/pyproject.toml index 9c7122c417..0d47eb844a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 99 -target-version = ['py36'] +target-version = ['py37'] include = '\.pyi?$' exclude = ''' ( @@ -21,8 +21,8 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.5.0-dev0' -description = 'Modmail is similar to Reddits Modmail both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way.' +version = '3.6.0' +description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ 'kyb3r ', @@ -36,10 +36,10 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "=1.2.5" -uvloop = "^0.14.0" -python-dotenv = "^0.10.3" -parsedatetime = "^2.5" +"discord.py" = "=1.5.1" +uvloop = {version = ">=0.12.0", markers = "sys_platform != 'win32'"} +python-dotenv = ">=0.10.3" +parsedatetime = "^2.6" dnspython = "^1.16" isodate = "^0.6.0" natural = "^0.2.0" @@ -47,10 +47,12 @@ motor = {version = "^2.1", optional = true} emoji = "^0.5.4" python-dateutil = "^2.8" colorama = "^0.4.3" -aiohttp = "<3.6.0,>=3.3.0" +aiohttp = ">=3.6.0,<3.7.0" [tool.poetry.dev-dependencies] -black = {version = "=19.3b0", allows-prereleases = true} +black = {version = "=19.10b0", allow-prereleases = true} pylint = "^2.4" bandit = "^1.6" +[tool.poetry.extras] +mongodb = ["motor"] diff --git a/requirements.min.txt b/requirements.min.txt index dded194188..9fd4adf1a3 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -1,24 +1,24 @@ -# Generated as of October, 2019 +# Generated as of June, 2020 # This is the bare minimum requirements.txt for running Modmail. # To install requirements.txt run: pip install -r requirements.min.txt -aiohttp==3.5.4 +aiohttp==3.6.2 async-timeout==3.0.1 attrs==19.3.0 chardet==3.0.4 -discord.py==1.2.5 +discord.py==1.5.1 dnspython==1.16.0 emoji==0.5.4 -future==0.18.1 -idna==2.8 +future==0.18.2 +idna==2.9 isodate==0.6.0 -motor==2.0.0 -multidict==4.5.2 +motor==2.1.0 +multidict==4.7.6 natural==0.2.0 -parsedatetime==2.4 -pymongo==3.9.0 -python-dateutil==2.8.0 -python-dotenv==0.10.3 -six==1.12.0 -websockets==6.0 -yarl==1.3.0 +parsedatetime==2.6 +pymongo==3.10.1 +python-dateutil==2.8.1 +python-dotenv==0.14.0 +six==1.15.0 +websockets==8.1 +yarl==1.4.2 diff --git a/runtime.txt b/runtime.txt index aefcfbece7..67068f10fe 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.5 +python-3.9.0 \ No newline at end of file diff --git a/translation_files.py b/translation_files.py deleted file mode 100644 index 07c6979f63..0000000000 --- a/translation_files.py +++ /dev/null @@ -1,127 +0,0 @@ -import csv -import glob -import re -import string - -from discord.ext import commands - -from core import translations -from cogs.modmail import Modmail -from cogs.plugins import Plugins -from cogs.utility import Utility - - -data = [("Identifier", "English", "Context")] -all_identifiers = [] -identifiers = {} - - -class FormatError(Exception): - def __init__(self, reason, string): - super().__init__(f"Unable to parse {reason}: {string}") - - -for filename in glob.glob("**/*.py") + glob.glob("*.py"): - if filename == "translation_files.py": - continue - with open(filename, encoding="utf8") as f: - filedata = f.read() - regex_matches = re.findall( - r"(?:^|[^A-z])_\(.+?(?:\'|\")\)+?", filedata, flags=re.DOTALL | re.MULTILINE - ) - - for i in regex_matches: - if "f'" in i or 'f"' in i: - print(FormatError("f-string", i)) - identifier = "" - read = False - ignore_inverted = False - newline = False - counter = 0 - mode = None - for n in range(len(i)): - triggered = False - x = i[n] - - if x in ("'", '"') and not ignore_inverted: - if not mode: - mode = x - if mode == x: - read = not read - triggered = True - - if x == "\n": - newline = True - - if read and not triggered: - newline = False - identifier += x - - if newline and x not in string.whitespace: - counter += 1 - if counter > 1: - break - else: - counter = 0 - - if x == "\\": - ignore_inverted = True - elif ignore_inverted: - ignore_inverted = False - - all_identifiers.append(identifier) - - filedata_lines = filedata.splitlines() - fullline = list(filter((lambda x: x.find(i.splitlines()[0]) != -1), filedata_lines))[0] - count = 0 - for nline, line in enumerate(filedata_lines): - if line == fullline: - count += 1 - if count == all_identifiers.count(identifier): - linenum = nline + 1 - break - - if identifier in identifiers.keys(): - if filename not in data[identifiers[identifier]][2]: - data[identifiers[identifier]][2] += f" {filename}/L{linenum}" - elif str(linenum) not in data[identifiers[identifier]][2]: - split_space = data[identifiers[identifier]][2].split(" ") - for nx, x in enumerate(split_space): - if filename in x: - split_space[nx] += f"/L{linenum}" - break - data[identifiers[identifier]][2] = (" ").join(split_space) - else: - data.append([identifier, identifier, f"File: {filename}/L{linenum}"]) - identifiers[identifier] = len(data) - 1 - - print(filename) - -translations.init() -done = set() -bot = commands.Bot(command_prefix=None) -cogs = [Modmail(bot), Plugins(bot), Utility(bot)] -for i in cogs: - if i.description: - data.append([i.description, i.description, f"Cog: {i.__cog_name__}"]) - - for cmd in i.walk_commands(): - if cmd not in done: - if cmd.short_doc: - print(cmd) - data.append( - [ - cmd.short_doc, - cmd.short_doc, - f"Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}", - ] - ) - data.append( - [cmd.help, cmd.help, f"Cog: {i.__cog_name__}\nCommand: {cmd.qualified_name}"] - ) - - done.add(cmd) - - -with open("languages/en.csv", "w+") as f: - csv.writer(f, dialect="unix").writerows(data) From 3cfba283e885e6bd58b313664b9ace27feee9cc8 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 4 Nov 2020 23:54:35 +0800 Subject: [PATCH 105/705] Plain replies (#2872) --- CHANGELOG.md | 5 ++++- bot.py | 17 +++++++++++++---- cogs/modmail.py | 28 ++++++++++++++++++++++++++++ cogs/plugins.py | 6 +++--- core/config.py | 2 ++ core/config_help.json | 15 +++++++++++++-- core/thread.py | 40 ++++++++++++++++++++++++++++++++++++---- 7 files changed, 99 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b9d415b2..7b9260338d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.6.3-dev0 +# v3.6.3-dev1 + +### Added +- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. ### Improved diff --git a/bot.py b/bot.py index ab5ded6c53..b442e89a25 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.6.3-dev0" +__version__ = "3.6.3-dev1" import asyncio @@ -896,10 +896,19 @@ async def process_commands(self, message): thread = await self.threads.find(channel=ctx.channel) if thread is not None: + anonymous = False + plain = False if self.config.get("anon_reply_without_command"): - await thread.reply(message, anonymous=True) - elif self.config.get("reply_without_command"): - await thread.reply(message) + anonymous = True + if self.config.get("plain_reply_without_command"): + plain = True + + if ( + self.config.get("reply_without_command") + or self.config.get("anon_reply_without_command") + or self.config.get("plain_reply_without_command") + ): + await thread.reply(message, anonymous=anonymous, plain=plain) else: await self.api.append_log(message, type_="internal") elif ctx.invoked_with: diff --git a/cogs/modmail.py b/cogs/modmail.py index 44f0e9dcde..4745ccd448 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -831,6 +831,34 @@ async def areply(self, ctx, *, msg: str = ""): async with ctx.typing(): await ctx.thread.reply(ctx.message, anonymous=True) + @commands.command(aliases=["plainreply"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def preply(self, ctx, *, msg: str = ""): + """ + Reply to a Modmail thread with a plain message. + + Supports attachments and images as well as + automatically embedding image URLs. + """ + ctx.message.content = msg + async with ctx.typing(): + await ctx.thread.reply(ctx.message, plain=True) + + @commands.command(aliases=["plainanonreply", "plainanonymousreply"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def pareply(self, ctx, *, msg: str = ""): + """ + Reply to a Modmail thread with a plain message and anonmymously. + + Supports attachments and images as well as + automatically embedding image URLs. + """ + ctx.message.content = msg + async with ctx.typing(): + await ctx.thread.reply(ctx.message, anonymous=True, plain=True) + @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() diff --git a/cogs/plugins.py b/cogs/plugins.py index 227cfc8270..e85907838f 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -172,10 +172,10 @@ async def download_plugin(self, plugin, force=False): except UnicodeDecodeError: pass else: - if raw == 'Not Found': - raise InvalidPluginError('Plugin not found') + if raw == "Not Found": + raise InvalidPluginError("Plugin not found") else: - raise InvalidPluginError('Invalid download recieved, non-bytes object') + raise InvalidPluginError("Invalid download recieved, non-bytes object") plugin_io = io.BytesIO(raw) if not plugin.cache_path.parent.exists(): diff --git a/core/config.py b/core/config.py index f2bb54a5c8..61f3b1ed5c 100644 --- a/core/config.py +++ b/core/config.py @@ -39,6 +39,7 @@ class ConfigManager: "thread_cooldown": isodate.Duration(), "reply_without_command": False, "anon_reply_without_command": False, + "plain_reply_without_command": False, # logging "log_channel_id": None, # threads @@ -130,6 +131,7 @@ class ConfigManager: "mod_typing", "reply_without_command", "anon_reply_without_command", + "plain_reply_without_command", "recipient_thread_close", "thread_auto_close_silently", "thread_move_notify", diff --git a/core/config_help.json b/core/config_help.json index 9778f49f8c..2466de613c 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -139,7 +139,7 @@ "`{prefix}config set reply_without_command no`" ], "notes": [ - "See also: `anon_reply_without_command`." + "See also: `anon_reply_without_command`, `plain_reply_without_command`." ] }, "anon_reply_without_command": { @@ -150,7 +150,18 @@ "`{prefix}config set anon_reply_without_command no`" ], "notes": [ - "See also: `reply_without_command`." + "See also: `reply_without_command`, `plain_reply_without_command`." + ] + }, + "plain_reply_without_command": { + "default": "Disabled", + "description": "Setting this configuration will make all non-command messages sent in the thread channel to be forwarded to the recipient in a plain form without the need of `{prefix}reply`.", + "examples": [ + "`{prefix}config set plain_reply_without_command yes`", + "`{prefix}config set plain_reply_without_command no`" + ], + "notes": [ + "See also: `reply_without_command`, `anon_reply_without_command`." ] }, "log_channel_id": { diff --git a/core/thread.py b/core/thread.py index 9c388389e0..adbfed2e67 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1,4 +1,5 @@ import asyncio +import io import re import typing from datetime import datetime, timedelta @@ -619,7 +620,9 @@ async def note(self, message: discord.Message) -> None: return msg - async def reply(self, message: discord.Message, anonymous: bool = False) -> None: + async def reply( + self, message: discord.Message, anonymous: bool = False, plain: bool = False + ) -> None: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): @@ -635,7 +638,11 @@ async def reply(self, message: discord.Message, anonymous: bool = False) -> None try: await self.send( - message, destination=self.recipient, from_mod=True, anonymous=anonymous + message, + destination=self.recipient, + from_mod=True, + anonymous=anonymous, + plain=plain, ) except Exception: logger.error("Message delivery failed:", exc_info=True) @@ -653,7 +660,7 @@ async def reply(self, message: discord.Message, anonymous: bool = False) -> None else: # Send the same thing in the thread channel. msg = await self.send( - message, destination=self.channel, from_mod=True, anonymous=anonymous + message, destination=self.channel, from_mod=True, anonymous=anonymous, plain=plain ) tasks.append( @@ -688,6 +695,7 @@ async def send( from_mod: bool = False, note: bool = False, anonymous: bool = False, + plain: bool = False, ) -> None: self.bot.loop.create_task( @@ -851,7 +859,31 @@ async def send( else: mentions = None - msg = await destination.send(mentions, embed=embed) + if plain: + if from_mod and not isinstance(destination, discord.TextChannel): + # Plain to user + if embed.footer.text: + plain_message = f"**({embed.footer.text}) " + else: + plain_message = "**" + plain_message += f"{embed.author.name}:** {embed.description}" + files = [] + for i in embed.fields: + if "Image" in i.name: + async with self.bot.session.get( + i.field[i.field.find("http") : -1] + ) as resp: + stream = io.BytesIO(await resp.read()) + files.append(discord.File(stream)) + + msg = await destination.send(plain_message, files=files) + else: + # Plain to mods + embed.set_footer(text="[PLAIN] " + embed.footer.text) + msg = await destination.send(mentions, embed=embed) + + else: + msg = await destination.send(mentions, embed=embed) if additional_images: self.ready = False From feebbefe918d05fe2ca7a06b5e6b0576d7130ea6 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 00:38:02 +0800 Subject: [PATCH 106/705] React to start thread --- CHANGELOG.md | 8 +++++++- cogs/modmail.py | 45 +++++++++++++++++++++++++++++++++++++------ core/config.py | 3 +++ core/config_help.json | 20 +++++++++++++++++++ 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b9260338d..b2b6eac90c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,13 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v3.6.3-dev1 ### Added -- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. + +- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. ([#2872](https://github.com/kyb3r/modmail/issues/2872)) +- React to start a thread, added configs `react_to_contact_message`, `react_to_contact_emoji`. + +### Fixed + +- `?contact` now sends members a DM ### Improved diff --git a/cogs/modmail.py b/cogs/modmail.py index 4745ccd448..a5b79fe0c9 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -909,6 +909,7 @@ async def contact( user: Union[discord.Member, discord.User], *, category: discord.CategoryChannel = None, + manual_trigger = True ): """ Create a thread with a specified member. @@ -924,7 +925,7 @@ async def contact( embed = discord.Embed( color=self.bot.error_color, description="Cannot start a thread with a bot." ) - return await ctx.send(embed=embed) + return await ctx.send(embed=embed, delete_afer=3) exists = await self.bot.threads.find(recipient=user) if exists: @@ -933,13 +934,21 @@ async def contact( description="A thread for this user already " f"exists in {exists.channel.mention}.", ) - await ctx.channel.send(embed=embed) + await ctx.channel.send(embed=embed, delete_after=3) else: thread = await self.bot.threads.create(user, creator=ctx.author, category=category) if self.bot.config["dm_disabled"] >= 1: logger.info("Contacting user %s when Modmail DM is disabled.", user) + if ctx.author.id == user.id: + description = "You have opened a Modmail thread." + else: + description = f"{ctx.author.name} has opened a Modmail thread." + em = discord.Embed(title="New Thread", description=description, color=self.bot.main_color, timestamp=datetime.utcnow()) + em.set_footer(icon_url=ctx.author.avatar_url) + await user.send(embed=em) + embed = discord.Embed( title="Created Thread", description=f"Thread started by {ctx.author.mention} for {user.mention}.", @@ -947,10 +956,34 @@ async def contact( ) await thread.wait_until_ready() await thread.channel.send(embed=embed) - sent_emoji, _ = await self.bot.retrieve_emoji() - await self.bot.add_reaction(ctx.message, sent_emoji) - await asyncio.sleep(3) - await ctx.message.delete() + + if manual_trigger: + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + await asyncio.sleep(5) + await ctx.message.delete() + + @commands.Cog.listener() + async def on_raw_reaction_add(self, payload): + react_message_id = int(self.bot.config.get("react_to_contact_message")) + react_message_emoji = self.bot.config.get("react_to_contact_emoji") + if all((react_message_id, react_message_emoji)): + if payload.message_id == react_message_id: + if payload.emoji.is_unicode_emoji(): + emoji_fmt = payload.emoji.name + else: + emoji_fmt = f'<:{payload.emoji.name}:{payload.emoji.id}>' + + if emoji_fmt == react_message_emoji: + channel = self.bot.get_channel(payload.channel_id) + member = channel.guild.get_member(payload.user_id) + message = await channel.fetch_message(payload.message_id) + await message.remove_reaction(payload.emoji, member) + + ctx = await self.bot.get_context(message) + ctx.author = member + await ctx.invoke(self.contact, user=member, manual_trigger=False) + @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.MODERATOR) diff --git a/core/config.py b/core/config.py index 61f3b1ed5c..528b22c483 100644 --- a/core/config.py +++ b/core/config.py @@ -75,6 +75,9 @@ class ConfigManager: "anon_username": None, "anon_avatar_url": None, "anon_tag": "Response", + # react to contact + "react_to_contact_message": None, + "react_to_contact_emoji": "\u2705", } private_keys = { diff --git a/core/config_help.json b/core/config_help.json index 2466de613c..a444f8a4ac 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -533,6 +533,26 @@ ], "image": "https://i.imgur.com/SKOC42Z.png" }, + "react_to_contact_message": { + "default": "None", + "description": "A message ID where reactions are tracked. If the `react_to_contact_emoji` is added, the bot opens a thread with them.", + "examples": [ + "`{prefix}config set react_to_contact_message 773575608814534717`" + ], + "notes": [ + "See also: `react_to_contact_emoji`" + ] + }, + "react_to_contact_emoji": { + "default": "\u2705", + "description": "An emoji which is tracked in `react_to_contact_message`", + "examples": [ + "`{prefix}config set react_to_contact_emoji 773575608814534717`" + ], + "notes": [ + "See also: `react_to_contact_message \u2705`" + ] + }, "modmail_guild_id": { "default": "Fallback on `GUILD_ID`", "description": "The ID of the discord server where the threads channels should be created (receiving server).", From edd37365ae3afe41c0967bb76b7d9c72affe9d10 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 00:46:39 +0800 Subject: [PATCH 107/705] Add config to mention mods after move , resolve #215 --- CHANGELOG.md | 3 ++- cogs/modmail.py | 5 +++++ core/config.py | 2 ++ core/config_help.json | 15 +++++++++++++-- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2b6eac90c..ca5739d8b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added -- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. ([#2872](https://github.com/kyb3r/modmail/issues/2872)) +- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. ([GH#2872](https://github.com/kyb3r/modmail/issues/2872)) - React to start a thread, added configs `react_to_contact_message`, `react_to_contact_emoji`. +- Mention mods after move: added config `thread_move_notify_mods` ([GH#215](https://github.com/kyb3r/modmail/issues/215)) ### Fixed diff --git a/cogs/modmail.py b/cogs/modmail.py index a5b79fe0c9..b19edd9f69 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -332,6 +332,11 @@ async def move(self, ctx, *, arguments): ) await thread.recipient.send(embed=embed) + if self.bot.config["thread_move_notify_mods"]: + mention = self.bot.config["mention"] + await thread.channel.send(f'{mention}, thread has been moved.') + + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) diff --git a/core/config.py b/core/config.py index 528b22c483..51efd82e48 100644 --- a/core/config.py +++ b/core/config.py @@ -60,6 +60,7 @@ class ConfigManager: "thread_self_close_response": "You have closed this Modmail thread.", "thread_move_title": "Thread Moved", "thread_move_notify": False, + "thread_move_notify_mods": False, "thread_move_response": "This thread has been moved.", "disabled_new_thread_title": "Not Delivered", "disabled_new_thread_response": "We are not accepting new threads.", @@ -138,6 +139,7 @@ class ConfigManager: "recipient_thread_close", "thread_auto_close_silently", "thread_move_notify", + "thread_move_notify_mods", "enable_plugins", "enable_eval", } diff --git a/core/config_help.json b/core/config_help.json index a444f8a4ac..ab97ba13cf 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -368,7 +368,7 @@ "`{prefix}config set thread_move_title Thread transferred to another channel!" ], "notes": [ - "See also: `thread_move_notify`, `thread_move_response`." + "See also: `thread_move_notify`, `thread_move_notify_mods`, `thread_move_response`." ] }, "thread_move_notify": { @@ -379,7 +379,18 @@ "`{prefix}config set thread_move_notify no`" ], "notes": [ - "See also: `thread_move_title`, `thread_move_response`." + "See also: `thread_move_title`, `thread_move_response`, `thread_move_notify_mods`." + ] + }, + "thread_move_notify_mods": { + "default": "No", + "description": "Notify mods again after the thread is moved", + "examples": [ + "`{prefix}config set thread_move_notify_mods yes`", + "`{prefix}config set thread_move_notify_mods no`" + ], + "notes": [ + "See also: `thread_move_title`, `thread_move_response`, `thread_move_notify`." ] }, "thread_move_response": { From 306a158bc69e55008354238671149eb45e5e466b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 00:56:51 +0800 Subject: [PATCH 108/705] transfer reactions config var, resolve #2783 --- CHANGELOG.md | 5 +++-- bot.py | 6 ++++-- core/config.py | 2 ++ core/config_help.json | 10 +++++++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca5739d8b0..ffe2d03e03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,10 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added -- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. ([GH#2872](https://github.com/kyb3r/modmail/issues/2872)) +- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. ([GH #2872](https://github.com/kyb3r/modmail/issues/2872)) - React to start a thread, added configs `react_to_contact_message`, `react_to_contact_emoji`. -- Mention mods after move: added config `thread_move_notify_mods` ([GH#215](https://github.com/kyb3r/modmail/issues/215)) +- Mention mods after move: added config `thread_move_notify_mods` ([GH #215](https://github.com/kyb3r/modmail/issues/215)) +- Added `transfer_reactions` config var ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) ### Fixed diff --git a/bot.py b/bot.py index b442e89a25..de5b7c7672 100644 --- a/bot.py +++ b/bot.py @@ -1009,10 +1009,12 @@ async def handle_reaction_events(self, payload): logger.warning("Failed to remove reaction: %s", e) async def on_raw_reaction_add(self, payload): - await self.handle_reaction_events(payload) + if self.config["transfer_reactions"]: + await self.handle_reaction_events(payload) async def on_raw_reaction_remove(self, payload): - await self.handle_reaction_events(payload) + if self.config["transfer_reactions"]: + await self.handle_reaction_events(payload) async def on_guild_channel_delete(self, channel): if channel.guild != self.modmail_guild: diff --git a/core/config.py b/core/config.py index 51efd82e48..e376d2048e 100644 --- a/core/config.py +++ b/core/config.py @@ -68,6 +68,7 @@ class ConfigManager: "disabled_current_thread_title": "Not Delivered", "disabled_current_thread_response": "We are not accepting any messages.", "disabled_current_thread_footer": "Please try again later...", + "transfer_reactions": True, # moderation "recipient_color": str(discord.Color.gold()), "mod_color": str(discord.Color.green()), @@ -140,6 +141,7 @@ class ConfigManager: "thread_auto_close_silently", "thread_move_notify", "thread_move_notify_mods", + "transfer_reactions", "enable_plugins", "enable_eval", } diff --git a/core/config_help.json b/core/config_help.json index ab97ba13cf..0c2f68e579 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -558,12 +558,20 @@ "default": "\u2705", "description": "An emoji which is tracked in `react_to_contact_message`", "examples": [ - "`{prefix}config set react_to_contact_emoji 773575608814534717`" + "`{prefix}config set react_to_contact_emoji \u2705`" ], "notes": [ "See also: `react_to_contact_message \u2705`" ] }, + "transfer_reactions": { + "default": "Yes", + "description": "Transfer users reactions to mods and vice versa", + "examples":[ + "`{prefix}config set transfer_reactions no" + ], + "notes": [] + }, "modmail_guild_id": { "default": "Fallback on `GUILD_ID`", "description": "The ID of the discord server where the threads channels should be created (receiving server).", From d0bcaf16776c5f22cd0da6026cd8be062de04ba7 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 01:08:21 +0800 Subject: [PATCH 109/705] close_on_leave config, resolves #2757 --- bot.py | 11 +++++++---- core/config.py | 2 ++ core/config_help.json | 8 ++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/bot.py b/bot.py index de5b7c7672..80c6b6597f 100644 --- a/bot.py +++ b/bot.py @@ -1059,10 +1059,13 @@ async def on_member_remove(self, member): return thread = await self.threads.find(recipient=member) if thread: - embed = discord.Embed( - description="The recipient has left the server.", color=self.error_color - ) - await thread.channel.send(embed=embed) + if self.config["close_on_leave"]: + await thread.close(closer=member.guild.me, message="The recipient has left the server.", silent=True) + else: + embed = discord.Embed( + description="The recipient has left the server.", color=self.error_color + ) + await thread.channel.send(embed=embed) async def on_member_join(self, member): if member.guild != self.guild: diff --git a/core/config.py b/core/config.py index e376d2048e..132ac27ee0 100644 --- a/core/config.py +++ b/core/config.py @@ -69,6 +69,7 @@ class ConfigManager: "disabled_current_thread_response": "We are not accepting any messages.", "disabled_current_thread_footer": "Please try again later...", "transfer_reactions": True, + "close_on_leave": False, # moderation "recipient_color": str(discord.Color.gold()), "mod_color": str(discord.Color.green()), @@ -142,6 +143,7 @@ class ConfigManager: "thread_move_notify", "thread_move_notify_mods", "transfer_reactions", + "close_on_leave", "enable_plugins", "enable_eval", } diff --git a/core/config_help.json b/core/config_help.json index 0c2f68e579..b8c626b4b8 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -572,6 +572,14 @@ ], "notes": [] }, + "close_on_leave": { + "default": "No", + "description": "Closes a modmail thread upon user leave automatically", + "examples":[ + "`{prefix}config set close_on_leave yes" + ], + "notes": [] + }, "modmail_guild_id": { "default": "Fallback on `GUILD_ID`", "description": "The ID of the discord server where the threads channels should be created (receiving server).", From 90e11cae82ab63844c8adbab06760ba03ecc2f16 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 01:11:30 +0800 Subject: [PATCH 110/705] Formatting --- CHANGELOG.md | 13 +++++++------ bot.py | 6 +++++- cogs/modmail.py | 15 +++++++++------ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffe2d03e03..1132d2b0f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,14 +10,15 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added -- Plain replies: added commands `preply`, `pareply`, added config `plain_reply_without_command`. Only works from mod to users. ([GH #2872](https://github.com/kyb3r/modmail/issues/2872)) -- React to start a thread, added configs `react_to_contact_message`, `react_to_contact_emoji`. -- Mention mods after move: added config `thread_move_notify_mods` ([GH #215](https://github.com/kyb3r/modmail/issues/215)) -- Added `transfer_reactions` config var ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) +- Plain replies functionality. Added commands `preply`, `pareply` and config `plain_reply_without_command`. ([GH #2872](https://github.com/kyb3r/modmail/issues/2872)) +- Added `react_to_contact_message`, `react_to_contact_emoji` to allow users to create threads by reacting to a message. +- Added `thread_move_notify_mods` to mention all mods again after moving thread. ([GH #215](https://github.com/kyb3r/modmail/issues/215)) +- Added `transfer_reactions` to link reactions between mods and users. ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) +- Added `close_on_leave` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) ### Fixed -- `?contact` now sends members a DM +- `?contact` now sends members a DM. ### Improved @@ -27,7 +28,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed -- Plugins downloading requirements in virtual environments +- Plugins downloading requirements in virtual environments. # v3.6.1 diff --git a/bot.py b/bot.py index 80c6b6597f..6613735843 100644 --- a/bot.py +++ b/bot.py @@ -1060,7 +1060,11 @@ async def on_member_remove(self, member): thread = await self.threads.find(recipient=member) if thread: if self.config["close_on_leave"]: - await thread.close(closer=member.guild.me, message="The recipient has left the server.", silent=True) + await thread.close( + closer=member.guild.me, + message="The recipient has left the server.", + silent=True, + ) else: embed = discord.Embed( description="The recipient has left the server.", color=self.error_color diff --git a/cogs/modmail.py b/cogs/modmail.py index b19edd9f69..73445ecba0 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -334,8 +334,7 @@ async def move(self, ctx, *, arguments): if self.bot.config["thread_move_notify_mods"]: mention = self.bot.config["mention"] - await thread.channel.send(f'{mention}, thread has been moved.') - + await thread.channel.send(f"{mention}, thread has been moved.") sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -914,7 +913,7 @@ async def contact( user: Union[discord.Member, discord.User], *, category: discord.CategoryChannel = None, - manual_trigger = True + manual_trigger=True, ): """ Create a thread with a specified member. @@ -950,7 +949,12 @@ async def contact( description = "You have opened a Modmail thread." else: description = f"{ctx.author.name} has opened a Modmail thread." - em = discord.Embed(title="New Thread", description=description, color=self.bot.main_color, timestamp=datetime.utcnow()) + em = discord.Embed( + title="New Thread", + description=description, + color=self.bot.main_color, + timestamp=datetime.utcnow(), + ) em.set_footer(icon_url=ctx.author.avatar_url) await user.send(embed=em) @@ -977,7 +981,7 @@ async def on_raw_reaction_add(self, payload): if payload.emoji.is_unicode_emoji(): emoji_fmt = payload.emoji.name else: - emoji_fmt = f'<:{payload.emoji.name}:{payload.emoji.id}>' + emoji_fmt = f"<:{payload.emoji.name}:{payload.emoji.id}>" if emoji_fmt == react_message_emoji: channel = self.bot.get_channel(payload.channel_id) @@ -989,7 +993,6 @@ async def on_raw_reaction_add(self, payload): ctx.author = member await ctx.invoke(self.contact, user=member, manual_trigger=False) - @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.MODERATOR) @trigger_typing From 9f8d8741c9f470ff54029ba8dd3fa7bb59851d8e Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 14:04:29 +0800 Subject: [PATCH 111/705] Added alert_on_mention, resolve #2833 --- CHANGELOG.md | 1 + bot.py | 18 ++++++++++++++++++ core/config.py | 2 ++ core/config_help.json | 10 ++++++++++ 4 files changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1132d2b0f0..f159aa15a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `thread_move_notify_mods` to mention all mods again after moving thread. ([GH #215](https://github.com/kyb3r/modmail/issues/215)) - Added `transfer_reactions` to link reactions between mods and users. ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) - Added `close_on_leave` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) +- Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/kyb3r/modmail/issues/2833)) ### Fixed diff --git a/bot.py b/bot.py index 6613735843..5642cb21ce 100644 --- a/bot.py +++ b/bot.py @@ -862,6 +862,24 @@ async def on_message(self, message): await self.wait_for_connected() if message.type == discord.MessageType.pins_add and message.author == self.user: await message.delete() + + if ( + (f"<@{self.user.id}" in message.content or f"<@!{self.user.id}" in message.content) + and self.config["alert_on_mention"] + and not message.author.bot + ): + if len(message.content) > 50: + extra = "..." + else: + extra = "" + em = discord.Embed( + title="Bot mention", + description=f"[Jump URL]({message.jump_url})\n{message.content[:50]}{extra}", + color=self.main_color, + timestamp=datetime.utcnow(), + ) + await self.log_channel.send(content=self.config["mention"], embed=em) + await self.process_commands(message) async def process_commands(self, message): diff --git a/core/config.py b/core/config.py index 132ac27ee0..936278d67b 100644 --- a/core/config.py +++ b/core/config.py @@ -70,6 +70,7 @@ class ConfigManager: "disabled_current_thread_footer": "Please try again later...", "transfer_reactions": True, "close_on_leave": False, + "alert_on_mention": False, # moderation "recipient_color": str(discord.Color.gold()), "mod_color": str(discord.Color.green()), @@ -144,6 +145,7 @@ class ConfigManager: "thread_move_notify_mods", "transfer_reactions", "close_on_leave", + "alert_on_mention", "enable_plugins", "enable_eval", } diff --git a/core/config_help.json b/core/config_help.json index b8c626b4b8..acb2834e53 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -580,6 +580,16 @@ ], "notes": [] }, + "alert_on_mention": { + "default": "No", + "description": "Mentions all mods (mention) in logs channel when bot is mentioned", + "examples":[ + "`{prefix}config set alert_on_mention yes" + ], + "notes": [ + "See also: `mention`" + ] + }, "modmail_guild_id": { "default": "Fallback on `GUILD_ID`", "description": "The ID of the discord server where the threads channels should be created (receiving server).", From 5cb85a22ab929405b31f3f0b7b5df1c4a0b3d529 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 15:27:41 +0800 Subject: [PATCH 112/705] Added confirm thread creation, resolve #2773 --- CHANGELOG.md | 1 + bot.py | 17 ++--- core/config.py | 7 ++ core/config_help.json | 50 ++++++++++++++ core/thread.py | 150 ++++++++++++++++++++++++++++++++---------- 5 files changed, 183 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f159aa15a1..839c915071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `transfer_reactions` to link reactions between mods and users. ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) - Added `close_on_leave` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) - Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/kyb3r/modmail/issues/2833)) +- Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) ### Fixed diff --git a/bot.py b/bot.py index 5642cb21ce..82344544c9 100644 --- a/bot.py +++ b/bot.py @@ -738,7 +738,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) - thread = await self.threads.create(message.author) + thread = await self.threads.create(message.author, message=message) else: if self.config["dm_disabled"] == 2: embed = discord.Embed( @@ -756,13 +756,14 @@ async def process_dm_modmail(self, message: discord.Message) -> None: await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) - try: - await thread.send(message) - except Exception: - logger.error("Failed to send message:", exc_info=True) - await self.add_reaction(message, blocked_emoji) - else: - await self.add_reaction(message, sent_emoji) + if not thread.cancelled: + try: + await thread.send(message) + except Exception: + logger.error("Failed to send message:", exc_info=True) + await self.add_reaction(message, blocked_emoji) + else: + await self.add_reaction(message, sent_emoji) async def get_contexts(self, message, *, cls=commands.Context): """ diff --git a/core/config.py b/core/config.py index 936278d67b..4e6b145924 100644 --- a/core/config.py +++ b/core/config.py @@ -82,6 +82,12 @@ class ConfigManager: # react to contact "react_to_contact_message": None, "react_to_contact_emoji": "\u2705", + # confirm thread creation + "confirm_thread_creation": False, + "confirm_thread_creation_title": "Confirm thread creation", + "confirm_thread_creation_description": "React to confirm thread creation which will directly contact the moderators", + "confirm_thread_creation_accept": "\u2705", + "confirm_thread_creation_deny": "\U0001F6AB", } private_keys = { @@ -146,6 +152,7 @@ class ConfigManager: "transfer_reactions", "close_on_leave", "alert_on_mention", + "confirm_thread_creation", "enable_plugins", "enable_eval", } diff --git a/core/config_help.json b/core/config_help.json index acb2834e53..c986be3ded 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -590,6 +590,56 @@ "See also: `mention`" ] }, + "confirm_thread_creation": { + "default": "No", + "description": "Ensure users confirm that they want to create a new thread", + "examples":[ + "`{prefix}config set confirm_thread_creation yes" + ], + "notes": [ + "See also: `confirm_thread_creation_title`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + ] + }, + "confirm_thread_creation_title": { + "default": "Confirm thread creation", + "description": "Title for the embed message sent to users to confirm a thread creation", + "examples":[ + "`{prefix}config set confirm_thread_creation_title Are you sure you want to create a new thread?" + ], + "notes": [ + "See also: `confirm_thread_creation`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + ] + }, + "confirm_thread_creation_description": { + "default": "React to confirm thread creation which will directly contact the moderators", + "description": "Description for the embed message sent to users to confirm a thread creation", + "examples":[ + "`{prefix}config set confirm_thread_creation_description React to confirm" + ], + "notes": [ + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + ] + }, + "confirm_thread_creation_accept": { + "default": "\u2705", + "description": "Emoji to accept a thread creation", + "examples":[ + "`{prefix}config set confirm_thread_creation_accept \u2611" + ], + "notes": [ + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, confirm_thread_creation_deny`" + ] + }, + "confirm_thread_creation_deny": { + "default": "\u2705", + "description": "Emoji to accept deny thread creation", + "examples":[ + "`{prefix}config set confirm_thread_creation_deny \u26D4" + ], + "notes": [ + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, confirm_thread_creation_accept`" + ] + }, "modmail_guild_id": { "default": "Fallback on `GUILD_ID`", "description": "The ID of the discord server where the threads channels should be created (receiving server).", diff --git a/core/thread.py b/core/thread.py index adbfed2e67..c844014462 100644 --- a/core/thread.py +++ b/core/thread.py @@ -39,19 +39,25 @@ def __init__( self._channel = channel self.genesis_message = None self._ready_event = asyncio.Event() + self.wait_tasks = [] self.close_task = None self.auto_close_task = None + self._cancelled = False def __repr__(self): return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id})' async def wait_until_ready(self) -> None: """Blocks execution until the thread is fully set up.""" - # timeout after 3 seconds + # timeout after 30 seconds + task = asyncio.create_task(asyncio.wait_for(self._ready_event.wait(), timeout=20)) + self.wait_tasks.append(task) try: - await asyncio.wait_for(self._ready_event.wait(), timeout=3) + await task except asyncio.TimeoutError: - return + pass + + self.wait_tasks.remove(task) @property def id(self) -> int: @@ -77,6 +83,17 @@ def ready(self, flag: bool): else: self._ready_event.clear() + @property + def cancelled(self) -> bool: + return self._cancelled + + @cancelled.setter + def cancelled(self, flag: bool): + self._cancelled = flag + if flag: + for i in self.wait_tasks: + i.cancel() + async def setup(self, *, creator=None, category=None): """Create the thread channel and other io related initialisation tasks""" self.bot.dispatch("thread_initiate", self) @@ -312,22 +329,25 @@ async def _close( self.bot.config["notification_squad"].pop(str(self.id), None) # Logging - log_data = await self.bot.api.post_log( - self.channel.id, - { - "open": False, - "closed_at": str(datetime.utcnow()), - "nsfw": self.channel.nsfw, - "close_message": message if not silent else None, - "closer": { - "id": str(closer.id), - "name": closer.name, - "discriminator": closer.discriminator, - "avatar_url": str(closer.avatar_url), - "mod": True, + if self.channel: + log_data = await self.bot.api.post_log( + self.channel.id, + { + "open": False, + "closed_at": str(datetime.utcnow()), + "nsfw": self.channel.nsfw, + "close_message": message if not silent else None, + "closer": { + "id": str(closer.id), + "name": closer.name, + "discriminator": closer.discriminator, + "avatar_url": str(closer.avatar_url), + "mod": True, + }, }, - }, - ) + ) + else: + log_data = None if isinstance(log_data, dict): prefix = self.bot.config["log_url_prefix"].strip("/") @@ -950,15 +970,20 @@ async def find( thread = self.cache.get(recipient_id) if thread is not None: - await thread.wait_until_ready() - if not thread.channel or not self.bot.get_channel(thread.channel.id): - logger.warning( - "Found existing thread for %s but the channel is invalid.", recipient_id - ) - self.bot.loop.create_task( - thread.close(closer=self.bot.user, silent=True, delete_channel=False) - ) - thread = None + try: + await thread.wait_until_ready() + except asyncio.CancelledError: + logger.warning("Thread for %s cancelled, abort creating", recipient) + return thread + else: + if not thread.channel or not self.bot.get_channel(thread.channel.id): + logger.warning( + "Found existing thread for %s but the channel is invalid.", recipient_id + ) + self.bot.loop.create_task( + thread.close(closer=self.bot.user, silent=True, delete_channel=False) + ) + thread = None else: channel = discord.utils.get( self.bot.modmail_guild.text_channels, topic=f"User ID: {recipient_id}" @@ -1000,6 +1025,7 @@ async def create( self, recipient: typing.Union[discord.Member, discord.User], *, + message: discord.Message = None, creator: typing.Union[discord.Member, discord.User] = None, category: discord.CategoryChannel = None, ) -> Thread: @@ -1008,14 +1034,19 @@ async def create( # checks for existing thread in cache thread = self.cache.get(recipient.id) if thread: - await thread.wait_until_ready() - if thread.channel and self.bot.get_channel(thread.channel.id): - logger.warning("Found an existing thread for %s, abort creating.", recipient) + try: + await thread.wait_until_ready() + except asyncio.CancelledError: + logger.warning("Thread for %s cancelled, abort creating", recipient) return thread - logger.warning("Found an existing thread for %s, closing previous thread.", recipient) - self.bot.loop.create_task( - thread.close(closer=self.bot.user, silent=True, delete_channel=False) - ) + else: + if thread.channel and self.bot.get_channel(thread.channel.id): + logger.warning("Found an existing thread for %s, abort creating.", recipient) + return thread + logger.warning("Found an existing thread for %s, closing previous thread.", recipient) + self.bot.loop.create_task( + thread.close(closer=self.bot.user, silent=True, delete_channel=False) + ) thread = Thread(self, recipient) @@ -1035,6 +1066,57 @@ async def create( self.bot.config.set("fallback_category_id", category.id) await self.bot.config.update() + if message and self.bot.config["confirm_thread_creation"]: + confirm = await message.channel.send( + embed=discord.Embed( + title=self.bot.config["confirm_thread_creation_title"], + description=self.bot.config["confirm_thread_creation_description"], + color=self.bot.main_color, + ) + ) + accept_emoji = self.bot.config["confirm_thread_creation_accept"] + deny_emoji = self.bot.config["confirm_thread_creation_deny"] + await confirm.add_reaction(accept_emoji) + await asyncio.sleep(0.2) + await confirm.add_reaction(deny_emoji) + try: + r, _ = await self.bot.wait_for( + "reaction_add", + check=lambda r, u: u.id == message.author.id + and r.message.id == confirm.id + and r.message.channel.id == confirm.channel.id + and r.emoji in (accept_emoji, deny_emoji), + timeout=20, + ) + except asyncio.TimeoutError: + thread.cancelled = True + + await confirm.remove_reaction(accept_emoji, self.bot.user) + await asyncio.sleep(0.2) + await confirm.remove_reaction(deny_emoji, self.bot.user) + await message.channel.send( + embed=discord.Embed( + title="Cancelled", description="Timed out", color=self.bot.error_color + ) + ) + del self.cache[recipient.id] + return thread + else: + if r.emoji == deny_emoji: + thread.cancelled = True + + await confirm.remove_reaction(accept_emoji, self.bot.user) + await asyncio.sleep(0.2) + await confirm.remove_reaction(deny_emoji, self.bot.user) + await message.channel.send( + embed=discord.Embed( + title="Cancelled", color=self.bot.error_color + ) + ) + del self.cache[recipient.id] + return thread + + self.bot.loop.create_task(thread.setup(creator=creator, category=category)) return thread From 3eee193a78fb49b6b7905ecff6d0904f9828c6fe Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 15:58:55 +0800 Subject: [PATCH 113/705] Support gyazo links in image embed, resolve #282 --- CHANGELOG.md | 3 ++- bot.py | 2 +- core/thread.py | 21 ++++++++++++--------- core/utils.py | 19 +++++++++++++++---- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 839c915071..55bbf33fe3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.6.3-dev1 +# v3.6.3-dev2 ### Added @@ -17,6 +17,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `close_on_leave` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) - Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/kyb3r/modmail/issues/2833)) - Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) +- Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) ### Fixed diff --git a/bot.py b/bot.py index 82344544c9..716a66c598 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.6.3-dev1" +__version__ = "3.6.3-dev2" import asyncio diff --git a/core/thread.py b/core/thread.py index c844014462..2ec55b8214 100644 --- a/core/thread.py +++ b/core/thread.py @@ -56,7 +56,7 @@ async def wait_until_ready(self) -> None: await task except asyncio.TimeoutError: pass - + self.wait_tasks.remove(task) @property @@ -86,7 +86,7 @@ def ready(self, flag: bool): @property def cancelled(self) -> bool: return self._cancelled - + @cancelled.setter def cancelled(self, flag: bool): self._cancelled = flag @@ -793,11 +793,15 @@ async def send( attachments.append(attachment) image_urls = re.findall( - r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", + r"http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message.content, ) - image_urls = [(url, None) for url in image_urls if is_image_url(url)] + image_urls = [ + (is_image_url(url, convert_size=False), None) + for url in image_urls + if is_image_url(url, convert_size=False) + ] images.extend(image_urls) embedded_image = False @@ -1043,7 +1047,9 @@ async def create( if thread.channel and self.bot.get_channel(thread.channel.id): logger.warning("Found an existing thread for %s, abort creating.", recipient) return thread - logger.warning("Found an existing thread for %s, closing previous thread.", recipient) + logger.warning( + "Found an existing thread for %s, closing previous thread.", recipient + ) self.bot.loop.create_task( thread.close(closer=self.bot.user, silent=True, delete_channel=False) ) @@ -1109,14 +1115,11 @@ async def create( await asyncio.sleep(0.2) await confirm.remove_reaction(deny_emoji, self.bot.user) await message.channel.send( - embed=discord.Embed( - title="Cancelled", color=self.bot.error_color - ) + embed=discord.Embed(title="Cancelled", color=self.bot.error_color) ) del self.cache[recipient.id] return thread - self.bot.loop.create_task(thread.setup(creator=creator, category=category)) return thread diff --git a/core/utils.py b/core/utils.py index a4f14182a5..a648f04f1a 100644 --- a/core/utils.py +++ b/core/utils.py @@ -117,7 +117,7 @@ def format_preview(messages: typing.List[typing.Dict[str, typing.Any]]): return out or "No Messages" -def is_image_url(url: str) -> bool: +def is_image_url(url: str, **kwargs) -> bool: """ Check if the URL is pointing to an image. @@ -131,10 +131,18 @@ def is_image_url(url: str) -> bool: bool Whether the URL is a valid image URL. """ - return bool(parse_image_url(url)) + if url.startswith("https://gyazo.com") or url.startswith("http://gyazo.com"): + # gyazo support + url = re.sub( + r"(http[s]?:\/\/)((?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)", + r"\1i.\2.png", + url, + ) + return parse_image_url(url, **kwargs) -def parse_image_url(url: str) -> str: + +def parse_image_url(url: str, *, convert_size=True) -> str: """ Convert the image URL into a sized Discord avatar. @@ -152,7 +160,10 @@ def parse_image_url(url: str) -> str: url = parse.urlsplit(url) if any(url.path.lower().endswith(i) for i in types): - return parse.urlunsplit((*url[:3], "size=128", url[-1])) + if convert_size: + return parse.urlunsplit((*url[:3], "size=128", url[-1])) + else: + return parse.urlunsplit(url) return "" From 1968f0ac385daad5f7520550cfe57ea3dad1f2e5 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 15:59:21 +0800 Subject: [PATCH 114/705] Support silent arg in contact --- CHANGELOG.md | 1 + cogs/modmail.py | 36 ++++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55bbf33fe3..5ed07feeac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/kyb3r/modmail/issues/2833)) - Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) - Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) +- Added `silent` argument to `?contact` to restore old behaviour. ### Fixed diff --git a/cogs/modmail.py b/cogs/modmail.py index 73445ecba0..fa420034bc 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -905,14 +905,14 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.command() + @commands.command(usage=" [category] [options]") @checks.has_permissions(PermissionLevel.SUPPORTER) async def contact( self, ctx, user: Union[discord.Member, discord.User], *, - category: discord.CategoryChannel = None, + category: Union[discord.CategoryChannel, str] = None, manual_trigger=True, ): """ @@ -923,7 +923,13 @@ async def contact( `category`, if specified, may be a category ID, mention, or name. `user` may be a user ID, mention, or name. + `options` can be `silent` """ + silent = False + if isinstance(category, str): + if "silent" in category or "silently" in category: + silent = True + category = None if user.bot: embed = discord.Embed( @@ -945,18 +951,20 @@ async def contact( if self.bot.config["dm_disabled"] >= 1: logger.info("Contacting user %s when Modmail DM is disabled.", user) - if ctx.author.id == user.id: - description = "You have opened a Modmail thread." - else: - description = f"{ctx.author.name} has opened a Modmail thread." - em = discord.Embed( - title="New Thread", - description=description, - color=self.bot.main_color, - timestamp=datetime.utcnow(), - ) - em.set_footer(icon_url=ctx.author.avatar_url) - await user.send(embed=em) + if not silent: + if ctx.author.id == user.id: + description = "You have opened a Modmail thread." + else: + description = f"{ctx.author.name} has opened a Modmail thread." + + em = discord.Embed( + title="New Thread", + description=description, + color=self.bot.main_color, + timestamp=datetime.utcnow(), + ) + em.set_footer(icon_url=ctx.author.avatar_url) + await user.send(embed=em) embed = discord.Embed( title="Created Thread", From 0222231263a157981c68e02459c469fa1fabdd86 Mon Sep 17 00:00:00 2001 From: Vincysuper07 <52707876+Vincysuper07@users.noreply.github.com> Date: Thu, 5 Nov 2020 10:25:16 +0100 Subject: [PATCH 115/705] Replace moderation plugin (#2873) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Reè * Confused branch once again --- plugins/registry.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 5c343ebcff..55ce288847 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -143,13 +143,13 @@ "thumbnail_url": "http://www.pngmart.com/files/7/Statistics-PNG-Clipart.png" }, "moderation": { - "repository": "xPolar/modmail-plugins", - "branch": "master", + "repository": "Vincysuper07/modmail-plugins", + "branch": "main", "description": "Moderate your server with Modmail, bring the Mod to Modmail!", "bot_version": "3.0.3", "title": "Moderate your server", - "icon_url": "https://cdn.discordapp.com/attachments/539943767562780704/601485194196680704/wGFmzZq.png", - "thumbnail_url": "https://cdn.discordapp.com/attachments/539943767562780704/601485194196680704/wGFmzZq.png" + "icon_url": "https://cdn.discordapp.com/attachments/759829573654544454/773535811143598110/ad2e4d6e7b90ca6005a5038e22b099cc.png", + "thumbnail_url": "https://cdn.discordapp.com/attachments/759829573654544454/773535811143598110/ad2e4d6e7b90ca6005a5038e22b099cc.png" }, "serverstats": { "repository": "dazvise/modmail-plugins", @@ -205,4 +205,4 @@ "icon_url": "https://i.imgur.com/yeHFKgl.png", "thumbnail_url": "https://i.imgur.com/yeHFKgl.png" } -} \ No newline at end of file +} From 0df4ab4d296bacdc3bbab98365f2f334c01d76fe Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 17:26:51 +0800 Subject: [PATCH 116/705] change moderation bot version to 3.6.2 --- plugins/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 55ce288847..f5e119912e 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -146,7 +146,7 @@ "repository": "Vincysuper07/modmail-plugins", "branch": "main", "description": "Moderate your server with Modmail, bring the Mod to Modmail!", - "bot_version": "3.0.3", + "bot_version": "3.6.2", "title": "Moderate your server", "icon_url": "https://cdn.discordapp.com/attachments/759829573654544454/773535811143598110/ad2e4d6e7b90ca6005a5038e22b099cc.png", "thumbnail_url": "https://cdn.discordapp.com/attachments/759829573654544454/773535811143598110/ad2e4d6e7b90ca6005a5038e22b099cc.png" From aba9b71a5568daeac3ea4448141704e4a589b178 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 18:43:35 +0800 Subject: [PATCH 117/705] add countdowns plugin --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index f5e119912e..ce2b76afc0 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -204,5 +204,14 @@ "title": "Translate", "icon_url": "https://i.imgur.com/yeHFKgl.png", "thumbnail_url": "https://i.imgur.com/yeHFKgl.png" + }, + "countdowns": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Setup a countdown voice channel in your server!", + "bot_version": "3.6.2", + "title": "Countdowns", + "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", + "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" } } From 59eabf8d55d3989035b70f99f721a41cd69da9b9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 23:25:35 +0800 Subject: [PATCH 118/705] Help and help all, resolve #2847 --- CHANGELOG.md | 1 + cogs/utility.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ed07feeac..44fa86d9eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) - Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) - Added `silent` argument to `?contact` to restore old behaviour. +- If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/kyb3r/modmail/issues/2847)) ### Fixed diff --git a/cogs/utility.py b/cogs/utility.py index b0d96ea094..e3c0d12b66 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -31,6 +31,19 @@ class ModmailHelpCommand(commands.HelpCommand): + async def command_callback(self, ctx, *, command=None): + """Ovrwrites original command_callback to ensure `help` without any arguments + returns with checks, `help all` returns without checks""" + if command is None: + self.verify_checks = True + else: + self.verify_checks = False + + if command == 'all': + command = None + + return await super().command_callback(ctx, command=command) + async def format_cog_help(self, cog, *, no_cog=False): bot = self.context.bot prefix = self.clean_prefix @@ -64,6 +77,9 @@ async def format_cog_help(self, cog, *, no_cog=False): ) embed = discord.Embed(description=f"*{description}*", color=bot.main_color) + if not format_: + continue + embed.add_field(name="Commands", value=format_ or "No commands.") continued = " (Continued)" if embeds else "" @@ -231,7 +247,6 @@ def __init__(self, bot): self.bot = bot self._original_help_command = bot.help_command self.bot.help_command = ModmailHelpCommand( - verify_checks=False, command_attrs={ "help": "Shows this help message.", "checks": [checks.has_permissions_predicate(PermissionLevel.REGULAR)], From e7ba21bed2859e20eb74d07b9fefa04e8bfe9175 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 23:46:45 +0800 Subject: [PATCH 119/705] Role blocking, resolve #2753 --- CHANGELOG.md | 1 + bot.py | 37 +++++++++++++++++++++++++ cogs/modmail.py | 72 +++++++++++++++++++++++++++++++++++++++---------- cogs/utility.py | 4 +-- core/config.py | 1 + 5 files changed, 99 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44fa86d9eb..a558003e84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) - Added `silent` argument to `?contact` to restore old behaviour. - If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/kyb3r/modmail/issues/2847)) +- Added a way to block roles. ([GH #2753](https://github.com/kyb3r/modmail/issues/2753)) ### Fixed diff --git a/bot.py b/bot.py index 716a66c598..bb0c4b853f 100644 --- a/bot.py +++ b/bot.py @@ -324,6 +324,10 @@ def main_category(self) -> typing.Optional[discord.CategoryChannel]: def blocked_users(self) -> typing.Dict[str, str]: return self.config["blocked"] + @property + def blocked_roles(self) -> typing.Dict[str, str]: + return self.config["blocked_roles"] + @property def blocked_whitelisted_users(self) -> typing.List[str]: return self.config["blocked_whitelist"] @@ -578,6 +582,36 @@ def check_guild_age(self, author: discord.Member) -> bool: return False return True + def check_manual_blocked_roles(self, author: discord.Member) -> bool: + for r in author.roles: + if str(r.id) in self.blocked_roles: + + blocked_reason = self.blocked_roles.get(str(r.id)) or "" + now = datetime.utcnow() + + # etc "blah blah blah... until 2019-10-14T21:12:45.559948." + end_time = re.search(r"until ([^`]+?)\.$", blocked_reason) + if end_time is None: + # backwards compat + end_time = re.search(r"%([^%]+?)%", blocked_reason) + if end_time is not None: + logger.warning( + r"Deprecated time message for user %s, block and unblock again to update.", + author.name, + ) + + if end_time is not None: + after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() + if after <= 0: + # No longer blocked + self.blocked_users.pop(str(author.id)) + logger.debug("No longer blocked, user %s.", author.name) + return True + logger.debug("User blocked, user %s.", author.name) + return False + + return True + def check_manual_blocked(self, author: discord.Member) -> bool: if str(author.id) not in self.blocked_users: return True @@ -656,6 +690,9 @@ async def is_blocked( if not self.check_manual_blocked(author): return True + if not self.check_manual_blocked_roles(author): + return True + await self.config.update() return False diff --git a/cogs/modmail.py b/cogs/modmail.py index fa420034bc..45e77f2eda 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -7,6 +7,7 @@ import discord from discord.ext import commands +from discord.role import Role from discord.utils import escape_markdown from dateutil import parser @@ -1009,6 +1010,7 @@ async def blocked(self, ctx): embeds = [discord.Embed(title="Blocked Users", color=self.bot.main_color, description="")] + roles = [] users = [] for id_, reason in self.bot.blocked_users.items(): @@ -1022,6 +1024,11 @@ async def blocked(self, ctx): except discord.NotFound: users.append((id_, reason)) + for id_, reason in self.bot.blocked_roles.items(): + role = self.bot.guild.get_role(int(id_)) + if role: + roles.append((role.mention, reason)) + if users: embed = embeds[0] @@ -1039,7 +1046,29 @@ async def blocked(self, ctx): else: embeds[0].description = "Currently there are no blocked users." + embeds.append( + discord.Embed(title="Blocked Roles", color=self.bot.main_color, description="") + ) + + if roles: + embed = embeds[-1] + + for mention, reason in roles: + line = mention + f" - {reason or 'No Reason Provided'}\n" + if len(embed.description) + len(line) > 2048: + embed = discord.Embed( + title="Blocked Roles (Continued)", + color=self.bot.main_color, + description=line, + ) + embeds.append(embed) + else: + embed.description += line + else: + embeds[-1].description = "Currently there are no blocked roles." + session = EmbedPaginatorSession(ctx, *embeds) + await session.run() @blocked.command(name="whitelist") @@ -1100,7 +1129,13 @@ async def blocked_whitelist(self, ctx, *, user: User = None): @commands.command(usage="[user] [duration] [reason]") @checks.has_permissions(PermissionLevel.MODERATOR) @trigger_typing - async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTime = None): + async def block( + self, + ctx, + user_or_role: Union[User, discord.Role] = None, + *, + after: UserFriendlyTime = None, + ): """ Block a user from using Modmail. @@ -1112,24 +1147,25 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi `duration` may be a simple "human-readable" time text. See `{prefix}help close` for examples. """ - if user is None: + if user_or_role is None: thread = ctx.thread if thread: - user = thread.recipient + user_or_role = thread.recipient elif after is None: raise commands.MissingRequiredArgument(SimpleNamespace(name="user")) else: raise commands.BadArgument(f'User "{after.arg}" not found.') - mention = getattr(user, "mention", f"`{user.id}`") + mention = getattr(user_or_role, "mention", f"`{user_or_role.id}`") - if str(user.id) in self.bot.blocked_whitelisted_users: - embed = discord.Embed( - title="Error", - description=f"Cannot block {mention}, user is whitelisted.", - color=self.bot.error_color, - ) - return await ctx.send(embed=embed) + if not isinstance(user_or_role, discord.Role): + if str(user_or_role.id) in self.bot.blocked_whitelisted_users: + embed = discord.Embed( + title="Error", + description=f"Cannot block {mention}, user is whitelisted.", + color=self.bot.error_color, + ) + return await ctx.send(embed=embed) reason = f"by {escape_markdown(ctx.author.name)}#{ctx.author.discriminator}" @@ -1143,11 +1179,15 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi reason += "." - msg = self.bot.blocked_users.get(str(user.id)) + if isinstance(user_or_role, discord.Role): + msg = self.bot.blocked_roles.get(str(user_or_role.id)) + else: + msg = self.bot.blocked_users.get(str(user_or_role.id)) + if msg is None: msg = "" - if str(user.id) in self.bot.blocked_users and msg: + if msg: old_reason = msg.strip().rstrip(".") embed = discord.Embed( title="Success", @@ -1161,7 +1201,11 @@ async def block(self, ctx, user: Optional[User] = None, *, after: UserFriendlyTi color=self.bot.main_color, description=f"{mention} is now blocked {reason}", ) - self.bot.blocked_users[str(user.id)] = reason + + if isinstance(user_or_role, discord.Role): + self.bot.blocked_roles[str(user_or_role.id)] = reason + else: + self.bot.blocked_users[str(user_or_role.id)] = reason await self.bot.config.update() return await ctx.send(embed=embed) diff --git a/cogs/utility.py b/cogs/utility.py index e3c0d12b66..8658767d9f 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -38,8 +38,8 @@ async def command_callback(self, ctx, *, command=None): self.verify_checks = True else: self.verify_checks = False - - if command == 'all': + + if command == "all": command = None return await super().command_callback(ctx, command=command) diff --git a/core/config.py b/core/config.py index 4e6b145924..8e093ecc1d 100644 --- a/core/config.py +++ b/core/config.py @@ -101,6 +101,7 @@ class ConfigManager: "oauth_whitelist": [], # moderation "blocked": {}, + "blocked_roles": {}, "blocked_whitelist": [], "command_permissions": {}, "level_permissions": {}, From ef4abaf1dbc666b44fe2b807f1a4b44297e87604 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 5 Nov 2020 23:51:30 +0800 Subject: [PATCH 120/705] Add functionality to unblock roles --- cogs/modmail.py | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 45e77f2eda..543a18af0f 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1158,14 +1158,16 @@ async def block( mention = getattr(user_or_role, "mention", f"`{user_or_role.id}`") - if not isinstance(user_or_role, discord.Role): - if str(user_or_role.id) in self.bot.blocked_whitelisted_users: - embed = discord.Embed( - title="Error", - description=f"Cannot block {mention}, user is whitelisted.", - color=self.bot.error_color, - ) - return await ctx.send(embed=embed) + if ( + not isinstance(user_or_role, discord.Role) + and str(user_or_role.id) in self.bot.blocked_whitelisted_users + ): + embed = discord.Embed( + title="Error", + description=f"Cannot block {mention}, user is whitelisted.", + color=self.bot.error_color, + ) + return await ctx.send(embed=embed) reason = f"by {escape_markdown(ctx.author.name)}#{ctx.author.discriminator}" @@ -1213,7 +1215,7 @@ async def block( @commands.command() @checks.has_permissions(PermissionLevel.MODERATOR) @trigger_typing - async def unblock(self, ctx, *, user: User = None): + async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): """ Unblock a user from using Modmail. @@ -1222,18 +1224,21 @@ async def unblock(self, ctx, *, user: User = None): `user` may be a user ID, mention, or name. """ - if user is None: + if user_or_role is None: thread = ctx.thread if thread: - user = thread.recipient + user_or_role = thread.recipient else: raise commands.MissingRequiredArgument(SimpleNamespace(name="user")) - mention = getattr(user, "mention", f"`{user.id}`") - name = getattr(user, "name", f"`{user.id}`") + mention = getattr(user_or_role, "mention", f"`{user_or_role.id}`") + name = getattr(user_or_role, "name", f"`{user_or_role.id}`") - if str(user.id) in self.bot.blocked_users: - msg = self.bot.blocked_users.pop(str(user.id)) or "" + if ( + not isinstance(user_or_role, discord.Role) + and str(user_or_role.id) in self.bot.blocked_users + ): + msg = self.bot.blocked_users.pop(str(user_or_role.id)) or "" await self.bot.config.update() if msg.startswith("System Message: "): @@ -1249,7 +1254,7 @@ async def unblock(self, ctx, *, user: User = None): embed.set_footer( text="However, if the original system block reason still applies, " f"{name} will be automatically blocked again. " - f'Use "{self.bot.prefix}blocked whitelist {user.id}" to whitelist the user.' + f'Use "{self.bot.prefix}blocked whitelist {user_or_role.id}" to whitelist the user.' ) else: embed = discord.Embed( @@ -1257,6 +1262,18 @@ async def unblock(self, ctx, *, user: User = None): color=self.bot.main_color, description=f"{mention} is no longer blocked.", ) + elif ( + isinstance(user_or_role, discord.Role) + and str(user_or_role.id) in self.bot.blocked_roles + ): + msg = self.bot.blocked_roles.pop(str(user_or_role.id)) or "" + await self.bot.config.update() + + embed = discord.Embed( + title="Success", + color=self.bot.main_color, + description=f"{mention} is no longer blocked.", + ) else: embed = discord.Embed( title="Error", description=f"{mention} is not blocked.", color=self.bot.error_color From 66856ca9244fc44012048368719d05dbb207a167 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Nov 2020 00:04:09 +0800 Subject: [PATCH 121/705] cooldown_thread_title and cooldown_thread_response config var, resolve #2865 --- CHANGELOG.md | 5 +++-- bot.py | 6 +++--- core/config.py | 4 +++- core/config_help.json | 35 +++++++++++++++++++++++++++++------ core/thread.py | 2 +- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a558003e84..74e5398b5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.6.3-dev2 +# v3.7.0-dev3 ### Added @@ -16,11 +16,12 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `transfer_reactions` to link reactions between mods and users. ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) - Added `close_on_leave` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) - Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/kyb3r/modmail/issues/2833)) -- Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) +- Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) - Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) - Added `silent` argument to `?contact` to restore old behaviour. - If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/kyb3r/modmail/issues/2847)) - Added a way to block roles. ([GH #2753](https://github.com/kyb3r/modmail/issues/2753)) +- Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865)) ### Fixed diff --git a/bot.py b/bot.py index bb0c4b853f..0ffbd59b51 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.6.3-dev2" +__version__ = "3.7.0-dev3" import asyncio @@ -753,8 +753,8 @@ async def process_dm_modmail(self, message: discord.Message) -> None: if delta: await message.channel.send( embed=discord.Embed( - title="Message not sent!", - description=f"You must wait for {delta} before you can contact me again.", + title=self.config["cooldown_thread_title"], + description=self.config["cooldown_thread_response"].format(delta=delta), color=self.error_color, ) ) diff --git a/core/config.py b/core/config.py index 8e093ecc1d..c4570f93f9 100644 --- a/core/config.py +++ b/core/config.py @@ -62,6 +62,8 @@ class ConfigManager: "thread_move_notify": False, "thread_move_notify_mods": False, "thread_move_response": "This thread has been moved.", + "cooldown_thread_title": "Message not sent!", + "cooldown_thread_response": "You must wait for {delta} before you can contact me again.", "disabled_new_thread_title": "Not Delivered", "disabled_new_thread_response": "We are not accepting new threads.", "disabled_new_thread_footer": "Please try again later...", @@ -85,7 +87,7 @@ class ConfigManager: # confirm thread creation "confirm_thread_creation": False, "confirm_thread_creation_title": "Confirm thread creation", - "confirm_thread_creation_description": "React to confirm thread creation which will directly contact the moderators", + "confirm_thread_response": "React to confirm thread creation which will directly contact the moderators", "confirm_thread_creation_accept": "\u2705", "confirm_thread_creation_deny": "\U0001F6AB", } diff --git a/core/config_help.json b/core/config_help.json index c986be3ded..27860c5b2e 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -404,6 +404,29 @@ "See also: `thread_move_title`, `thread_move_notify`." ] }, + "cooldown_thread_title": { + "default": "Message not sent!", + "description": "The title of the message embed when the user has a cooldown before creating a new thread.", + "examples": [ + "`{prefix}config set cooldown_thread_title Error`" + ], + "notes": [ + "Only has an effect when `thread_cooldown` is set", + "See also: `cooldown_thread_response`." + ] + }, + "cooldown_thread_response": { + "default": "You must wait for {delta} before you can contact me again.", + "description": "The description of the message embed when the user has a cooldown before creating a new thread.", + "examples": [ + "`{prefix}config set cooldown_thread_response Be patient! You are on cooldown, wait {delta} more." + ], + "notes": [ + "Only has an effect when `thread_cooldown` is set", + "Must have a {delta} included which will be replaced with the duration of time.", + "See also: `cooldown_thread_title`." + ] + }, "disabled_new_thread_title": { "default": "Not Delivered.", "description": "The title of the message embed when Modmail new thread creation is disabled and user tries to create a new thread.", @@ -597,7 +620,7 @@ "`{prefix}config set confirm_thread_creation yes" ], "notes": [ - "See also: `confirm_thread_creation_title`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + "See also: `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" ] }, "confirm_thread_creation_title": { @@ -607,14 +630,14 @@ "`{prefix}config set confirm_thread_creation_title Are you sure you want to create a new thread?" ], "notes": [ - "See also: `confirm_thread_creation`, `confirm_thread_creation_description`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + "See also: `confirm_thread_creation`, `confirm_thread_response`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" ] }, - "confirm_thread_creation_description": { + "confirm_thread_response": { "default": "React to confirm thread creation which will directly contact the moderators", "description": "Description for the embed message sent to users to confirm a thread creation", "examples":[ - "`{prefix}config set confirm_thread_creation_description React to confirm" + "`{prefix}config set confirm_thread_response React to confirm" ], "notes": [ "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" @@ -627,7 +650,7 @@ "`{prefix}config set confirm_thread_creation_accept \u2611" ], "notes": [ - "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, confirm_thread_creation_deny`" + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_deny`" ] }, "confirm_thread_creation_deny": { @@ -637,7 +660,7 @@ "`{prefix}config set confirm_thread_creation_deny \u26D4" ], "notes": [ - "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_description`, confirm_thread_creation_accept`" + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_accept`" ] }, "modmail_guild_id": { diff --git a/core/thread.py b/core/thread.py index 2ec55b8214..0d8e61929d 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1076,7 +1076,7 @@ async def create( confirm = await message.channel.send( embed=discord.Embed( title=self.bot.config["confirm_thread_creation_title"], - description=self.bot.config["confirm_thread_creation_description"], + description=self.bot.config["confirm_thread_response"], color=self.bot.main_color, ) ) From 06a0a87aa4b1f655d460028e97163eba46971e31 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Nov 2020 00:18:53 +0800 Subject: [PATCH 122/705] Add ?selfcontact resolves #2762 --- CHANGELOG.md | 1 + cogs/modmail.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74e5398b5e..90e4b7c9d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/kyb3r/modmail/issues/2847)) - Added a way to block roles. ([GH #2753](https://github.com/kyb3r/modmail/issues/2753)) - Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865)) +- Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/kyb3r/modmail/issues/2762)) ### Fixed diff --git a/cogs/modmail.py b/cogs/modmail.py index 543a18af0f..01b60e6709 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -906,6 +906,11 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) + @commands.command() + @checks.has_permissions(PermissionLevel.REGULAR) + async def selfcontact(self, ctx): + await ctx.invoke(self.contact, user=ctx.author) + @commands.command(usage=" [category] [options]") @checks.has_permissions(PermissionLevel.SUPPORTER) async def contact( From 8da1e20246d81b35f44acd89f06e829f77f48b10 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Nov 2020 01:04:04 +0800 Subject: [PATCH 123/705] Fix bugs introduced in -dev3 --- CHANGELOG.md | 2 +- bot.py | 2 +- cogs/modmail.py | 2 +- cogs/utility.py | 2 +- core/config_help.json | 22 ++++++++++++---------- core/thread.py | 6 ++---- core/utils.py | 10 +++++++++- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90e4b7c9d2..59b1d521f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev3 +# v3.7.0-dev4 ### Added diff --git a/bot.py b/bot.py index 0ffbd59b51..38cf135352 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev3" +__version__ = "3.7.0-dev4" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index 01b60e6709..d51d210f8a 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -988,7 +988,7 @@ async def contact( @commands.Cog.listener() async def on_raw_reaction_add(self, payload): - react_message_id = int(self.bot.config.get("react_to_contact_message")) + react_message_id = tryint(self.bot.config.get("react_to_contact_message")) react_message_emoji = self.bot.config.get("react_to_contact_emoji") if all((react_message_id, react_message_emoji)): if payload.message_id == react_message_id: diff --git a/cogs/utility.py b/cogs/utility.py index 8658767d9f..e355e2dd65 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -863,7 +863,7 @@ async def config_help(self, ctx, key: str.lower = None): return await ctx.send(embed=embed) def fmt(val): - return val.format(prefix=self.bot.prefix, bot=self.bot) + return val.format(prefix=self.bot.prefix, bot=self.bot, delta='{delta}') index = 0 embeds = [] diff --git a/core/config_help.json b/core/config_help.json index 27860c5b2e..32d8cb58ac 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -419,7 +419,7 @@ "default": "You must wait for {delta} before you can contact me again.", "description": "The description of the message embed when the user has a cooldown before creating a new thread.", "examples": [ - "`{prefix}config set cooldown_thread_response Be patient! You are on cooldown, wait {delta} more." + "`{prefix}config set cooldown_thread_response Be patient! You are on cooldown, wait {delta} more.`" ], "notes": [ "Only has an effect when `thread_cooldown` is set", @@ -591,7 +591,7 @@ "default": "Yes", "description": "Transfer users reactions to mods and vice versa", "examples":[ - "`{prefix}config set transfer_reactions no" + "`{prefix}config set transfer_reactions no`" ], "notes": [] }, @@ -599,7 +599,7 @@ "default": "No", "description": "Closes a modmail thread upon user leave automatically", "examples":[ - "`{prefix}config set close_on_leave yes" + "`{prefix}config set close_on_leave yes`" ], "notes": [] }, @@ -607,7 +607,7 @@ "default": "No", "description": "Mentions all mods (mention) in logs channel when bot is mentioned", "examples":[ - "`{prefix}config set alert_on_mention yes" + "`{prefix}config set alert_on_mention yes`" ], "notes": [ "See also: `mention`" @@ -617,7 +617,7 @@ "default": "No", "description": "Ensure users confirm that they want to create a new thread", "examples":[ - "`{prefix}config set confirm_thread_creation yes" + "`{prefix}config set confirm_thread_creation yes`" ], "notes": [ "See also: `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" @@ -627,7 +627,7 @@ "default": "Confirm thread creation", "description": "Title for the embed message sent to users to confirm a thread creation", "examples":[ - "`{prefix}config set confirm_thread_creation_title Are you sure you want to create a new thread?" + "`{prefix}config set confirm_thread_creation_title Are you sure you want to create a new thread?`" ], "notes": [ "See also: `confirm_thread_creation`, `confirm_thread_response`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" @@ -637,7 +637,7 @@ "default": "React to confirm thread creation which will directly contact the moderators", "description": "Description for the embed message sent to users to confirm a thread creation", "examples":[ - "`{prefix}config set confirm_thread_response React to confirm" + "`{prefix}config set confirm_thread_response React to confirm`" ], "notes": [ "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" @@ -647,19 +647,21 @@ "default": "\u2705", "description": "Emoji to accept a thread creation", "examples":[ - "`{prefix}config set confirm_thread_creation_accept \u2611" + "`{prefix}config set confirm_thread_creation_accept \u2611`" ], "notes": [ + "Has no effect unless `confirm_thread_creation` is set", "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_deny`" ] }, "confirm_thread_creation_deny": { - "default": "\u2705", + "default": "\uD83D\uDEAB", "description": "Emoji to accept deny thread creation", "examples":[ - "`{prefix}config set confirm_thread_creation_deny \u26D4" + "`{prefix}config set confirm_thread_creation_deny \u26D4`" ], "notes": [ + "Has no effect unless `confirm_thread_creation` is set", "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_accept`" ] }, diff --git a/core/thread.py b/core/thread.py index 0d8e61929d..1d1fc2f65c 100644 --- a/core/thread.py +++ b/core/thread.py @@ -50,7 +50,7 @@ def __repr__(self): async def wait_until_ready(self) -> None: """Blocks execution until the thread is fully set up.""" # timeout after 30 seconds - task = asyncio.create_task(asyncio.wait_for(self._ready_event.wait(), timeout=20)) + task = asyncio.create_task(asyncio.wait_for(self._ready_event.wait(), timeout=25)) self.wait_tasks.append(task) try: await task @@ -346,8 +346,6 @@ async def _close( }, }, ) - else: - log_data = None if isinstance(log_data, dict): prefix = self.bot.config["log_url_prefix"].strip("/") @@ -393,7 +391,7 @@ async def _close( tasks = [self.bot.config.update()] - if self.bot.log_channel is not None: + if self.bot.log_channel is not None and self.channel is not None: tasks.append(self.bot.log_channel.send(embed=embed)) # Thread closed message diff --git a/core/utils.py b/core/utils.py index a648f04f1a..d3ddb2fccd 100644 --- a/core/utils.py +++ b/core/utils.py @@ -29,6 +29,7 @@ "trigger_typing", "escape_code_block", "format_channel_name", + "tryint", ] @@ -117,7 +118,7 @@ def format_preview(messages: typing.List[typing.Dict[str, typing.Any]]): return out or "No Messages" -def is_image_url(url: str, **kwargs) -> bool: +def is_image_url(url: str, **kwargs) -> str: """ Check if the URL is pointing to an image. @@ -327,3 +328,10 @@ def format_channel_name(author, guild, exclude_channel=None): counter += 1 return new_name + + +def tryint(x): + try: + return int(x) + except ValueError: + return x From 5dea0bd32de1ab0d47de4503f82e395697ecb87b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Nov 2020 01:10:20 +0800 Subject: [PATCH 124/705] More elegant solution for unseenformatter --- cogs/utility.py | 17 ++++++++--------- core/models.py | 11 +++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index e355e2dd65..0e9aaac753 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1,31 +1,30 @@ import asyncio import inspect import os -import traceback import random +import traceback from contextlib import redirect_stdout from datetime import datetime from difflib import get_close_matches -from io import StringIO, BytesIO -from itertools import zip_longest, takewhile +from io import BytesIO, StringIO +from itertools import takewhile, zip_longest from json import JSONDecodeError, loads from textwrap import indent from types import SimpleNamespace from typing import Union import discord +from aiohttp import ClientResponseError from discord.enums import ActivityType, Status from discord.ext import commands, tasks from discord.ext.commands.view import StringView - -from aiohttp import ClientResponseError from pkg_resources import parse_version -from core import checks +from core import checks, utils from core.changelog import Changelog -from core.models import InvalidConfigError, PermissionLevel, getLogger +from core.models import InvalidConfigError, PermissionLevel, UnseenFormatter, getLogger from core.paginator import EmbedPaginatorSession, MessagePaginatorSession -from core import utils + logger = getLogger(__name__) @@ -863,7 +862,7 @@ async def config_help(self, ctx, key: str.lower = None): return await ctx.send(embed=embed) def fmt(val): - return val.format(prefix=self.bot.prefix, bot=self.bot, delta='{delta}') + return UnseenFormatter().format(val, prefix=self.bot.prefix, bot=self.bot) index = 0 embeds = [] diff --git a/core/models.py b/core/models.py index e19086b198..12365f24da 100644 --- a/core/models.py +++ b/core/models.py @@ -174,3 +174,14 @@ def get_field(self, field_name, args, kwargs): except (IndexError, KeyError): pass return "", first + + +class UnseenFormatter(Formatter): + def get_value(self, key, args, kwds): + if isinstance(key, str): + try: + return kwds[key] + except KeyError: + return "{" + key + "}" + else: + return Formatter.get_value(key, args, kwds) From 91153d33449fba3fba012057478476727f7318be Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Nov 2020 01:16:24 +0800 Subject: [PATCH 125/705] Fix errors in -v3/4 --- bot.py | 2 +- core/utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index 38cf135352..c06c8914a7 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev4" +__version__ = "3.7.0-dev5" import asyncio diff --git a/core/utils.py b/core/utils.py index d3ddb2fccd..72c96c00f6 100644 --- a/core/utils.py +++ b/core/utils.py @@ -333,5 +333,5 @@ def format_channel_name(author, guild, exclude_channel=None): def tryint(x): try: return int(x) - except ValueError: + except (ValueError, TypeError): return x From 55bf442df3de9da2be3916471b342df3f331cbad Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Nov 2020 01:17:05 +0800 Subject: [PATCH 126/705] up version in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59b1d521f1..c8e5cc6da6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev4 +# v3.7.0-dev5 ### Added From 3657ad1efca7c61cecf3ce18f0fcf5a68826dd62 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Nov 2020 13:19:41 +0800 Subject: [PATCH 127/705] Close on thread reason config var-dev6 --- CHANGELOG.md | 4 ++-- bot.py | 6 +++--- core/config.py | 1 + core/config_help.json | 19 ++++++++++++++++--- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e5cc6da6..3317ecd03a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev5 +# v3.7.0-dev6 ### Added @@ -14,7 +14,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `react_to_contact_message`, `react_to_contact_emoji` to allow users to create threads by reacting to a message. - Added `thread_move_notify_mods` to mention all mods again after moving thread. ([GH #215](https://github.com/kyb3r/modmail/issues/215)) - Added `transfer_reactions` to link reactions between mods and users. ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) -- Added `close_on_leave` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) +- Added `close_on_leave`, `close_on_leave_reason` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) - Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/kyb3r/modmail/issues/2833)) - Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) - Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) diff --git a/bot.py b/bot.py index c06c8914a7..57a511233e 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev5" +__version__ = "3.7.0-dev6" import asyncio @@ -1118,12 +1118,12 @@ async def on_member_remove(self, member): if self.config["close_on_leave"]: await thread.close( closer=member.guild.me, - message="The recipient has left the server.", + message=self.config["close_on_leave_reason"], silent=True, ) else: embed = discord.Embed( - description="The recipient has left the server.", color=self.error_color + description=self.config["close_on_leave_reason"], color=self.error_color ) await thread.channel.send(embed=embed) diff --git a/core/config.py b/core/config.py index c4570f93f9..91c50d66f5 100644 --- a/core/config.py +++ b/core/config.py @@ -72,6 +72,7 @@ class ConfigManager: "disabled_current_thread_footer": "Please try again later...", "transfer_reactions": True, "close_on_leave": False, + "close_on_leave_reason": "The recipient has left the server.", "alert_on_mention": False, # moderation "recipient_color": str(discord.Color.gold()), diff --git a/core/config_help.json b/core/config_help.json index 32d8cb58ac..cc941048c5 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -601,7 +601,20 @@ "examples":[ "`{prefix}config set close_on_leave yes`" ], - "notes": [] + "notes": [ + "See also: `close_on_leave_reason`." + ] + }, + "close_on_leave_reason": { + "default": "The recipient has left the server.", + "description": "Reason for closing the thread once member leaves", + "examples":[ + "`{prefix}config set close_on_leave_reason Member left`" + ], + "notes": [ + "This has no effect unless `close_on_leave` is set.", + "See also: `close_on_leave`." + ] }, "alert_on_mention": { "default": "No", @@ -650,7 +663,7 @@ "`{prefix}config set confirm_thread_creation_accept \u2611`" ], "notes": [ - "Has no effect unless `confirm_thread_creation` is set", + "This has no effect unless `confirm_thread_creation` is set", "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_deny`" ] }, @@ -661,7 +674,7 @@ "`{prefix}config set confirm_thread_creation_deny \u26D4`" ], "notes": [ - "Has no effect unless `confirm_thread_creation` is set", + "This has no effect unless `confirm_thread_creation` is set", "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_accept`" ] }, From 2aca7ff9fc6066ed490c43ce70439a7bf89c0945 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Nov 2020 01:15:08 +0800 Subject: [PATCH 128/705] Custom dpy version with stickers, support stickers/pins --- Pipfile | 29 +-- Pipfile.lock | 416 +++++++++++++++++++--------------------- bot.py | 3 + core/thread.py | 12 +- discord.py-1.5.2.tar.gz | Bin 0 -> 649387 bytes pyproject.toml | 2 +- requirements.min.txt | 2 +- 7 files changed, 230 insertions(+), 234 deletions(-) create mode 100644 discord.py-1.5.2.tar.gz diff --git a/Pipfile b/Pipfile index 01485b1e63..fb20f42c21 100644 --- a/Pipfile +++ b/Pipfile @@ -10,19 +10,26 @@ bandit = "==1.6.2" flake8 = "*" [packages] -colorama = ">=0.4.0" -python-dateutil = ">=2.7.0" -emoji = ">=0.2" -uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} -motor = ">=2.0.0" +aiohttp = "==3.6.2" +async-timeout = "==3.0.1" +attrs = "==19.3.0" +chardet = "==3.0.4" +"discord.py" = {path = "discord.py-1.5.2.tar.gz"} +dnspython = "==1.16.0" +emoji = "==0.5.4" +future = "==0.18.2" +idna = "==2.9" +isodate = "==0.6.0" +motor = "==2.1.0" +multidict = "==4.7.6" natural = "==0.2.0" -isodate = ">=0.6.0" -dnspython = "~=1.16.0" parsedatetime = "==2.6" -aiohttp = ">=3.6.0,<3.7.0" -python-dotenv = ">=0.10.3" -pipenv = "*" -"discord.py" = "==1.5.1" +pymongo = "==3.10.1" +python-dateutil = "==2.8.1" +python-dotenv = "==0.14.0" +six = "==1.15.0" +websockets = "==8.1" +yarl = "==1.4.2" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 005ce37f67..d88503c8d8 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0491618cb8bd6d70e4ab3337c23b72fc3b1d5f9ca0603d8be6b890b661039102" + "sha256": "2be2574267d4b75a621fe0a7202531936a02f5bc0cd0a79addf757344a3acb4d" }, "pipfile-spec": 6, "requires": {}, @@ -16,82 +16,55 @@ "default": { "aiohttp": { "hashes": [ - "sha256:1a4160579ffbc1b69e88cb6ca8bb0fbd4947dfcbf9fb1e2a4fc4c7a4a986c1fe", - "sha256:206c0ccfcea46e1bddc91162449c20c72f308aebdcef4977420ef329c8fcc599", - "sha256:2ad493de47a8f926386fa6d256832de3095ba285f325db917c7deae0b54a9fc8", - "sha256:319b490a5e2beaf06891f6711856ea10591cfe84fe9f3e71a721aa8f20a0872a", - "sha256:470e4c90da36b601676fe50c49a60d34eb8c6593780930b1aa4eea6f508dfa37", - "sha256:60f4caa3b7f7a477f66ccdd158e06901e1d235d572283906276e3803f6b098f5", - "sha256:66d64486172b032db19ea8522328b19cfb78a3e1e5b62ab6a0567f93f073dea0", - "sha256:687461cd974722110d1763b45c5db4d2cdee8d50f57b00c43c7590d1dd77fc5c", - "sha256:698cd7bc3c7d1b82bb728bae835724a486a8c376647aec336aa21a60113c3645", - "sha256:797456399ffeef73172945708810f3277f794965eb6ec9bd3a0c007c0476be98", - "sha256:a885432d3cabc1287bcf88ea94e1826d3aec57fd5da4a586afae4591b061d40d", - "sha256:c506853ba52e516b264b106321c424d03f3ddef2813246432fa9d1cefd361c81", - "sha256:fb83326d8295e8840e4ba774edf346e87eca78ba8a89c55d2690352842c15ba5" + "sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", + "sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", + "sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", + "sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", + "sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", + "sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", + "sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", + "sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", + "sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", + "sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", + "sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", + "sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965" ], "index": "pypi", - "version": "==3.6.3" - }, - "appdirs": { - "hashes": [ - "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", - "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" - ], - "version": "==1.4.4" + "version": "==3.6.2" }, "async-timeout": { "hashes": [ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], - "markers": "python_full_version >= '3.5.3'", + "index": "pypi", "version": "==3.0.1" }, "attrs": { "hashes": [ - "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", - "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" + "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", + "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.0" - }, - "certifi": { - "hashes": [ - "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", - "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" - ], - "version": "==2020.6.20" + "index": "pypi", + "version": "==19.3.0" }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" ], + "index": "pypi", "version": "==3.0.4" }, - "colorama": { + "discord-py": { "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + "sha256:5aac5a89eb8d70ba7bb5721ad9b495b437cc46328bab6a9170a4e0f8a568a9e8" ], - "index": "pypi", - "version": "==0.4.4" + "path": "./discord.py-1.5.2.tar.gz", + "version": "==1.5.2" }, "discord.py": { - "hashes": [ - "sha256:2367359e31f6527f8a936751fc20b09d7495dd6a76b28c8fb13d4ca6c55b7563", - "sha256:def00dc50cf36d21346d71bc89f0cad8f18f9a3522978dc18c7796287d47de8b" - ], - "index": "pypi", - "version": "==1.5.1" - }, - "distlib": { - "hashes": [ - "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb", - "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1" - ], - "version": "==0.3.1" + "path": "discord.py-1.5.2.tar.gz" }, "dnspython": { "hashes": [ @@ -103,25 +76,25 @@ }, "emoji": { "hashes": [ - "sha256:e42da4f8d648f8ef10691bc246f682a1ec6b18373abfd9be10ec0b398823bd11" + "sha256:60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174" ], "index": "pypi", - "version": "==0.6.0" + "version": "==0.5.4" }, - "filelock": { + "future": { "hashes": [ - "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", - "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" + "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" ], - "version": "==3.0.12" + "index": "pypi", + "version": "==0.18.2" }, "idna": { "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", + "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.10" + "index": "pypi", + "version": "==2.9" }, "isodate": { "hashes": [ @@ -133,11 +106,12 @@ }, "motor": { "hashes": [ - "sha256:428d94750123d19fcd0a89b8671ff9b4656f205217bad9f44161748c64c5fc80", - "sha256:f1692b760d834707e3477996ce8d407af8cd61c1a2abedbf81c22ef14675e61a" + "sha256:599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", + "sha256:756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", + "sha256:97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a" ], "index": "pypi", - "version": "==2.3.0" + "version": "==2.1.0" }, "multidict": { "hashes": [ @@ -159,7 +133,7 @@ "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" ], - "markers": "python_version >= '3.5'", + "index": "pypi", "version": "==4.7.6" }, "natural": { @@ -177,73 +151,67 @@ "index": "pypi", "version": "==2.6" }, - "pipenv": { - "hashes": [ - "sha256:448ac3a36443db633d52a2359cac15ecbc4f429eab4ddd420697602b721d1c5a", - "sha256:eff0e10eadb330f612edfa5051d3d8e775e9e0e918c3c50361da703bd0daa035" - ], - "index": "pypi", - "version": "==2020.8.13" - }, "pymongo": { "hashes": [ - "sha256:03dc64a9aa7a5d405aea5c56db95835f6a2fa31b3502c5af1760e0e99210be30", - "sha256:05fcc6f9c60e6efe5219fbb5a30258adb3d3e5cbd317068f3d73c09727f2abb6", - "sha256:076a7f2f7c251635cf6116ac8e45eefac77758ee5a77ab7bd2f63999e957613b", - "sha256:137e6fa718c7eff270dbd2fc4b90d94b1a69c9e9eb3f3de9e850a7fd33c822dc", - "sha256:1f865b1d1c191d785106f54df9abdc7d2f45a946b45fd1ea0a641b4f982a2a77", - "sha256:213c445fe7e654621c6309e874627c35354b46ef3ee807f5a1927dc4b30e1a67", - "sha256:25e617daf47d8dfd4e152c880cd0741cbdb48e51f54b8de9ddbfe74ecd87dd16", - "sha256:3d9bb1ba935a90ec4809a8031efd988bdb13cdba05d9e9a3e9bf151bf759ecde", - "sha256:40696a9a53faa7d85aaa6fd7bef1cae08f7882640bad08c350fb59dee7ad069b", - "sha256:421aa1b92c291c429668bd8d8d8ec2bd00f183483a756928e3afbf2b6f941f00", - "sha256:4437300eb3a5e9cc1a73b07d22c77302f872f339caca97e9bf8cf45eca8fa0d2", - "sha256:455f4deb00158d5ec8b1d3092df6abb681b225774ab8a59b3510293b4c8530e3", - "sha256:475a34a0745c456ceffaec4ce86b7e0983478f1b6140890dff7b161e7bcd895b", - "sha256:4797c0080f41eba90404335e5ded3aa66731d303293a675ff097ce4ea3025bb9", - "sha256:4ae23fbbe9eadf61279a26eba866bbf161a6f7e2ffad14a42cf20e9cb8e94166", - "sha256:4b32744901ee9990aa8cd488ec85634f443526def1e5190a407dc107148249d7", - "sha256:50127b13b38e8e586d5e97d342689405edbd74ad0bd891d97ee126a8c7b6e45f", - "sha256:50531caa7b4be1c4ed5e2d5793a4e51cc9bd62a919a6fd3299ef7c902e206eab", - "sha256:63a5387e496a98170ffe638b435c0832c0f2011a6f4ff7a2880f17669fff8c03", - "sha256:68220b81850de8e966d4667d5c325a96c6ac0d6adb3d18935d6e3d325d441f48", - "sha256:689142dc0c150e9cb7c012d84cac2c346d40beb891323afb6caf18ec4caafae0", - "sha256:6a15e2bee5c4188369a87ed6f02de804651152634a46cca91966a11c8abd2550", - "sha256:7122ffe597b531fb065d3314e704a6fe152b81820ca5f38543e70ffcc95ecfd4", - "sha256:7307024b18266b302f4265da84bb1effb5d18999ef35b30d17592959568d5c0a", - "sha256:7a4a6f5b818988a3917ec4baa91d1143242bdfece8d38305020463955961266a", - "sha256:83c5a3ecd96a9f3f11cfe6dfcbcec7323265340eb24cc996acaecea129865a3a", - "sha256:890b0f1e18dbd898aeb0ab9eae1ab159c6bcbe87f0abb065b0044581d8614062", - "sha256:8deda1f7b4c03242f2a8037706d9584e703f3d8c74d6d9cac5833db36fe16c42", - "sha256:8ea13d0348b4c96b437d944d7068d59ed4a6c98aaa6c40d8537a2981313f1c66", - "sha256:91e96bf85b7c07c827d339a386e8a3cf2e90ef098c42595227f729922d0851df", - "sha256:96782ebb3c9e91e174c333208b272ea144ed2a684413afb1038e3b3342230d72", - "sha256:9755c726aa6788f076114dfdc03b92b03ff8860316cca00902cce88bcdb5fedd", - "sha256:9dbab90c348c512e03f146e93a5e2610acec76df391043ecd46b6b775d5397e6", - "sha256:9ee0eef254e340cc11c379f797af3977992a7f2c176f1a658740c94bf677e13c", - "sha256:9fc17fdac8f1973850d42e51e8ba6149d93b1993ed6768a24f352f926dd3d587", - "sha256:a2787319dc69854acdfd6452e6a8ba8f929aeb20843c7f090e04159fc18e6245", - "sha256:b7c522292407fa04d8195032493aac937e253ad9ae524aab43b9d9d242571f03", - "sha256:bd312794f51e37dcf77f013d40650fe4fbb211dd55ef2863839c37480bd44369", - "sha256:c0d660a186e36c526366edf8a64391874fe53cf8b7039224137aee0163c046df", - "sha256:c4869141e20769b65d2d72686e7a7eb141ce9f3168106bed3e7dcced54eb2422", - "sha256:cc4057f692ac35bbe82a0a908d42ce3a281c9e913290fac37d7fa3bd01307dfb", - "sha256:cccf1e7806f12300e3a3b48f219e111000c2538483e85c869c35c1ae591e6ce9", - "sha256:ce208f80f398522e49d9db789065c8ad2cd37b21bd6b23d30053474b7416af11", - "sha256:d0565481dc196986c484a7fb13214fc6402201f7fb55c65fd215b3324962fe6c", - "sha256:d1b3366329c45a474b3bbc9b9c95d4c686e03f35da7fd12bc144626d1f2a7c04", - "sha256:d226e0d4b9192d95079a9a29c04dd81816b1ce8903b8c174a39224fe978547cb", - "sha256:d38b35f6eef4237b1d0d8e845fc1546dad85c55eba447e28c211da8c7ef9697c", - "sha256:d64c98277ea80e4484f1332ab107e8dfd173a7dcf1bdbf10a9cccc97aaab145f", - "sha256:d9de8427a5601799784eb0e7fa1b031aa64086ce04de29df775a8ca37eedac41", - "sha256:e6a15cf8f887d9f578dd49c6fb3a99d53e1d922fdd67a245a67488d77bf56eb2", - "sha256:e8c446882cbb3774cd78c738c9f58220606b702b7c1655f1423357dc51674054", - "sha256:e8d188ee39bd0ffe76603da887706e4e7b471f613625899ddf1e27867dc6a0d3", - "sha256:ef76535776c0708a85258f6dc51d36a2df12633c735f6d197ed7dfcaa7449b99", - "sha256:f6efca006a81e1197b925a7d7b16b8f61980697bb6746587aad8842865233218" + "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", + "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", + "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", + "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", + "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", + "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", + "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", + "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", + "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", + "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", + "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", + "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", + "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", + "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", + "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", + "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", + "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", + "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", + "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", + "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", + "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", + "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", + "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", + "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", + "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", + "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", + "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", + "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", + "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", + "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", + "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", + "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", + "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", + "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", + "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", + "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", + "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", + "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", + "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", + "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", + "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", + "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", + "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", + "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", + "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", + "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", + "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", + "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", + "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", + "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", + "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", + "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", + "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", + "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", + "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", + "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==3.11.0" + "index": "pypi", + "version": "==3.10.1" }, "python-dateutil": { "hashes": [ @@ -266,62 +234,59 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "index": "pypi", "version": "==1.15.0" }, - "uvloop": { - "hashes": [ - "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", - "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", - "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", - "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", - "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", - "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", - "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", - "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", - "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362" - ], - "markers": "sys_platform != 'win32'", - "version": "==0.14.0" - }, - "virtualenv": { - "hashes": [ - "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2", - "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380" + "websockets": { + "hashes": [ + "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", + "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", + "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", + "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", + "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", + "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", + "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", + "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", + "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", + "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", + "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", + "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", + "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", + "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", + "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", + "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", + "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", + "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", + "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", + "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", + "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", + "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.1.0" - }, - "virtualenv-clone": { - "hashes": [ - "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", - "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.5.4" + "index": "pypi", + "version": "==8.1" }, "yarl": { "hashes": [ - "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", - "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593", - "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2", - "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8", - "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d", - "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692", - "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02", - "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a", - "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8", - "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6", - "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511", - "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e", - "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a", - "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb", - "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f", - "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", - "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" + "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", + "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", + "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", + "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", + "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", + "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", + "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", + "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", + "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", + "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", + "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", + "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", + "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", + "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", + "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", + "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", + "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2" ], - "markers": "python_version >= '3.5'", - "version": "==1.5.1" + "index": "pypi", + "version": "==1.4.2" } }, "develop": { @@ -342,11 +307,11 @@ }, "attrs": { "hashes": [ - "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", - "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" + "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", + "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.0" + "index": "pypi", + "version": "==19.3.0" }, "bandit": { "hashes": [ @@ -377,7 +342,7 @@ "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], - "index": "pypi", + "markers": "platform_system == 'Windows' and sys_platform == 'win32'", "version": "==0.4.4" }, "flake8": { @@ -503,42 +468,58 @@ }, "regex": { "hashes": [ - "sha256:0cb23ed0e327c18fb7eac61ebbb3180ebafed5b9b86ca2e15438201e5903b5dd", - "sha256:1a065e7a6a1b4aa851a0efa1a2579eabc765246b8b3a5fd74000aaa3134b8b4e", - "sha256:1a511470db3aa97432ac8c1bf014fcc6c9fbfd0f4b1313024d342549cf86bcd6", - "sha256:1c447b0d108cddc69036b1b3910fac159f2b51fdeec7f13872e059b7bc932be1", - "sha256:2278453c6a76280b38855a263198961938108ea2333ee145c5168c36b8e2b376", - "sha256:240509721a663836b611fa13ca1843079fc52d0b91ef3f92d9bba8da12e768a0", - "sha256:4e21340c07090ddc8c16deebfd82eb9c9e1ec5e62f57bb86194a2595fd7b46e0", - "sha256:570e916a44a361d4e85f355aacd90e9113319c78ce3c2d098d2ddf9631b34505", - "sha256:59d5c6302d22c16d59611a9fd53556554010db1d47e9df5df37be05007bebe75", - "sha256:6a46eba253cedcbe8a6469f881f014f0a98819d99d341461630885139850e281", - "sha256:6f567df0601e9c7434958143aebea47a9c4b45434ea0ae0286a4ec19e9877169", - "sha256:781906e45ef1d10a0ed9ec8ab83a09b5e0d742de70e627b20d61ccb1b1d3964d", - "sha256:8469377a437dbc31e480993399fd1fd15fe26f382dc04c51c9cb73e42965cc06", - "sha256:8cd0d587aaac74194ad3e68029124c06245acaeddaae14cb45844e5c9bebeea4", - "sha256:97a023f97cddf00831ba04886d1596ef10f59b93df7f855856f037190936e868", - "sha256:a973d5a7a324e2a5230ad7c43f5e1383cac51ef4903bf274936a5634b724b531", - "sha256:af360e62a9790e0a96bc9ac845d87bfa0e4ee0ee68547ae8b5a9c1030517dbef", - "sha256:b706c70070eea03411b1761fff3a2675da28d042a1ab7d0863b3efe1faa125c9", - "sha256:bfd7a9fddd11d116a58b62ee6c502fd24cfe22a4792261f258f886aa41c2a899", - "sha256:c30d8766a055c22e39dd7e1a4f98f6266169f2de05db737efe509c2fb9c8a3c8", - "sha256:c53dc8ee3bb7b7e28ee9feb996a0c999137be6c1d3b02cb6b3c4cba4f9e5ed09", - "sha256:c95d514093b80e5309bdca5dd99e51bcf82c44043b57c34594d9d7556bd04d05", - "sha256:d43cf21df524283daa80ecad551c306b7f52881c8d0fe4e3e76a96b626b6d8d8", - "sha256:d62205f00f461fe8b24ade07499454a3b7adf3def1225e258b994e2215fd15c5", - "sha256:e289a857dca3b35d3615c3a6a438622e20d1bf0abcb82c57d866c8d0be3f44c4", - "sha256:e5f6aa56dda92472e9d6f7b1e6331f4e2d51a67caafff4d4c5121cadac03941e", - "sha256:f4b1c65ee86bfbf7d0c3dfd90592a9e3d6e9ecd36c367c884094c050d4c35d04" - ], - "version": "==2020.10.23" + "sha256:03855ee22980c3e4863dc84c42d6d2901133362db5daf4c36b710dd895d78f0a", + "sha256:06b52815d4ad38d6524666e0d50fe9173533c9cc145a5779b89733284e6f688f", + "sha256:11116d424734fe356d8777f89d625f0df783251ada95d6261b4c36ad27a394bb", + "sha256:119e0355dbdd4cf593b17f2fc5dbd4aec2b8899d0057e4957ba92f941f704bf5", + "sha256:127a9e0c0d91af572fbb9e56d00a504dbd4c65e574ddda3d45b55722462210de", + "sha256:1ec66700a10e3c75f1f92cbde36cca0d3aaee4c73dfa26699495a3a30b09093c", + "sha256:227a8d2e5282c2b8346e7f68aa759e0331a0b4a890b55a5cfbb28bd0261b84c0", + "sha256:2564def9ce0710d510b1fc7e5178ce2d20f75571f788b5197b3c8134c366f50c", + "sha256:297116e79074ec2a2f885d22db00ce6e88b15f75162c5e8b38f66ea734e73c64", + "sha256:2dc522e25e57e88b4980d2bdd334825dbf6fa55f28a922fc3bfa60cc09e5ef53", + "sha256:3a5f08039eee9ea195a89e180c5762bfb55258bfb9abb61a20d3abee3b37fd12", + "sha256:3dfca201fa6b326239e1bccb00b915e058707028809b8ecc0cf6819ad233a740", + "sha256:49461446b783945597c4076aea3f49aee4b4ce922bd241e4fcf62a3e7c61794c", + "sha256:4afa350f162551cf402bfa3cd8302165c8e03e689c897d185f16a167328cc6dd", + "sha256:4b5a9bcb56cc146c3932c648603b24514447eafa6ce9295234767bf92f69b504", + "sha256:52e83a5f28acd621ba8e71c2b816f6541af7144b69cc5859d17da76c436a5427", + "sha256:625116aca6c4b57c56ea3d70369cacc4d62fead4930f8329d242e4fe7a58ce4b", + "sha256:654c1635f2313d0843028487db2191530bca45af61ca85d0b16555c399625b0e", + "sha256:8092a5a06ad9a7a247f2a76ace121183dc4e1a84c259cf9c2ce3bbb69fac3582", + "sha256:832339223b9ce56b7b15168e691ae654d345ac1635eeb367ade9ecfe0e66bee0", + "sha256:8ca9dca965bd86ea3631b975d63b0693566d3cc347e55786d5514988b6f5b84c", + "sha256:96f99219dddb33e235a37283306834700b63170d7bb2a1ee17e41c6d589c8eb9", + "sha256:9b6305295b6591e45f069d3553c54d50cc47629eb5c218aac99e0f7fafbf90a1", + "sha256:a62162be05edf64f819925ea88d09d18b09bebf20971b363ce0c24e8b4aa14c0", + "sha256:aacc8623ffe7999a97935eeabbd24b1ae701d08ea8f874a6ff050e93c3e658cf", + "sha256:b45bab9f224de276b7bc916f6306b86283f6aa8afe7ed4133423efb42015a898", + "sha256:b88fa3b8a3469f22b4f13d045d9bd3eda797aa4e406fde0a2644bc92bbdd4bdd", + "sha256:b8a686a6c98872007aa41fdbb2e86dc03b287d951ff4a7f1da77fb7f14113e4d", + "sha256:bd904c0dec29bbd0769887a816657491721d5f545c29e30fd9d7a1a275dc80ab", + "sha256:bf4f896c42c63d1f22039ad57de2644c72587756c0cfb3cc3b7530cfe228277f", + "sha256:c13d311a4c4a8d671f5860317eb5f09591fbe8259676b86a85769423b544451e", + "sha256:c2c6c56ee97485a127555c9595c069201b5161de9d05495fbe2132b5ac104786", + "sha256:c32c91a0f1ac779cbd73e62430de3d3502bbc45ffe5bb6c376015acfa848144b", + "sha256:c3466a84fce42c2016113101018a9981804097bacbab029c2d5b4fcb224b89de", + "sha256:c454ad88e56e80e44f824ef8366bb7e4c3def12999151fd5c0ea76a18fe9aa3e", + "sha256:c8a2b7ccff330ae4c460aff36626f911f918555660cc28163417cb84ffb25789", + "sha256:cb905f3d2e290a8b8f1579d3984f2cfa7c3a29cc7cba608540ceeed18513f520", + "sha256:cfcf28ed4ce9ced47b9b9670a4f0d3d3c0e4d4779ad4dadb1ad468b097f808aa", + "sha256:dd3e6547ecf842a29cf25123fbf8d2461c53c8d37aa20d87ecee130c89b7079b", + "sha256:de7fd57765398d141949946c84f3590a68cf5887dac3fc52388df0639b01eda4", + "sha256:ea37320877d56a7f0a1e6a625d892cf963aa7f570013499f5b8d5ab8402b5625", + "sha256:f1fce1e4929157b2afeb4bb7069204d4370bab9f4fc03ca1fbec8bd601f8c87d", + "sha256:f43109822df2d3faac7aad79613f5f02e4eab0fc8ad7932d2e70e2a83bd49c26" + ], + "version": "==2020.10.28" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "index": "pypi", "version": "==1.15.0" }, "smmap": { @@ -559,10 +540,11 @@ }, "toml": { "hashes": [ - "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", - "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "version": "==0.10.1" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "version": "==0.10.2" }, "typed-ast": { "hashes": [ diff --git a/bot.py b/bot.py index 57a511233e..daf1f593c1 100644 --- a/bot.py +++ b/bot.py @@ -746,6 +746,9 @@ async def process_dm_modmail(self, message: discord.Message) -> None: if blocked: return sent_emoji, blocked_emoji = await self.retrieve_emoji() + + if message.type != discord.MessageType.default: + return thread = await self.threads.find(recipient=message.author) if thread is None: diff --git a/core/thread.py b/core/thread.py index 1d1fc2f65c..426b76489d 100644 --- a/core/thread.py +++ b/core/thread.py @@ -780,7 +780,7 @@ async def send( url=f"https://discordapp.com/users/{author.id}#{message.id}", ) - ext = [(a.url, a.filename) for a in message.attachments] + ext = [(a.url, a.filename, False) for a in message.attachments] images = [] attachments = [] @@ -796,11 +796,12 @@ async def send( ) image_urls = [ - (is_image_url(url, convert_size=False), None) + (is_image_url(url, convert_size=False), None, False) for url in image_urls if is_image_url(url, convert_size=False) ] images.extend(image_urls) + images.extend((str(i.image_url), f'{i.name} Sticker', True) for i in message.stickers) embedded_image = False @@ -809,11 +810,14 @@ async def send( additional_images = [] additional_count = 1 - for url, filename in images: + for url, filename, is_sticker in images: if not prioritize_uploads or (is_image_url(url) and not embedded_image and filename): embed.set_image(url=url) if filename: - embed.add_field(name="Image", value=f"[{filename}]({url})") + if is_sticker: + embed.add_field(name=filename, value=f"\u200b") + else: + embed.add_field(name="Image", value=f"[{filename}]({url})") embedded_image = True elif filename is not None: if note: diff --git a/discord.py-1.5.2.tar.gz b/discord.py-1.5.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..79619c9a8e36cfde75e22f715d15cf4a4bdcbdc0 GIT binary patch literal 649387 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
    9I&RraX-kD2 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

    -O5Ah2?Whk$Eqb;`t%vP zI#g{zUod%=vZdKp4_9fo-a{Z6&!@IO|5?f7XFrhW3@cpGp z3>Vvg5?-4mv<1JPWTJ-0mrKI3Jj~$eB(Wwb{=GX%v?L9$pSTQafaTygV(m;Z-^ky) zg3k`ZzUEnzk%eWwNhA^vqMCCluWvAWsP{orNt1CG1F&ZYAsSbFi8ar0Lbfu7&Nc3t zLb88_Xu}Z|aB+HvUc|C}eDJYm#9=?igrI&hwd6s`Ccm&ADsX>kyJl=`;Ed$e z^;doG%8duuqH`CT3>a!&CTKXIoV}b(-FnL(fxZ3b`8+5rmcHgDiWi*d6%@ z-J$W{F$ga}I3VFww_A~p(|dZ~OgD@{Ks-Cc=4t+?#Y719@se$}7of;IU_KaCTgqVrf&X~d(AV4-= zaMidSsn^Zdqp!M=*xVs#vh2$s9+o(2rU9#C2m~iEqKon>qHBTh8`QOs;n--J@@qzU zS!&M6PSR#YFYmZiFAwH43{w2A0`Y}2^=0#QK`mupf;ZTAo#}69at^JS_9rPB9;wY+KpA~9FS9U>KjMUP{+97 z&k5-0k717NwLe6EG*~?K(fwhDF9g>r3OJ5tH0i1)9`ht)+RD8I;xs~cg=O@o(&45n zt)HGLc!obN`m`!ZWlk!q+(|_NloLf!80ZiB5|Lk@gvZTZ#E;Q@=R_rQ<%;^f7#GUK zl^m;N*U7GxSHl#PjhTjXW&aoHlAiN)QPVZ7#<8 z)2kCky{axOLw-BFdx$!;j63vK;6VcfN00TgNbps6zeD&yrsy|zP;PX<10nwJQzr|R zHq3fTj}xCpovq3To3_f$(L4RIBeh@C!n@v`q->cu}fpRpyG( zv_{@13M;y6s_#_fWtieTX%otHVW|JAWx@;q_!ozrH7px`Rxc zkG7bPlD#g!{9?O0u5F&~*fRXdQ)c;GU46uc$8&YZqu8OU@0~S|vWUCj#(Ikhw0u8(Cn6B3!klQ`CRp>;1R9L%#SEMuZ}ool!2Zv(^ zVWx=g)y}Z41eIBnCy3j1IcF&tV_R5X^O_HpwJWc(w+j1N{EJKt$=kJSiH?ka*=~cf zM>Ab^;&n#~MG{X0l%@e*XH;aYTWt4c>6BldQM8`AR-}k+(H!|it7`&_6@3ZxsAO8| zu5qdHp9(Q@mk4kV|FyVS4}_;(#unhbiq@L3lSw}Sox62XSJ;K|A`E|!y_+pR z-h?@Phg~E~g~Z=be@`28ElslsJtdxMCX~d&J}Uvrj5wc;JOMdov?(UM#1edny1@4A zN4*uiCx`dPatQ#jnVN93&NNq^Iwq$&Gh_MA$VW8rl*vFXqrsQucoDO08)l}*Zke{I z?kX`8KMrP07<_?t4B+n_qv7wP0{(VK4qN=QP_kT4m4M!Fv#}lw)B{XU{Z-}cLk+Ca0*tF!iHkP4K)EIjXE4^x zEV3vsH_I!`@+Zym-bfghLHDE3}GLHqDam9i_%eyNNq>5W3-LhSr5U9A9b(|C(R82#c7W4P+T zpkyNqv-Aj{b+HM>nG84P7ofl0AjZvVTr-*nC1LVyw&yQB2%Rgkgl7Du$7vJl006*K z028n?;jL@hlFS6K=-^bP*;JB-u?SW88c$?Pq3Gj2M zD$s%pjaiR~_}yiLfwKn!$-{Qq&LMA)CN&`+SA3P*6EGZ;!6`A*Le$Ny*|!>wJe7)w zP+s~D9?h9aSMU2{8R7v5OnQ#h{7Xo0Eltodguu%s6UDFYA~NGs2SkHOdY*v*4l|da zGg5`=b~##!{HNChWkB!sLx6&JGPJl=tylq@f4dhEImjZ#ajX2F6x(qn2ySKi5+R8)^X!<5W5B8W}%}c@*2+K zOoZ$SND1UY_if-Amt(y{?0r~#5;iu+!IQY=eCjt=OUVB6v0eD&lm$4R0hTwY9}ZpH zMxf_)VOh|=&~WU6(GRr<54ZyQEdY{0ZNC~zed(b8obD@C5b$AKyXk*_q(?+3(0hVZ zh07-P08u*FuGCkjOEbRN&!Oq)?q5*b2C+?Lm)OU&o*0}2EiGLvr9YKDRP}kfnKnk; zR62lC&31{KtLTXAq4hjlt;n7a&=tQvgz5fF=^Q#K-+hA0S_FSu)l1hqQPxz=mJQKI zKw`H0V`l)3JLLKyGXr}$?1yH9r$T=wb9X=|?4$~4sFiO}J8h!UiY5S1C$Bb*YHoqz zYgw~9)_!uHTsZ3!Irf&Ndew}D{eJj12WwgYq4?{8=q{QOs-hsk zpr3v{? zrXhIiq3{6hxkx*J-6?G8cZ43v#Hb#DQDG0z#0m+4Ry`J4^;l@tW1&@#g;qTlTJ>0H z)nlU7x}B-f1Sb}AC;psbtr4|%H_b{_pIFS>uwEqzdHvTU4nS4X|KK;Vi1M8`PVAR# zH46aM-s1Qd=^3n{Wh>tv+K$+UG!KQoi#K2T1tMa_vZWUcakQhz3rK!Z%+)D7B(ZUy z+u6&hY+hyXSX)B-r7949lVH$Z)q75pb_a~bZxv+aovmh?wnPD>p?%n18Yl%U85ZjM zXQfzsbi}k^UwuOdT2hdbt%5~dJ zJ-9Xq5y(fJJzM=L3>TTgY~Dnl9ZToXgVA$&a^s^cxm+;F%kTAwNTT6X#*>n)a6(21yov|K_L^`2Fen*$cCO(tKHiXP_VI^Ws8R z&U$g*11w%LQ4snM^P1cEZzYDX+Z<0hZn}jlK!tdSSAa*#`!88EXpR}3@6L{MJ&hB_ z={ChjETtHz*@Ux>{uHe4#wrAu0ux5vYKN+_*PECth@pfr-1JOq*hA@<@(jk^w|7*576th$q4>PTl4miv7jHkSHPG%2=RQ# zn+)h}+5Ihh_E5#Htc|BI=EUBrFjayTO=v=6GZIJ8*B04J&BNXkNiMS;h&(JJnS$s~ z*aXqP)+UI47LIz;!dq=^9}C&1$(MEw2ZK7(Hf( zYhW6aH#Dn^8EgKK2cZS$7eKX7rV=FN?jH|@t5{pYrE^%gw$t9MRm|S9ciOD4{D>1pm z6}X5KmHib{j#whN!;TV@ZZ8pOo{$A@p5fS`8d{NRxH&{(vNunapP`oN+vuzO<1&7W zNi(+olKrD@7@sY1%JrTC$S5rd3`^j~+H5PoqlLTmgVwEP%*`O}C&7E763~r+o(y>R zALHQIbdqK`eFys-M**y1&rG>A-xBAuf0h&?j%HYEPoTxRtRO~oF_tA zb)J&1PgcBtNht$l}5U#)fG@unkfVZ2F+jUEPPp?1a_DgLGNFNdWxm zF2X}p)oubO+MrxAaS0VZbh%uzpZ4%WGQH5r`*a5kUYZ0PVuQc7$o5e9Q^>c>V{yIS)CyX%X!44^n8U0iyQy)DdAV+KL$AudT%~0 z%UHpA(YYAI@KZA$1)0udj`EU+RU$n+sWol{7b;fZSb0ZiDD$$1CwG8O%F=okdZm5| z^CDwWFAEd6Jhg!yfyWmopBT=BW-M`+f>?&>@ZC&YK>tkCkIdF4;$kE|YqAti!Lfg) zzl+DN5||SRw`#W)e-7x$$;Nf`1m@UnLQ7l$h*Y>>P`epyMdWF%u9Z1@-;f-0(vxkP zX*{y;FOsF155{c6BCX0M(=vo5t{g#qY~&qy^?wDE7b;e^VOoqDn*&>E1?OTrVcJrb zrM68r!;0_-!2|yjHAEz1kG%dnlS~&^8&wrM1Cpjzh4JIVAJEIj!i;GY44-mhsg7MH zSTdIyo5pW_ZxX!37q5k-ow0bbOVR0?jznouD4zo_?JU%E*i290cwS|T@NejP2HCF2zMAx{=D5^YIN>tLPFI_LOgo`CCC8krL z6UIVo?ODiGpvh{AjoL6IW4_q=;9aJ4ej-vYYeZ7cv#Yv*qx4{f0>u%+8tN_PDM+XO z<1=DztK2KF*_&bq`3T7Mzve*8AH!IB_9A2YkwEf8`>`+HYN*#iRg26Vgi7l*sX5>~ z(^~&H4mtkStkC2gSJN1jZKD38U>7V0mx0tr)EF3z1W@^df3%JwRhjzyXW)-3SQp9% zPc&w>M2DhJw8oZ5a^X|lW@M9Ax9drEcWafvN?@dN?3#>-V5C_{L?t@EzeE`J9QVf# z)>c^vfaVwla{W^@!=3#W#*qEuxh{U#)*Ii_*%D9K;A7u6C1w||t3JjTmAwQhmVTl{ zGY+|a;{@;(GyZv!-S%>xFo=MTnbWq^|7L>dOc!rrg?2F`?xCX+1GQcOLCz@KAy0sJ z!#)Jw6p6KwY=o#IwEGu&KVZ}tY{5L+_@@jEnYA#Fyvkjs#*58ta+_$Y%x!gmfw0vw zj#!8cAEoVDxKok0+vtb}4QE$C>RV_yf1*mg3yh+lXj?U@L-D;ykf^?%r@NC;%A*8t zp+^e&x+DKded(k94avG=z1~fW+ah~l8}{uX`Ia72rKH0n;cVm}11UwmekV`g*4rdl z#T|esVW(=Xgl8YD$l&3d08Q=rfM826!Lhesj9l;TD`90r6`U)k3I~Wv7#rswO-trq+CUKJ9kdlTziygq&|VEidlV@np$Sc}c4(-|@P9 zM<2ujvx9m{u0JipGC0z|Lj)(ior5ZVk&aa@91>x( z^75rfgx#tf+^6~aptvd@MIxBwM=n`F*KIl19a(Y#+1*obZOCL|2jzx;I}4YIJ^Dd( zuN=8H4JDIHv>?&BpcRs=^My-!gQh1VhtvOX7G8iu8M!`Fz>|0P$t={dRzNPCDQ|p^ zvk+x!7lOTC!IEH5h%dRATA}^^5=*G1U5arF^zG{$@^-&XmHMLnvLY``G9Z-~C4ne| z(k`7i9bZ@EAd8MmIJSpNeu3Z?5l`$%0Xnd(VP+{4#!Pg2ETYq65uF~3==4}br^g~X zJr>dFv4~EOMRa-u(Fvtp$tW4h|F4VQ@_)GKVsX!!i<|uH|NY{|=-XlHH#nA!b#O=I z7JmHF8CCByiVjL=2$<9u(54cE)G)Lr`(H(+nNyw7iwHFf#JGpPVYxoLg^BtdvUZE!zMU+K@eUj-7>-?K32u&J1-SusWRES6;Lz2j%%nHk~Oc-*lVdqnTh z&YD=T!+L?4w`i)!Qg1Jmx3BsE$BkM!SKeOp1CBvb2KuRjK=HPq-sjf`74K=PLNS7F ziM9;QH0WdMbg_u);YmF>cPOL!hSuD~0jNUZoqqig`&kk1OB-kb^0nm&y;8^vn?yU} zArpZHx?LGW;NznZ^39jGFa80%leAzsD3s0UWH2vCGix}B-XWwRsWco~rlR$%%7wX1 zp)kGE;HmlvRa=B?J(_P%q$8L|NQot|b z=S+{-xL6EmTwI)+_c>lsumBi0?Q+sA?N+{cJO|Lr%tKf z_82_7p6345-VI^kO7!Snf*HbLNX<|W#JXy4wRD8U86sRYEltr>%l}{Ao~L@-kOk9OFV;uG`q*>Vr>Tf- z5DAT6v_5oOKD;&`4heyTMNiS{Rlt??;lq;9kFUT<=5R*!&*t#~{YCzWlc`xJv)lp@ zh$vNh#yaoB@G0^$`*1ptW<8pkaE#;2`JOXlq`R&gI0UIiMX$VJo>1d$W3#sV3HHvo zDxd9<5Bf`wX!jk*0H|)kam@ITzT=1&&>qz7LLsx9jv@8 z35`QVNI&E+Js2=nIf`=q!H60-C^z0?ntT&EHPOalQoo1?a1YxeppV{W$_v2<7D-S{ zST}YpAH6YkKOm1vn&pQJ?QA$qNbUm6(@k6FJ?xgsPO|KQ(aI65E}usm_6Dg>^>wV7 zfH+u!%zrPyXAh}}-;`tJ8AuT%ICS3xQ~THz&_NPJA=Dj#44tvIac3qFZozri5Php0 z^Rb2Vnz>g5jjEqIXiL`|yUKS!e{an=#n+|3qsXC?dMThsP-+YK_SAUf?Jnt@;ybWv zKfORFa8)n8{*D|xWxk|8KpS{Zq(^>{>4oPQ%~#)`x@)TSF&2hb8*HVC^cAMd5Bj#y zaB!}((yo+xiwGqLBE(MX%QvD!j*}RR*kPu4kB9jiu51)P5&V5 zvGh1PhKAGj@*PW-EYaJN1J|5A>fMdt$ke}d#VHU4CT|~~vd7Nnulx&)iKaKvquCC- zjkb%OZBgR+X-PQ!E=#}JKjKpY6`!AXAmvc7r9F00e&t2$4R29{FAL-Adiz!3^<*f zf(->Gr|?5OoxMGc+y3k=(n-L9#=IR2`g$VU<{L$iK-`b)Ghc;txHRGSc5=Gc!}f)y z&Lb!hC$!r#0TtvE15PMwQYbatKB16VPBRI}w_1CiD&vupXvOVRy zY)6H)KVF2+FiZ8MHJ$8d}Ep`{kjepB1dq}a9?LZ7_=A{Yblp045E#{S8amQxE&M8IRz-)bI_ z%X2L&2!=B{s+Y*;`0b$a9fyW|j%Qdy8895Ph-JBvEgwrAyhNJb9MZexlC}r0hL$dy z(Q)2j$jsc80Z8=zX^swFcI<%ME=Mr9iOsNIzC{gbSxJs9jlPiaVTg^drhQt zbh`q2f8cD-0%Q6Wi;QW}fJo{1R#5M#2?vCGud`0kcgZCa9{f0VX62pqz%Puz`VmsY zdCZUPTZg`0<&Qg~3M(H9k=s!ZS~(s2Gm-s5E?4NRQ}yZVL=%xGvKa+I80Efj>|M)$ zD>ol*-6vDW2sxEd9X;R2W@E3}L|BZNOZ*yUl#NHsARAAZF*bf}hS>PM8DZmjGr-1c z@VtXdhP=J(3qd{B$2wV~mn~k5e%91Jp;61Nv3|mtPZAVsjit;hecfpnBqcB0dsTd0 z3W0d#?d4Z1$q&Y>_r>rL4D|KbUbfIk2|p&&g{kj?WRrKyDmQ+PcNG1kYBZJ)ayp`S z^vFH>^L;Sr>(n1PZO6w3qzAKN z`n?@0)xHK1)Tq@M#|hLq=(B1({6~&a>YqskwmkkIp?Z^?W38jE$wqUlYfe?S>E({P zw9Qs*15N@6r$a<|H_{VdeUBFR&omw_M-nAteR)02M<;d8tV)sg=$)b_Rj+XB1yqw# zckH67I$?^!(@v;%?aFH$bcfm3!VNISjc@vd<10LZaBt&7;RJ!Fm`G02+n4%D3G0U- zSY~cXk3m#%Yc?tJ_ePidJ=yBlieP9twapQ4D}?R(Tv(JX?oV7IyoLF7nHFxML#xuI zHe3<=yb(3`-ASw}8pkMGYmN0-5e-%O{+s0<$>wcha)D@OeTiH56T*wR#&E^N{=|5H z>oFmh6ZxWF6JeyE7jCUj6eIe?IlaI0+=L~w3H-52f7TuGqE{5c{DUshoZi`aPSN)z z2kc7nW0x}SO=ax`yIfxe@oqd;HU?XI);7AFJto_Rh_9i>o!dBT9YHidvCfZ~$?OP) zDc!w(9ZAI%B+NT|4*BbX@-t0HRW{cs+QlSpIFamiojrie-AFTzJlY*EBdHuw5UqM= zcLqjf$d=-VAkM|f<|G@SR{ej8(D!ovKRU5t5}bLl*^eZ9&7+g-p)axaY}&;(Gwot~ zPTEC6{bt(5JxcfC$5dEZbQ1!N1%k%mE-`CPG*Je)^|2Cizz#)rgv zP0_SVZa6|c?mow+SJ8oDIn<%(=gifo*%+%3tR#X$jc?*;<(=nM{fQJW;tyX-vE2Av zUbVbppG|HYpuy>nuvc#U2>=(xSa3m$FDct5OrGyoqkTaHAzIPqtCnYbh>HK`4i~O= z)71&O`ue2gUIMY};7LwEzirj-IM?U*b*x^d7@8D}Gt>%&yMys3#0G5-c-vULFC~L{ z{<5roKM;240W-&-qB|NyFa+f$4z9QAPzMR^C= zBA=s4jg@mCzYNW7zn09nh&#qw;~1&5M&1+Aw4HigTT0#RVCBsc4_*(qL*6Uza4euN zTg?vXh9Ze<1&K8u)Sbg#k?a3n659tS)LaBHqcq*mrx?a1Z)jkkVU%5+6()etxOMHgca@xP-`xf95CqJ+a9+YeW7&kl!BeRtOqged7^QCwZV8u*; zp1YRC9dz>=ptbzMnybnhUfaVTzQ*{{CxYa}{*G!q<(Kb&+C4~zKY4Bp_6;U5{@Pvv z4rkkDeA*>J?0bK`+et&!m&^$eGdo8{_h;MkJG%l~Q!8qlE`zvvx*juMO-}}_{m1qGs0$XeykAg#Jx?4}Mnk}Mj2)y6 zay7z$p{4v=(NbJ=iwf>=EihKCC(iD90i%C_J}hrT1DJQw{w9}bw-4=IHP9)EhHV&- ze18dUrhGt8i4^&xsHG3J5c;^w0i2TrXhM2e!U`*mdBiWD@aqG?c%)1`d>-=J(u4FE zXypSE(RR{QdqsKPx9f;U)b9DVJ2x?9i{j9LZ4u{rwWb!vlVac$_B1DEemd zoSgt-=Q)4;@0FKrL>2h&YrnDn*$IkwpHi3ne)x*7`t^QQKc}4SAtfEJxa2FyznG;5FlHj$j_7)_~V*GxvAXgmjeYVF?_@v zCC`oH9yELoi-$U6T|dfG&hGac&Pw`Li^i}497L$uA+(IPNQA;@UHP$JYG<2!y+e25 zWb(=P_7L_{yt_34w*2}Q-e4#fu#G5X6G|vi@k~-dd7HF^DsNwy@#mRqnRY_k@{TTCb}9rt2^8(OSIawhkEKUnm*1xA`&+BcB|Ta#KX6#4yF<8Zr@KRR zcaWEsKJ2m6Hy<9P@=tMbgo=z!A_?f%<-geR&1ZD|*)jUFvvq8>e4!h+`{;vyx;ca! zSRsA(akV_Oi~jf0|F@|0Fm2hxxIQVbI6O%_tnG*<3f3|(ut%0@@w@KT!i)Og7D9Xe z7952yUItkEdD^PqA|`IdfzO+;_Wn-#-$o#65B2$g9Z&a|!ycmI75gUvY|_mh>Pzh& z#i*Kqf!&{=KmXj%mu(@qgY(QEl{kdo&fUo1TP@$$f(HEhdJgNb9cHJC&V8SV*UXa5zM!SH*Dc;13Uec!SfdPFQYm54h{B) ztLI>f{3dpZ_K&p?j~`LO*Yeb?c%Kenp#W=gqe39c(E5Y%kd{p6A-GY|t^(7gmF?s2 zcdW(V;98*8UPi6WCTd;L>9bb1lQHcFbak3B?asZp@22~ce7~FShw_i_1?>E%UfM51 z6MMzYA-ef~60#D-GSk%!=j#Pbpxm`g_3d9B(85dR5M7~x@CiE_6wY93A;Dz-*x?MV zYh=#Os=Q?5M6e-t_go-Ijy-Fdw6K3!z^JbWPS)ZCA1Vq0x+;Q#vPCeNc0{T2o43wo1b9|cjmTKaINXbPUXaVIJP-$``Pk@bxt#-$!y`n#{mjmj(C&zw!ieKqvu6g4p z97^v|_>9WWtQSPZY7ggM!i<L+9u#KpfAlUD*Kq8S*cm;nCFFL9$>Zv0mHcI%b;`va|n%!!_ufYERBl8 z(x^Brjf%t4s5mT*io?>VI4q5dgET6d@!U2MxhQGlUfzP4e9BD*#|tDZE>;tezfSEuzy; zI_)Pe(hKTU51=I$CQjjNMFjC8;DAQ)wT-J8IF?QrN$(jN8eJbeGtR&DGx{t?);N6@a$d~YWX}}(tm)#{C=kC}ip1}) zOT_PUE5z^LD#h=M)#A6Q0S%v|jPh_&?P%QSC#G&ooN_rBIi!>#Yjs79oq|rb03Hc@ z;2*M9ZllN^E4Wt5DC{QPiIRVd7KvqI_!MEzR>K&fg1?BgGIrHW0yS(RbW{<$5bopT zUe`#d(`cxsBvltRUe&4bvMAe>Nr=e6Qi|S)$Ye?H@4BEhEA^$#TyQV04g@fUL7QQ&wMn^OK; zUUHt7#MzWpFDPuvnlSuX)d_#fd-W}%M=#i+u*MswUc^Hi+osdcZyofbHSmUhI?PeB z&9#q(e3V9pRtT`vnrk&w9V$FNPD|KfN)*_LH}lXO3wPrpR@5OnCI2@$Fz7%(7r8o- zDHwVd9QiW90IhH+ye>~~!l!{)maB~|Y7=FwmQxzHep-kIN(Z$iqDsxcKP@zDTT;5Q z>DO4AG(0xQ)#-N_%H=}GHevjmUii#NeP(_cp`(eQ!78KhTH=U#Eg@>I<`6=(EzpEU z47;MIbZQ!=jcvlQ8@5R@##w<0d9fVfx=k%7Eba`qg_7P%ZK_E3TT8lBuEw|;AL!vP z{uLf>W7}J~I?Vgoc9?}{s2J)^#r$y9XFQ3wR4i1T%>C$$a`hB+YkHQI{#6gr#-$)a zBrtGj0o~YOSExP4f`mA4se+&kqM6<_6}MZz%+GbjFHujS__56zZILB$c#Kt}C}Lw@ zY%lQUt~kh0kzV_xPFhq_4&n^9RVP(^EO-xP;tiEh)Qed!=xT;qc!IY;)09+;W)V9e z6nlC#?sK7uhL;+BHSGmU*LPH9i(5Xc>x+=C57^RyLDcmjODgnx$csjfXZ;g3Un}oA zFp6rvUtgZW1G|w>>(!_+l3gt<_*Vi<7Sv%3l&Ft)6gE3MSW|c4>~+S%gz@+^)bJgZ zi8RZ+*>|6$)E3o|`(EDK~gcSQ$0i10xqyaCg$7&bertAb7e)!%Jt`v9xQWq#J0(WJUh?i$i* z3o4wpJ}}eI;cs9NHGKzxQ(lEM%aDipuPIHkPFNQNqntvRRp1HGpSW2f8&-Ner$=nk z|EiOsLzQ-9efR5B`#i%&AroAYbqbzE(L>l6>|kf4u-jwglD!dThkQh&sFvl;A^kFN z$M&TDkK3l8n+WAfw3bZ`oly8TTs7ZMv_MsPh9AYZ&H_50 zu*mRivZ1_`rXPgSN7MC#5&v#$+{#n&tk-%Z5u(58k40M)#ZVMQL; zO7#Lgr+*ZK>6wZ4$++a1ZsRE=b6(@ABKS$Fx@Df(VCf5!k4RtGj{3!gzZLd~FL>X9 z@1I;TN)_S}0<9uv+<>%U80IsiXG#u{?qG-q-8Icfe7&v%EcCB}9t!L~4qFLSW@vB12!7lEPyI|em^C=>wR8Yc<94IS0Cv1iq9TXrhw3ydX1 zC!glS^1Ucr4vGG)5s)d|ppc;nqmv@eq7j^67xRLGo3UVo;)G?95)yb0i^TV6|M1VJYa zomSDqcKa(mdK1Oc(6`Wb4>Ou12L+1|$I~pf0(wyds~4j4C~UX-FkDX+*C7$@BP0@Z zsw?0T-cqcKijWA!5y}t@C;3Lg&Kef$U7}_Gm0|*sVruo1Hdski?`ETBH$Yp?&gm%+ zA*X$A9(%;|)$<5!$F9K}<*O$UaEB3a&%5w>?==X|j*GYihX}SEsG5BAEjt!Gg#}Nz z={H7fhS$hya?-7_97ZRVf;hMGLpS`qtEOdBcvIhr653m?%oAwJm6ntvJv&z?8 zwDkK@PmhVu_TXn{=(E?cH=|fFs;6k67=;7j98blQ zc+ws=gZ|VX(bg_tRi|b20`CPpC~EhVEZdVDE&U3o543H7MOzVC6e;ShhyoEdC`&5f zRVB-yGpw}tGuftEVFm~jgZXo8#iRdP7|8Z%(p!DD23eo1>ho-X`rU!%98A#yY@dw! z7;i;8bYVYLE5YUNJBDSxa2RR6tYp zNKBd(f?2?{Hc_G7st~xj9D!o9XphRUyXG0W6NND0jOxZPp|mVg2Rb7>O7;k*MH|un zP&0^snFsFHpl3b)Ws9Rc>I8N$0*vuw5WIlT%ONB1vB`SqujDDZ%mu>X?mpx1lPHZU(i?JQWO5`i8M>)RG1)c3 z42_IJ3t*8JPm?+DwjdYNT*#64Z8ETr(B-;fY%A;6gl}lbiqxa>`}26@W<#L^cMEc$ zRj4CZbw*Ua7=UHVSZPg=VRxXdK#@9Ce)n+Nhy8p%e0N@PwnE!+&9$Y6+!nJyzS5fz zQ-l(Ls9Eq)(lNz2VGlgYr5h+#Wf^$C>)%$cTnQ)>aT-kYNwV2ThS10Y;#;v{s|Nh< zLbVSUR$(^@GO9jBc6C%uP%xinCpuRJA_X8+_&)^7(QOeR zz=L78QMAGxIbl=u+zoE&ysGB~q4pQZ!PDxzKM#?G5V0|>hN7!gS^bd znxd)rgPeLz#4dO>XzsxJgMtgQJ`apa&{;(Ht^$OOU>@I`fje4X(xVu;x6k8w+js-z zL?G>ozNAy(btQPZNq6`12Kz`NA&hkJ7?mPjL-VpqGtSTB@P{{4B5W-=h<6xE!M{}( z>`{Pv4AVq3$u^G%zp+A~O&W0|=L|5nQrONMMb-Q;bQ47nqN{Zd4uN58D1< z2YHO(mDtM$cqoYuTbd>hCsmM#H^lKrUucJ?Q{ia_sdO4pHv~^XsQI1)p4!FJsp4q? zJe>_sg%+p*wLob1|7D7!Z6c8{pxP&E`h)#rYJNNE1!vU)Uo#t+1R*&3%abY+=sfB6 zQMo`~Vi+xB1L{lIra@auwPP7M3rM+SR(_I5G{A122EsCIXF&7^Wd3cL-#-<^YxB<+ zDZe`K#3`I04;)dPhovYK&I5#}j3E-0?^6kpv;c~+oBwk$6~Ed)Q?K&rzn(+<%ioa8 zcMi&Yh>sHPIjT2dDHG>T_%{It1;lX|wK+!;coZ^G4*6f5k8B5$L3i4@f$P*T)f6Nd!> zc-FTd^xV7!HuaSj4d zOb6<#a9h2Z3;RTFdWP6g+|igQ*9;A%)=W=+zhs3yfVX;cdg^^Mht z(OD=r2kq@09{o9dZk~aG4;M$^0w zzN5qO&Nz>dA?`q&HgbP(!ELiCXNiDZ!%Yv(o-@|c#K)y7}ODp>YK015e;MK>hAigRzV^Bp(JWI^tJyn ztdnaz#G!sa6<$OM;*bO^I zk-Am=7l`t_t{5O#g>U{@21UbDFv6WK29zR~FJz?Y@`zZvrM88JZMS8c*Ypygmz&7s z#D6npo%eU5g|~Ya_f191yrvfwX#6htVi7)bXncNwX7R&TBY@egn)#+`vQ_-1 z&Yr3@nyQs*6!w1TLpjxmc7Ci?FNYTH!e>ysRs_#x!!uyHib~)a-fPfu3G9saq^?d6 zPRz(oAr4;KYfqnrlB|?PA5FfgQn9pBd~m$A7eID_R|>}-yhhnk;J6U*do5PsiufkV zLfD{!VXNRrf?LqHAWoBpkeQt%Svp# zSZq*noh{E@QH@x@Tj54r9+A^{p-aF&V1eAb@R*5SP3#Wsyql@x zQq$#B0h8;tsYKOG4qRMe7}aE$d_t>eF@K4_ZB!lNWwkH? z$lZJZfre@~dx`5I!Oh|ah<`xw&8#__X0iW_y}mJH%wF&2uWP)kO`T4vKRtxI$7?JH z!o0juFt5N1yWaO?y8I7O8Bk|K?+r{$&D7p@w zD^?e(`1X+xJrOJV4;y(_@#>E7_;vq(7hkxXNQI*$>-cC#T%`l7dCmTv?xhQbe52 zrq9=SSzO`A6--nK#HI{`s?LMoIC}{Lhi0yf#Iv@6BqBxV^gB$y?-p5V7fwb@iz?Eg zK%eBvS{}0o$Lhap9XL}d2}L`_SLe~LxGY6dpW$@518pG8EgnXfRZdJ*;D@iF`n{8d zenqF<%Nk)CfRSHr_ZT;t&q;V{88$^BU;|pA*ry+jBEuUl)=O_)Hcz(|@K)zr$bQU# zefOV$c!Ad|#EsvZV=R=O9vGa*ZMX19?44T@iEjwC+wM*ro-DQ1K$9$E{euc?+TS>p zbUA0PQ=Cy>9*+R8IB-}#(99zT_J_hU)6N3-tMK+fuM~(&SBJX>10Sxxal#2s1>hsY z2VM+~1Aq;s2#8YI{u8jPFo~OmT8zAEsT=9o0x22hgKffiZM=VHg4CE3=O#p)6Q~>0 zVL_)*A=|G-KAf&aMrZMUfE{3*mHt9N2N$5}xtgAP8;KfFZa?-ML=WzntHo^JN+gVp zMHwIjLvTM#RoYeq?*5E)7X7_$TO z4n!lz7`Alpad7{)c_r^3UbXcTnBA+7}r6r ziQr1e2L|2Lc>)dD2uk>r>?|sbbOUG(k0aQH0RRuY5elmS1!f-VoJP%8M?V*T zFfHGd!-`Js(f??L)TfkjrTJ?-R!9er{?~lrWz&|4o04sEBA2xLmHeb7R)56`)1g#n zV?+rnYZXRTTknx#fTX9PCz-wPGK?>WkvVj9X3JeEvscS9RQA%Fc zsT+qgo19B{7hcc8!qiLLbRF1!K@w_>+$C6KdJ>S?_9J*d&HCgmS?WM@1b&lGpC7>2 zQ^iU6kw>E7`k{82ZEp4gI@uhSbDCM` z2NH>g8en6#ozhoyKP!r5EyUEG zbARxx6>ZcF7Y!8Z^miJM1Lteym&u`&p-WrX%;rZiQddN#gUghi4+OZV;_6=CBeJz# z=Xwi6Pi8$!v0`r=_>Gjoj2ko4^z*!*Ir?NEWS)vn43ulzim@_kQPQX6>S%pN0lqINtn|ZmWtfsj z1@@D+0j@^wvluv$&Fo-LVmyD<+2XA@y2zOJY~M8O|0Qmz4-3e~Jqar0CWYYh9#5I_)UFdm$hju~&JWVxk% z@Uj0$@TmVMu1?;{g15mQb-l$lp1=gUK?hQkeieWeK?H-oG(IC`P@X|styl_`l^!>r z7)|N7d2``WS2G@=-!z9-J~fMhU86`;_nMiM{&6gxxa|5=#<C4F zzO}D|;$4E+({29V>dAT{+C^#kN@@l#Vj`m)vSQUuZsE~Dbhs{)?Fc&~m?bkKGMHJn zP-;oVi{3Fw=AFUzHFrVD-W79J_`VS~vjWGmst2=tKb8;l?z}G4w*;h48N|*3lXphq z*@`oq`hJ)7df;T>SdOm{?Spu9xEsm#@`hOzV`zl@m6o>C<_+a2!+-;#cz30ffW%WwlP~y8;D~1a{V<4^6`;q{Kd#^f85BLAX1e972yvE*< z`9YvT#@cH}J<@w>=mZOvA?Dd3&AG@nh>Z5bFr`KGaH%8*PGuUlZ4~N!C7-xWLHznS z>J2N-d89KKn$tnmZ@>?>@1^(mV3Z<2DZ#ff%1zm*hxfRRWp`$Z{mNdtN(6u{8O2%X zH+MiOT&^3$3aE%)(N9B4!67xG@K4D<9mQNgD0bVjgkA@vQ|h7-Lf2O)IDH+f8kB z4FAxie;Xg{n2&viu4lnOMo6^qUEUx|du8Vy#%EDhajeG(<|6`=Yxa%`pWaRJ5#(zk z65Aoe<5T!0eeQ4W>ymmzl!2M20J@vJ_v=HuqD%kt58_cq4%ur5ILqFH>DB! zg*MC!!vgaH4$?>l@L;?>%;YmWgTezwR1DgS{`I;Q<;W4c{UR}tS{lfa zd=n*Z-u?8z+Whj+g>`;38X0$?Pn|JM_|Zf@%v@+Z{BsOEbHy9~A>kpWb#vYPVqq8v z!^#FEAX$Q;S{lXxJkn7s8#u)*%9WC|(*~?ozv}ApzfKu8DTEFtW;^Ns8>L0I@WW^H zY2^B2>C-g6PqADIIeD1qS&CkqOB6vTza}q#txYWu$J(E;adkL_)Di#N0IAEo75-Dv zrzbL+DR+&!qTD}K=54IL>k_nHWGT*OW7hXv``O|%0Xmo|u}y6h9$ADiV8IA#jf-b% z`W6xMfV!mU4;68Bnr5g)8jqkVD)#+-BMJS^ImlCAnFW-xYT8N6=oDOyH$&pOa}u6M zh>K$hCn&y#>tpm_Wg9=CGh`ntt_zxByG>zUVBWSrif*AGr?ie~1pjQ3Mo`q~F_vM@ zx8+e5Tr@c&V|8l`jbVgGpB{K3ch_XnqfKU>=Hz&I@pNB4^bHH@#Ra@Lj|KmPy(*qo z{asWO$I0Jg1_r_gB3aer;m^fLyZK&W!pq;r!x=E@8JfO4=H{(^SLx~uS-(36HiXpX z8bw8=kzcy*FoRq$z1E?}?Qdj6@<$?a|YMz*F!ekhw_FiM&6n~a6??!P% z*T@^mpiCreiUtLYF%K;U^S;46G%SUA{)WF!ujOm2tDR6Q;MmP- zjBQbK)WQqqera5Ox#A*MD_h)8fXU0I`HS^CbHudX0KyziYw6~(_!OyhH#Q9Gbq2j+ zp0iS!k12I-^8;D?IZR1a34klB|A@}y{ctM4GJ7_HkDdt!BfeW|hGJRcqTcwX13OCK zz6rCtQ_RTq79S{K`k1;d2rvE9m8qoH^sK_tx@zl6hK}6NA#+x zdT|c5xxI~!*^CAEx&K4jN{Z_f9`_i&{34kx-kW4bRE#c-x^^!fY&#tL-bFmp_c7Zz zpG*yLY`^a&*sJ5Lv-L`|@z)vrU*Ry79}JqC;3DPEk05k%Y6gJMiHRsf3R z@BlW%8qSg%uYikhcx|K>f9w*?xZ&^GxV2J1c9G?D;3S+HyB zO=R|q9fk+AvFI?7Iu-iY!?wemjGv6}eE@IEIxPqGqEI(t9<~FIOAWK&KPVVec-NP$ zN`p|TR$50D)?Pj8yxlj$ZVa*iG zk5s3gfU>>tmKuwF8H(uMX*Gi}0)%~;3D{KnO%Zn9)l`Dq|}%q5IJVFOZ6D(r-j;MYyLEnumBGl@fc;ZeT!1N2G4SM zbTuk+dj5C4M0u6R&JW|!ym1LWWmaz6OcZf*GSBi6FYnxSoi&r+d1VAu?X#<^P5@RZ z(qP(wCBvv*)m1q#;9n3DyEg}&$xG3%T{emn-im!**t(HpnI5CG)&})h^b~;>mD$&( z<&#F&KS7c`QdD*w@}EqSV?3(?{QDq~Rh18-zX@v0C~RzAu9oGs3kE}l$pY-{=ADAi z_!BzRdE>zJ|H$Q^3R^7~04|5s|DFtqLr_mA%#_oZm(Yyd&*Zn3DZwiCM&wKY9Nwo@ zbST^-TEf=J#04F~UI5=tjY8wGZ(_T}4#0Pz2k>N7l3xFbKyAe>Dv+~MU7ZHdE;H>@ zUOY!vhk3CAD5l5Uj6P-!g1!N!=ITLM+~kIYEt-am&8LQw^14=`p1=(=ZmZmMobZOO z#xW^T5m2tl)m3&_wTWcOR%f-T!vdU7AV||0LGz{&Y`?9zl)`x4l@RaYtTc?zJvK!f#xrUsO?lL+AGi4{fDB@{>>NoDOKWZW8+QJ`Aeg2<2n2)G zAdZQ>-ALFl2Tul9*%fD8zhrV0P1b=;d87=dOOXxHYv19$sdTCC;NIsLbx=Z<%{x5osn6 zCwvWhZGH#imA*QH(n3!>36DSv<{}kfL6j5cF2c)D5w=%64MWkIx4|`UHH+f{zS58@ zAXfADLnvWbTTR6@HPn~mUQ9A8Hd?Ix9JIKFG8203z+2|TuDWX!`nf#EeCAUWCObUc%)loBg?UBU3a0rA#^_kV0TS=!@as zArqYgvjVgEmU%5yIJQSmTXfSRn4j6SZ^Dq#dXq5c572xRT?bEZrg#a!tYJvl*y->H zz&&h#KTB0|+PpyCxqiXW!92uTq1Y}oTVa6nw%DP_NCKEnVC-OfA?83fk5_eC44!%8 zg_M6KDvb*GKFr5FBlbq=Xriz?6!u>WGTID&I1ru~=#9f9&xjrTEsV1?e+F=!<$zWL zdkXF)eU>370&(dlIfa%!s_(zX>)%qEse+mzlIZw;en{baeP6E`3NHuF=d1AiyLe)| zxh8=C!M22h&A!~41kMH{0%xcR`4z-D&=RZtGvY%tR-C{*)t(AG#~-`vW06vNMl81! zIdc};EFx6TXq#`t6W09SbNIg(@O8O--Bd%H$p76QI2H%Enh}VU^UIKk7}GA(j78v!hD-XMk0!}*o5 zD^5}Z`DLgXEGOqDPyR#lg$XuHuR^C!aPc1oF%WZNiP-07v}CIEhh?^9FDWzRz+Ne~ z=A`HG<~G*{y$H4@V}ujDf3J`ThgG5?Bo0i4Y3%-&1x(5 z2z|LZbCl>b4Y>^??!#o5UmZ!0k7a#NbUUSeOOi7nU@7hU!^Bu&$QXp9W%?6ZtjN;w z!7byDqpQOcnz;*ptxD6hdB>7frb(aZ!Uc_rN@M4MMwwNpAcXnz7EN(9h_q`?f zrnX{>$0(j{{aQmT)~w$W{EfB$7jl;Sp@XsSdPhN^$Vu(s;sOh<3c~`f?kqC>iFA1Q z;@*6ldXtO2G1dQz@)N0iDV4wC^W{G`HK^|f)?Z+^oum@TmpMAQAF{HSP#abgMguy% z)Bvjo#cO{>N(C^f!FZ`dCSgPOYpc4OHQR>WoR~uU#H(A1hJ($dNe2GUP zn(-^(+svv!mS_j0^GM%Rh8c>RI69>i-CMcA4QkjQ|q*!Z}F=P>=!FHxLTXG}fbHcwb zqc~{Hhx%`v0rg|jabwmFM2mB(d5<$H>oZ>QAVb>^_1a!>_VH#Ob;gR}CMb12J#f){ zG-1&*A_6a?oGB#vSJAWm<>@fkzTeP2PW#I!kM?b%dkjJMaz+(U!Y42j_Nx=1 z+xoLcZabakx0t8MP$shESf(LxQCfdRST*L3&XCis>^DIBne}_ArLJ>+?v$CRICLN_~HB&!jqCB zlAXeIekEGPJ1X0L3^y!b7Nl}N{;8DVtvKP4dOgOp8VqR&sN+c+5E?5!u04y+7@;9O zl~JeP|6wSx=3hM0N1Bnh6BFjS(TXk|NtzVq4dZ5?N1l|uY496L{Pav9G3q}R7?IX} z1PlGTp^joV`qp4K+7}tiIJ6bPek_FR98bmTlpzys38>!;g+2T*bZ*@ZN&G^o^*mC$ zr?Kr{^=)ykx~Ci^!ZqK0y_4Z43f;Kx8k5z>V^q}NpfeV zCd}uyd5mRGj@e6LbZ(rlu5~vF{Ks}nqQ4QFSLza~^KyCE%5%8S|1LV8Xs&bqy{Uer z^B?2&hh9s6IQ?__!#_^7^oN`6(^Yh%5-P-o|5bmO=G&IkAnxObRCL^Y{r^^pxByQw z8>-MBqCcAv!sIR3aBj^=Rt}cAf!rC)*v(^l#lx}D!%4m3d5_R54oj9^vDk*=Q20ZY z3jfPrZ-pVfOpzKYCk8%@gD5=il10&Ocp8^3Ia=&c_y~%M`UxDvFpzy44(mHH4?iM9_l)s86a6hN;)@cJg}Lb zA{NGfHEoTTP$O%^Gt}R-1u%sZ-a&CXLj}Y&3dkFM8>9SXbWPkjhx9=YYi)r#t8iNY zeHW*a9yPlyfQS9-zJ#?k-iiaMzFl!P^Iu?K1@egmq?u8Kj!uCWZpBY*`1(#?Y+^!m|H$JR6A{5Y;004hv21 z9f#61y&w(4d*8QIbOnlFnt&s*pAV;NeE$PAzTZ6b8IAAC1}t$(=zGma&~5JJq#rBq zl6i+b&_@DEBt8*{nzPdtW%WDhxXU0eBn$qIA`J1zPC=gsb671d@qu1=ZNTgG4d`xdY6Bq9oz%0rzG;P0G=I=_X#vy5DjP`ToY_?*Q?Zjr0Qcl~@LSHzcx zn>-c0=K&E&?XC`tl#l@CsYR|aF={8E&ZvT^^aih^UXue>)O?%{shMjnd#8|})8v!n zIR;;T0m>*vB%_p&jIx3bGT^a=XGor)SwTuZ6o?nHOD-d%)yy<|Nkx-*xv-Bu)V79&`r=Sc-DQxKxdIJRKFxKNn&u|cE%JFme zd8`PZFGWh)EWE~*tJhpBGO)gk1eWLc_~m3QF9Nw{c%f5%v8q44dtgY>k_ zM3D)^v2whyyKTh1TT)bn9-%054C~*+93P%z_kVz0h%m<~B#_tRGnw5F!rcA6Z05)K z?E5z8S}R`tD2Ht@=-k6M{#+?#u&vF(ZWb~uqrQwO2ebbhUpRbpc!8D?1h5q#)5qyB zLnS4}rr6ewHk8wftRoC#@;WXao$k23Qmp7VvBvshkqGvJCAHFmnYf49%v-NbbtZ^x zH;S*A#rE`Bw&c^53Y+;ltHo$0Fo|fozUKlIm>E5*vL!vNcCLV-Fx=h)^M6k(et

    Sz2z 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

    2z7U%M!UkoWC&SG?D1= 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

    luAa|*bTAU63X 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

    W5Nq=aQxt0yqxKV@=NwMvYtGa8hLK}uD&=T_GE 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

    )A^}}-s0o=K~Vg}@yok9 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 zǓ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 Znkm>8)2%tce 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 literal 0 HcmV?d00001 diff --git a/pyproject.toml b/pyproject.toml index 0d47eb844a..e7c56eb749 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "=1.5.1" +"discord.py" = "./discord.py-1.5.2.tar.gz" uvloop = {version = ">=0.12.0", markers = "sys_platform != 'win32'"} python-dotenv = ">=0.10.3" parsedatetime = "^2.6" diff --git a/requirements.min.txt b/requirements.min.txt index 9fd4adf1a3..cf1b4bdd26 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -6,7 +6,7 @@ aiohttp==3.6.2 async-timeout==3.0.1 attrs==19.3.0 chardet==3.0.4 -discord.py==1.5.1 +./discord.py-1.5.2.tar.gz dnspython==1.16.0 emoji==0.5.4 future==0.18.2 From 247955842c3b64a20243a869a3e763c5779f9ab9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Nov 2020 01:15:46 +0800 Subject: [PATCH 129/705] Bump version --- CHANGELOG.md | 3 ++- bot.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3317ecd03a..a62d66c2e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev6 +# v3.7.0-dev7 ### Added @@ -23,6 +23,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added a way to block roles. ([GH #2753](https://github.com/kyb3r/modmail/issues/2753)) - Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865)) - Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/kyb3r/modmail/issues/2762)) +- Support stickers and reject non-messages (i.e. pin_add) ### Fixed diff --git a/bot.py b/bot.py index daf1f593c1..a5dce84191 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev6" +__version__ = "3.7.0-dev7" import asyncio From edd7ef26426f3d1f7ac19787474a6b3795a354fd Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Nov 2020 01:24:54 +0800 Subject: [PATCH 130/705] Clearer error messages for plain messages edit/del --- cogs/modmail.py | 4 ++-- core/thread.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index d51d210f8a..7afcabcd76 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -898,7 +898,7 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): return await ctx.send( embed=discord.Embed( title="Failed", - description="Cannot find a message to edit.", + description="Cannot find a message to edit. Plain messages are not supported.", color=self.bot.error_color, ) ) @@ -1307,7 +1307,7 @@ async def delete(self, ctx, message_id: int = None): return await ctx.send( embed=discord.Embed( title="Failed", - description="Cannot find a message to delete.", + description="Cannot find a message to delete. Plain messages are not supported.", color=self.bot.error_color, ) ) diff --git a/core/thread.py b/core/thread.py index 426b76489d..5fbcfadea8 100644 --- a/core/thread.py +++ b/core/thread.py @@ -553,7 +553,7 @@ async def find_linked_messages( return message1, msg except ValueError: continue - raise ValueError("DM message not found.") + raise ValueError("DM message not found. Plain messages are not supported.") async def edit_message(self, message_id: typing.Optional[int], message: str) -> None: try: From d294d08d5930df64fb98cbc345e1f5828a56cda5 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 6 Nov 2020 18:57:02 +0100 Subject: [PATCH 131/705] Update modmail.py --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 7afcabcd76..312cfd9c35 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -855,7 +855,7 @@ async def preply(self, ctx, *, msg: str = ""): @checks.thread_only() async def pareply(self, ctx, *, msg: str = ""): """ - Reply to a Modmail thread with a plain message and anonmymously. + Reply to a Modmail thread with a plain message and anonymously. Supports attachments and images as well as automatically embedding image URLs. From 305196b9c96142f1ca82144c8ac9bbe193a36303 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Nov 2020 15:21:51 +0800 Subject: [PATCH 132/705] Add support for thread titles, resolve #2838 --- CHANGELOG.md | 3 ++- bot.py | 5 +++-- cogs/modmail.py | 9 +++++++++ core/thread.py | 12 ++++++++++-- core/utils.py | 23 +++++++++++++++++++++-- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a62d66c2e6..d83da82e29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev7 +# v3.7.0-dev8 ### Added @@ -24,6 +24,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865)) - Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/kyb3r/modmail/issues/2762)) - Support stickers and reject non-messages (i.e. pin_add) +- Add support for thread titles, `?title` ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) ### Fixed diff --git a/bot.py b/bot.py index a5dce84191..32ff4e76e8 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev7" +__version__ = "3.7.0-dev8" import asyncio @@ -32,7 +32,7 @@ from core import checks from core.clients import ApiClient, PluginDatabaseClient, MongoDBClient from core.config import ConfigManager -from core.utils import human_join, normalize_alias +from core.utils import human_join, match_title, normalize_alias from core.models import PermissionLevel, SafeFormatter, getLogger, configure_logging from core.thread import ThreadManager from core.time import human_timedelta @@ -458,6 +458,7 @@ async def on_ready(self): log["channel_id"], { "open": False, + "title": match_title(thread.channel.topic), "closed_at": str(datetime.utcnow()), "close_message": "Channel has been deleted, no closer found.", "closer": { diff --git a/cogs/modmail.py b/cogs/modmail.py index 7afcabcd76..7c8352bb64 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -646,6 +646,15 @@ def format_log_embeds(self, logs, avatar_url): embeds.append(embed) return embeds + + @commands.command() + @checks.thread_only() + async def title(self, ctx, *, name: str): + await ctx.thread.set_title(name) + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + + @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) async def logs(self, ctx, *, user: User = None): diff --git a/core/thread.py b/core/thread.py index 5fbcfadea8..a70f25a58f 100644 --- a/core/thread.py +++ b/core/thread.py @@ -12,7 +12,7 @@ from core.models import getLogger from core.time import human_timedelta -from core.utils import is_image_url, days, match_user_id, truncate, format_channel_name +from core.utils import is_image_url, days, match_title, match_user_id, truncate, format_channel_name logger = getLogger(__name__) @@ -334,6 +334,7 @@ async def _close( self.channel.id, { "open": False, + "title": match_title(self.channel.topic), "closed_at": str(datetime.utcnow()), "nsfw": self.channel.nsfw, "close_message": message if not silent else None, @@ -346,6 +347,8 @@ async def _close( }, }, ) + else: + log_data = None if isinstance(log_data, dict): prefix = self.bot.config["log_url_prefix"].strip("/") @@ -353,7 +356,9 @@ async def _close( prefix = "" log_url = f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{log_data['key']}" - if log_data["messages"]: + if log_data["title"]: + sneak_peak = log_data["title"] + elif log_data["messages"]: content = str(log_data["messages"][0]["content"]) sneak_peak = content.replace("\n", "") else: @@ -931,6 +936,9 @@ def get_notifications(self) -> str: return " ".join(mentions) + async def set_title(self, title) -> None: + user_id = match_user_id(self.channel.topic) + await self.channel.edit(topic=f'Title: {title}\nUser ID: {user_id}') class ThreadManager: """Class that handles storing, finding and creating Modmail threads.""" diff --git a/core/utils.py b/core/utils.py index 72c96c00f6..0a7b452f18 100644 --- a/core/utils.py +++ b/core/utils.py @@ -216,9 +216,28 @@ def cleanup_code(content: str) -> str: return content.strip("` \n") -TOPIC_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) +TOPIC_TITLE_REGEX = re.compile(r"\bTitle: (.*)\n(?:User ID: )\b", flags=re.IGNORECASE | re.DOTALL) +TOPIC_UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) +def match_title(text: str) -> int: + """ + Matches a title in the foramt of "Title: XXXX" + + Parameters + ---------- + text : str + The text of the user ID. + + Returns + ------- + Optional[str] + The title if found + """ + match = TOPIC_TITLE_REGEX.search(text) + if match is not None: + return match.group(1) + def match_user_id(text: str) -> int: """ Matches a user ID in the format of "User ID: 12345". @@ -233,7 +252,7 @@ def match_user_id(text: str) -> int: int The user ID if found. Otherwise, -1. """ - match = TOPIC_REGEX.search(text) + match = TOPIC_UID_REGEX.search(text) if match is not None: return int(match.group(1)) return -1 From 435021312524670a2645fac036014de4da9b9d95 Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Sat, 7 Nov 2020 17:24:09 -0800 Subject: [PATCH 133/705] im scared to lose my work :| --- cogs/modmail.py | 15 ++++++++++++++- core/clients.py | 19 +++++++++++++++++++ core/thread.py | 14 +++++++++++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index a383a78553..b2656c03c9 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -873,7 +873,7 @@ async def pareply(self, ctx, *, msg: str = ""): async with ctx.typing(): await ctx.thread.reply(ctx.message, anonymous=True, plain=True) - @commands.command() + @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() async def note(self, ctx, *, msg: str = ""): @@ -887,6 +887,19 @@ async def note(self, ctx, *, msg: str = ""): msg = await ctx.thread.note(ctx.message) await msg.pin() + @note.command(name="persistent", aliases=["persist"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def note_persistent(self, ctx, *, msg: str = ""): + """ + Take a persistent note about the current user. + """ + ctx.message.content = msg + async with ctx.typing(): + msg = await ctx.thread.note(ctx.message, persistent=True) + await msg.pin() + await self.bot.api.create_note(recipient=ctx.thread.recipient, message=ctx.message) + @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() diff --git a/core/clients.py b/core/clients.py index 03921d5a17..6d74290105 100644 --- a/core/clients.py +++ b/core/clients.py @@ -401,6 +401,25 @@ async def search_by_text(self, text: str, limit: Optional[int]): {"messages": {"$slice": 5}}, ).to_list(limit) + async def create_note(self, recipient: Member, message: Message): + await self.db.notes.insert_one( + { + "recipient": str(recipient.id), + "author": { + "id": str(message.author.id), + "name": message.author.name, + "discriminator": message.author.discriminator, + "avatar_url": str(message.author.avatar_url), + }, + } + ) + + async def delete_note(self): + pass + + async def find_notes(self, recipient: Member): + return await self.db.notes.find({"recipient": str(recipient.id)}).to_list(None) + def get_plugin_partition(self, cog): cls_name = cog.__class__.__name__ return self.db.plugins[cls_name] diff --git a/core/thread.py b/core/thread.py index a70f25a58f..7786e89ace 100644 --- a/core/thread.py +++ b/core/thread.py @@ -190,6 +190,13 @@ async def send_recipient_genesis_message(): close_emoji = await self.bot.convert_emoji(close_emoji) await self.bot.add_reaction(msg, close_emoji) + async def send_persistent_notes(): + notes = await self.bot.api.find_notes() + for note in notes: + message = discord.Message() + await self.note(note.message) + pass + await asyncio.gather(send_genesis_message(), send_recipient_genesis_message()) self.bot.dispatch("thread_ready", self) @@ -629,11 +636,11 @@ async def edit_dm_message(self, message: discord.Message, content: str) -> None: self.bot.api.edit_message(message.id, content), linked_message.edit(embed=embed) ) - async def note(self, message: discord.Message) -> None: + async def note(self, message: discord.Message, persistent=False) -> None: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) - msg = await self.send(message, self.channel, note=True) + msg = await self.send(message, self.channel, note=True, persistent_note=persistent) self.bot.loop.create_task( self.bot.api.append_log( @@ -719,6 +726,7 @@ async def send( note: bool = False, anonymous: bool = False, plain: bool = False, + persistent_note: bool = False, ) -> None: self.bot.loop.create_task( @@ -780,7 +788,7 @@ async def send( else: # Special note messages embed.set_author( - name=f"Note ({author.name})", + name=f"{'Persistent' if persistent_note else ''} Note ({author.name})", icon_url=system_avatar_url, url=f"https://discordapp.com/users/{author.id}#{message.id}", ) From c7f6d537aeb19d55a148796fd3e2179dc81314bd Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:13:49 +0800 Subject: [PATCH 134/705] Privacy policy/data_collection config-dev9 --- CHANGELOG.md | 7 +-- PRIVACY.md | 122 ++++++++++++++++++++++++++++++++++++++++++ README.md | 6 +++ bot.py | 25 ++++----- core/config.py | 3 ++ core/config_help.json | 9 ++++ 6 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 PRIVACY.md diff --git a/CHANGELOG.md b/CHANGELOG.md index d83da82e29..e6dca02925 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev8 +# v3.7.0-dev9 ### Added @@ -19,12 +19,13 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) - Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) - Added `silent` argument to `?contact` to restore old behaviour. -- If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/kyb3r/modmail/issues/2847)) +- Added new functionality: If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/kyb3r/modmail/issues/2847)) - Added a way to block roles. ([GH #2753](https://github.com/kyb3r/modmail/issues/2753)) - Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865)) - Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/kyb3r/modmail/issues/2762)) - Support stickers and reject non-messages (i.e. pin_add) -- Add support for thread titles, `?title` ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) +- Added support for thread titles, `?title` ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) +- Added `data_collection` to specify if bot metadata should be collected by Modmail developers ### Fixed diff --git a/PRIVACY.md b/PRIVACY.md new file mode 100644 index 0000000000..8ff361b702 --- /dev/null +++ b/PRIVACY.md @@ -0,0 +1,122 @@ +# Privacy Statement + +Hey, we are the lead developers of Modmail bot. This is a look into the data we collect, the data you collect, the data other parties collect, and what can be done about any of this data. +> **Disclaimer**: None of us are lawyers. We are just trying to be more transparent + +### TL;DR + +Yes, we collect some data to keep us happy. You collect some data to keep the bot functioning. External services also collect some data that is out of our control. + +## Interpretation + +- Modmail: This application that has been made open-source. +- Modmail Team: Lead developers, namely kyb3r, fourjr and taku. +- Bot: Your instance of the Modmail bot. +- Bot owner: The person managing the bot. +- Guild: A [server](https://discord.com/developers/docs/resources/guild#guild-resource), an isolated collection of users and channels, within Discord +- User: The end user, or server members, that interface with the bot. +- Database: A location where data is stored, hosted by the bot owner. The following types of database are currently supported: [MongoDB](#MongoDB). +- Logviewer: A webserver hosted by the bot owner. + +## The Data We Collect + +No data is being collected unless someone decides to host the bot and the bot is kept online. + +The Modmail Team collect some metadata to keep us updated on the number of instances that are making use of the bot and know what features we should focus on. The following is a list of data that we collect: +- Bot ID +- Bot username and discriminator +- Bot avatar URL +- Main guild ID +- Main guild name +- Main guild member count +- Bot uptime +- Bot latency +- Bot version +- Whether the bot is seflhosted + +No tokens/passwords/private data is ever being collected or sent to our servers. + +This metadata is sent to our centralised servers every hour that the bot is up and can be viewed in the bot logs when the `log_level` is set to `DEBUG`. + +As our bot is completely open-source, the part that details this behaviour is located in `bot.py > ModmailBot > post_metadata`. + +We assure you that the data is not being sold to anybody. + +### Opting out + +The bot owner can opt out of this data collection by setting `data_collection` to `off` within the configuration variables or the `.env` file. + +### Data deletion + +Data can be deleted with a request in a DM to our [support server](https://discord.gg/etJNHCQ)'s Modmail bot. + +## The Data You Collect + +When using the bot, the bot can collect various bits of user data to ensure that the bot can run smoothly. +This data is stored in a database instance that is hosted by the bot owner (more details below). + +When a thread is created, the bot saves the following data: +- Timestamp +- Log Key +- Channel ID +- Guild ID +- Bot ID +- Recipient ID +- Recipient Username and Discriminator +- Recipient Avatar URL +- Whether the recipient is a moderator + +When a message is sent in a thread, the bot saves the following data: +- Timestamp +- Message ID +- Message author ID +- Message author username and discriminator +- Message author avatar URL +- Whether the message author is a moderator +- Message content +- All attachment urls in the message + +This data is essential to have live logs for the web logviewer to function. +The Modmail team does not track any data by users. + +### Opting out + +There is no way for users or moderators to opt out frmo this data collection. + +### Data deletion + +Logs can be deleted using the `?logs delete ` command. This will remove all data from that specific log entry from the database permenantly. + +## The Data Other Parties Collect + +Plugins form a large part of the Modmail experience. Although we do not have any control over the data plugins collect, including plugins within our registry, all plugins are open-sourced by design. Some plugin devs may collect data beyond our control, and it is the bot owner's responsibility to check with the various plugin developers involved. + +We recommend 4 external services to be used when setting up the Modmail bot. +We have no control over the data external parties collect and it is up to the bot owner's choice as to which external service they choose to employ when using Modmail. +If you wish to opt out of any of this data collection, please view their own privacy policies and data collection information. We will not provide support for such a procedure. + +### Discord + +- [Discord Privacy Policy](https://discord.com/privacy) + +### Heroku + +- [Heroku Security](https://www.heroku.com/policy/security) +- [Salesforce Privacy Policy](https://www.salesforce.com/company/privacy/). + +### MongoDB + +- [MongoDB Privacy Policy](https://www.mongodb.com/legal/privacy-policy). + +### Github + +- [Github Privacy Statement](https://docs.github.com/en/free-pro-team@latest/github/site-policy/github-privacy-statement) + +## Maximum Privacy Setup + +For a maximum privacy setup, we recommend the following hosting procedure. We have included links to various help articles for each relevant step. We will not provide support for such a procedure. +- [Creating a local mongodb instance](https://zellwk.com/blog/local-mongodb/) +- [Hosting Modmail on your personal computer](https://taaku18.github.io/modmail/local-hosting/) +- Ensuring `data_collection` is set to `no` in the `.env` file. +- [Opt out of discord data collection](https://support.discord.com/hc/en-us/articles/360004109911-Data-Privacy-Controls) +- Do not use any plugins, setting `enable_plugins` to `no`. diff --git a/README.md b/README.md index 6173484788..700b3bc10b 100644 --- a/README.md +++ b/README.md @@ -184,3 +184,9 @@ Plugins requests and support is available in our [Modmail Plugins Server](https: Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. If you like this project and would like to show your appreciation, support us on **[Patreon](https://www.patreon.com/kyber)**! + +## Beta Testing + +Our [development](https://github.com/kyb3r/modmail/tree/development) branch is where most of our features are tested before public release. Be warned that there could be bugs in various commands so keep it away from any large servers you manage. + +If you wish to test the new features and play around with them, feel free to join our [Public Test Server](https://discord.gg/v5hTjKC). Bugs can be raised within that server or in our Github issues (state that you are using the development branch though). diff --git a/bot.py b/bot.py index 32ff4e76e8..81dc347f95 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev8" +__version__ = "3.7.0-dev9" import asyncio @@ -477,17 +477,18 @@ async def on_ready(self): "Failed to close thread with channel %s, skipping.", log["channel_id"] ) - self.metadata_loop = tasks.Loop( - self.post_metadata, - seconds=0, - minutes=0, - hours=1, - count=None, - reconnect=True, - loop=None, - ) - self.metadata_loop.before_loop(self.before_post_metadata) - self.metadata_loop.start() + if self.config["data_collection"]: + self.metadata_loop = tasks.Loop( + self.post_metadata, + seconds=0, + minutes=0, + hours=1, + count=None, + reconnect=True, + loop=None, + ) + self.metadata_loop.before_loop(self.before_post_metadata) + self.metadata_loop.start() other_guilds = [ guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild} diff --git a/core/config.py b/core/config.py index 91c50d66f5..5a9ecc7787 100644 --- a/core/config.py +++ b/core/config.py @@ -137,6 +137,8 @@ class ConfigManager: "github_token": None, # Logging "log_level": "INFO", + # data collection + "data_collection": True, } colors = {"mod_color", "recipient_color", "main_color", "error_color"} @@ -158,6 +160,7 @@ class ConfigManager: "alert_on_mention", "confirm_thread_creation", "enable_plugins", + "data_collection", "enable_eval", } diff --git a/core/config_help.json b/core/config_help.json index cc941048c5..a0584e36fa 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -758,5 +758,14 @@ "notes": [ "This configuration can only to be set through `.env` file or environment (config) variables." ] + }, + "data_collection": { + "default": "Yes", + "description": "Controls if bot metadata should be sent to the development team.", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] } } From 4af8dde4e5b811a9e5379c3546dc3945560220ae Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:19:06 +0800 Subject: [PATCH 135/705] add check for title --- cogs/modmail.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/modmail.py b/cogs/modmail.py index a383a78553..f59b1a9139 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -648,6 +648,7 @@ def format_log_embeds(self, logs, avatar_url): @commands.command() + @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() async def title(self, ctx, *, name: str): await ctx.thread.set_title(name) From 4bd61ad34c7d4857a2f29fe13b4036803cd9802f Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:22:44 +0800 Subject: [PATCH 136/705] pin ?title message --- cogs/modmail.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/modmail.py b/cogs/modmail.py index f59b1a9139..ce03a969c3 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -653,6 +653,7 @@ def format_log_embeds(self, logs, avatar_url): async def title(self, ctx, *, name: str): await ctx.thread.set_title(name) sent_emoji, _ = await self.bot.retrieve_emoji() + await ctx.message.pin() await self.bot.add_reaction(ctx.message, sent_emoji) From 2da6fddf644b58b5b7c2075083ceae5a76112316 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 9 Nov 2020 00:23:12 +0800 Subject: [PATCH 137/705] Set docstring for title --- cogs/modmail.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/modmail.py b/cogs/modmail.py index ce03a969c3..f9dc2eb025 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -651,6 +651,7 @@ def format_log_embeds(self, logs, avatar_url): @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() async def title(self, ctx, *, name: str): + """Sets title for a thread""" await ctx.thread.set_title(name) sent_emoji, _ = await self.bot.retrieve_emoji() await ctx.message.pin() From d647edb34b1d9bc25837838e4322a4779154af65 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:24:31 +0800 Subject: [PATCH 138/705] `?move` now does not require exact category names, accepts case-insensitive and startswith names --- CHANGELOG.md | 3 ++- bot.py | 4 ++-- cogs/modmail.py | 8 +++----- core/models.py | 23 +++++++++++++++++++++++ core/thread.py | 14 +++++++++++--- core/utils.py | 1 + 6 files changed, 42 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6dca02925..68fe124f9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev9 +# v3.7.0-dev10 ### Added @@ -34,6 +34,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Improved - Plugins installations have clearer error messages +- `?move` now does not require exact category names, accepts case-insensitive and startswith names # v3.6.2 diff --git a/bot.py b/bot.py index 81dc347f95..15deef95a0 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev9" +__version__ = "3.7.0-dev10" import asyncio @@ -748,7 +748,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: if blocked: return sent_emoji, blocked_emoji = await self.retrieve_emoji() - + if message.type != discord.MessageType.default: return diff --git a/cogs/modmail.py b/cogs/modmail.py index f9dc2eb025..01bdb4d341 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -14,7 +14,7 @@ from natural.date import duration from core import checks -from core.models import PermissionLevel, getLogger +from core.models import PermissionLevel, SimilarCategoryConverter, getLogger from core.paginator import EmbedPaginatorSession from core.thread import Thread from core.time import UserFriendlyTime, human_timedelta @@ -305,7 +305,7 @@ async def move(self, ctx, *, arguments): else: fmt = " ".join(split_args[:-i]) - category = await commands.CategoryChannelConverter().convert(ctx, fmt) + category = await SimilarCategoryConverter().convert(ctx, fmt) except commands.BadArgument: if i == len(split_args) - 1: # last one @@ -646,7 +646,6 @@ def format_log_embeds(self, logs, avatar_url): embeds.append(embed) return embeds - @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @@ -657,7 +656,6 @@ async def title(self, ctx, *, name: str): await ctx.message.pin() await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) async def logs(self, ctx, *, user: User = None): @@ -930,7 +928,7 @@ async def contact( ctx, user: Union[discord.Member, discord.User], *, - category: Union[discord.CategoryChannel, str] = None, + category: Union[SimilarCategoryConverter, str] = None, manual_trigger=True, ): """ diff --git a/core/models.py b/core/models.py index 12365f24da..30565632dd 100644 --- a/core/models.py +++ b/core/models.py @@ -185,3 +185,26 @@ def get_value(self, key, args, kwds): return "{" + key + "}" else: return Formatter.get_value(key, args, kwds) + + +class SimilarCategoryConverter(commands.CategoryChannelConverter): + async def convert(self, ctx, argument): + bot = ctx.bot + guild = ctx.guild + result = None + + try: + return await super().convert(ctx, argument) + except commands.ChannelNotFound: + def check(c): + return isinstance(c, discord.CategoryChannel) and c.name.lower().startswith(argument.lower()) + + if guild: + result = discord.utils.find(check, guild.categories) + else: + result = discord.utils.find(check, bot.get_all_channels()) + + if not isinstance(result, discord.CategoryChannel): + raise commands.ChannelNotFound(argument) + + return result diff --git a/core/thread.py b/core/thread.py index a70f25a58f..3eb6e93a52 100644 --- a/core/thread.py +++ b/core/thread.py @@ -12,7 +12,14 @@ from core.models import getLogger from core.time import human_timedelta -from core.utils import is_image_url, days, match_title, match_user_id, truncate, format_channel_name +from core.utils import ( + is_image_url, + days, + match_title, + match_user_id, + truncate, + format_channel_name, +) logger = getLogger(__name__) @@ -806,7 +813,7 @@ async def send( if is_image_url(url, convert_size=False) ] images.extend(image_urls) - images.extend((str(i.image_url), f'{i.name} Sticker', True) for i in message.stickers) + images.extend((str(i.image_url), f"{i.name} Sticker", True) for i in message.stickers) embedded_image = False @@ -938,7 +945,8 @@ def get_notifications(self) -> str: async def set_title(self, title) -> None: user_id = match_user_id(self.channel.topic) - await self.channel.edit(topic=f'Title: {title}\nUser ID: {user_id}') + await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}") + class ThreadManager: """Class that handles storing, finding and creating Modmail threads.""" diff --git a/core/utils.py b/core/utils.py index 0a7b452f18..239522139a 100644 --- a/core/utils.py +++ b/core/utils.py @@ -238,6 +238,7 @@ def match_title(text: str) -> int: if match is not None: return match.group(1) + def match_user_id(text: str) -> int: """ Matches a user ID in the format of "User ID: 12345". From 69d60abb57a82c834d9e82c92d53beebd2b24d6f Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:30:57 +0800 Subject: [PATCH 139/705] Fix issue with updateperms not casting to str, resolve #2856 --- CHANGELOG.md | 1 + bot.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68fe124f9a..8f7b91c612 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed - `?contact` now sends members a DM. +- Fixed issue where `level_permissions` and `command_permissions` would sometimes be reset. ([GH #2856](https://github.com/kyb3r/modmail/issues/2856)) ### Improved diff --git a/bot.py b/bot.py index 15deef95a0..670ea066f6 100644 --- a/bot.py +++ b/bot.py @@ -882,7 +882,7 @@ async def get_context(self, message, *, cls=commands.Context): async def update_perms( self, name: typing.Union[PermissionLevel, str], value: int, add: bool = True ) -> None: - value = int(value) + value = str(value) if isinstance(name, PermissionLevel): permissions = self.config["level_permissions"] name = name.name From 27afe7d837c18ab1b4e8e9ceabd75d58010c2b49 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 17:25:47 +0800 Subject: [PATCH 140/705] Added `?autotrigger` to specify keywords to trigger commands, resolve #130, resolve #649 --- CHANGELOG.md | 7 +-- bot.py | 50 ++++++++++++++++++++ cogs/modmail.py | 5 +- cogs/utility.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++- core/config.py | 1 + core/models.py | 5 +- core/thread.py | 26 +++++++++-- 7 files changed, 205 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f7b91c612..1dda1042e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,9 +23,10 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added a way to block roles. ([GH #2753](https://github.com/kyb3r/modmail/issues/2753)) - Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865)) - Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/kyb3r/modmail/issues/2762)) -- Support stickers and reject non-messages (i.e. pin_add) -- Added support for thread titles, `?title` ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) -- Added `data_collection` to specify if bot metadata should be collected by Modmail developers +- Support stickers and reject non-messages. (i.e. pin_add) +- Added support for thread titles, `?title`. ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) +- Added `data_collection` to specify if bot metadata should be collected by Modmail developers. +- Added `?autotrigger` to specify keywords to trigger commands. ([GH #130](https://github.com/kyb3r/modmail/issues/130), [GH #649](https://github.com/kyb3r/modmail/issues/649)) ### Fixed diff --git a/bot.py b/bot.py index 670ea066f6..b68e0121aa 100644 --- a/bot.py +++ b/bot.py @@ -2,6 +2,7 @@ import asyncio +import copy import logging import os import re @@ -244,6 +245,10 @@ def snippets(self) -> typing.Dict[str, str]: def aliases(self) -> typing.Dict[str, str]: return self.config["aliases"] + @property + def auto_triggers(self) -> typing.Dict[str, str]: + return self.config["auto_triggers"] + @property def token(self) -> str: token = self.config["token"] @@ -852,6 +857,51 @@ async def get_contexts(self, message, *, cls=commands.Context): ctx.command = self.all_commands.get(invoker) return [ctx] + async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context): + message.author = self.modmail_guild.me + message.channel = channel + + view = StringView(message.content) + ctx = cls(prefix=self.prefix, view=view, bot=self, message=message) + thread = await self.threads.find(channel=ctx.channel) + + invoked_prefix = self.prefix + invoker = view.get_word().lower() + + # Check if there is any aliases being called. + alias = self.auto_triggers[ + next(filter(lambda x: x in message.content, self.auto_triggers.keys())) + ] + if alias is None: + ctx.thread = thread + ctx.invoked_with = invoker + ctx.command = self.all_commands.get(invoker) + ctxs = [ctx] + else: + ctxs = [] + aliases = normalize_alias(alias, message.content[len(f"{invoked_prefix}{invoker}") :]) + if not aliases: + logger.warning("Alias %s is invalid as called in automove.", invoker) + + for alias in aliases: + view = StringView(invoked_prefix + alias) + ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) + ctx_.thread = thread + discord.utils.find(view.skip_string, await self.get_prefix()) + ctx_.invoked_with = view.get_word().lower() + ctx_.command = self.all_commands.get(ctx_.invoked_with) + ctxs += [ctx_] + + for ctx in ctxs: + if ctx.command: + old_checks = copy.copy(ctx.command.checks) + ctx.command.checks = [checks.has_permissions(PermissionLevel.INVALID)] + + await self.invoke(ctx) + + ctx.command.checks = old_checks + continue + async def get_context(self, message, *, cls=commands.Context): """ Returns the invocation context from the message. diff --git a/cogs/modmail.py b/cogs/modmail.py index 01bdb4d341..8c0323ae09 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -338,7 +338,10 @@ async def move(self, ctx, *, arguments): await thread.channel.send(f"{mention}, thread has been moved.") sent_emoji, _ = await self.bot.retrieve_emoji() - await self.bot.add_reaction(ctx.message, sent_emoji) + try: + await self.bot.add_reaction(ctx.message, sent_emoji) + except discord.NotFound: + pass async def send_scheduled_close_message(self, ctx, after, silent=False): human_delta = human_timedelta(after.dt) diff --git a/cogs/utility.py b/cogs/utility.py index 0e9aaac753..55f237ab3f 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -22,7 +22,13 @@ from core import checks, utils from core.changelog import Changelog -from core.models import InvalidConfigError, PermissionLevel, UnseenFormatter, getLogger +from core.models import ( + InvalidConfigError, + PermissionLevel, + SimilarCategoryConverter, + UnseenFormatter, + getLogger, +) from core.paginator import EmbedPaginatorSession, MessagePaginatorSession @@ -1698,6 +1704,119 @@ async def oauth_show(self, ctx): await ctx.send(embed=embed) + @commands.group(invoke_without_command=True) + @checks.has_permissions(PermissionLevel.OWNER) + async def autotrigger(self, ctx): + """Automatically trigger alias-like commands based on a certain keyword""" + await ctx.send_help(ctx.command) + + @autotrigger.command(name="add") + @checks.has_permissions(PermissionLevel.OWNER) + async def autotrigger_add(self, ctx, keyword, *, command): + """Adds a trigger to automatically trigger an alias-like command""" + if keyword in self.bot.auto_triggers: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"Another autotrigger with the same name already exists: `{name}`.", + ) + else: + self.bot.auto_triggers[keyword] = command + await self.bot.config.update() + + embed = discord.Embed( + title="Success", + color=self.bot.main_color, + description=f"Keyword `{keyword}` has been linked to `{command}`.", + ) + + await ctx.send(embed=embed) + + @autotrigger.command(name="edit") + @checks.has_permissions(PermissionLevel.OWNER) + async def autotrigger_edit(self, ctx, keyword, *, command): + """Edits a pre-existing trigger to automatically trigger an alias-like command""" + if keyword not in self.bot.auto_triggers: + embed = utils.create_not_found_embed( + keyword, self.bot.auto_triggers.keys(), "Autotrigger" + ) + else: + self.bot.auto_triggers[keyword] = command + await self.bot.config.update() + + embed = discord.Embed( + title="Success", + color=self.bot.main_color, + description=f"Keyword `{keyword}` has been linked to `{command}`.", + ) + + await ctx.send(embed=embed) + + @autotrigger.command(name="remove") + @checks.has_permissions(PermissionLevel.OWNER) + async def autotrigger_remove(self, ctx, keyword): + """Removes a trigger to automatically trigger an alias-like command""" + try: + del self.bot.auto_triggers[keyword] + except KeyError: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"Keyword `{keyword}` could not be found.", + ) + await ctx.send(embed=embed) + else: + await self.bot.config.update() + + embed = discord.Embed( + title="Success", + color=self.bot.main_color, + description=f"Keyword `{keyword}` has been removed.", + ) + await ctx.send(embed=embed) + + @autotrigger.command(name="test") + @checks.has_permissions(PermissionLevel.OWNER) + async def autotrigger_test(self, ctx, *, text): + """Tests a string against the current autotrigger setup""" + for keyword in list(self.bot.auto_triggers): + if keyword in text: + alias = self.bot.auto_triggers[keyword] + embed = discord.Embed( + title="Keyword Found", + color=self.bot.main_color, + description=f"autotrigger keyword `{keyword}` found. Command executed: `{alias}`", + ) + return await ctx.send(embed=embed) + + embed = discord.Embed( + title="Keyword Not Found", + color=self.bot.error_color, + description=f"No autotrigger keyword found. Thread will stay in {self.bot.main_category}.", + ) + return await ctx.send(embed=embed) + + @autotrigger.command(name="list") + @checks.has_permissions(PermissionLevel.OWNER) + async def autotrigger_list(self, ctx): + """Lists all autotriggers set up""" + embeds = [] + for keyword in list(self.bot.auto_triggers): + command = self.bot.auto_triggers[keyword] + embed = discord.Embed(title=keyword, color=self.bot.main_color, description=command,) + embeds.append(embed) + + if not embeds: + embeds.append( + discord.Embed( + title="No autotrigger set", + color=self.bot.error_color, + description=f"Use `{self.bot.prefix}autotrigger add` to add new autotriggers.", + ) + ) + + await EmbedPaginatorSession(ctx, *embeds).run() + @commands.command(hidden=True, name="eval") @checks.has_permissions(PermissionLevel.OWNER) async def eval_(self, ctx, *, body: str): diff --git a/core/config.py b/core/config.py index 5a9ecc7787..66bb7a69ba 100644 --- a/core/config.py +++ b/core/config.py @@ -117,6 +117,7 @@ class ConfigManager: # misc "plugins": [], "aliases": {}, + "auto_triggers": {}, } protected_keys = { diff --git a/core/models.py b/core/models.py index 30565632dd..1cd3ec4a6a 100644 --- a/core/models.py +++ b/core/models.py @@ -196,8 +196,11 @@ async def convert(self, ctx, argument): try: return await super().convert(ctx, argument) except commands.ChannelNotFound: + def check(c): - return isinstance(c, discord.CategoryChannel) and c.name.lower().startswith(argument.lower()) + return isinstance(c, discord.CategoryChannel) and c.name.lower().startswith( + argument.lower() + ) if guild: result = discord.utils.find(check, guild.categories) diff --git a/core/thread.py b/core/thread.py index 3eb6e93a52..944ab81387 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1,4 +1,5 @@ import asyncio +import copy import io import re import typing @@ -10,7 +11,8 @@ import discord from discord.ext.commands import MissingRequiredArgument, CommandError -from core.models import getLogger +from core import checks +from core.models import PermissionLevel, getLogger from core.time import human_timedelta from core.utils import ( is_image_url, @@ -101,7 +103,7 @@ def cancelled(self, flag: bool): for i in self.wait_tasks: i.cancel() - async def setup(self, *, creator=None, category=None): + async def setup(self, *, creator=None, category=None, initial_message=None): """Create the thread channel and other io related initialisation tasks""" self.bot.dispatch("thread_initiate", self) recipient = self.recipient @@ -197,7 +199,19 @@ async def send_recipient_genesis_message(): close_emoji = await self.bot.convert_emoji(close_emoji) await self.bot.add_reaction(msg, close_emoji) - await asyncio.gather(send_genesis_message(), send_recipient_genesis_message()) + async def activate_auto_triggers(): + message = copy.copy(initial_message) + if message: + for keyword in list(self.bot.auto_triggers): + if keyword in message.content: + try: + return await self.bot.trigger_auto_triggers(message, channel) + except StopIteration: + pass + + await asyncio.gather( + send_genesis_message(), send_recipient_genesis_message(), activate_auto_triggers(), + ) self.bot.dispatch("thread_ready", self) def _format_info_embed(self, user, log_url, log_count, color): @@ -880,6 +894,8 @@ async def send( if delete_message and destination == self.channel: try: await message.delete() + except discord.NotFound: + pass except Exception as e: logger.warning("Cannot delete message: %s.", e) @@ -1138,7 +1154,9 @@ async def create( del self.cache[recipient.id] return thread - self.bot.loop.create_task(thread.setup(creator=creator, category=category)) + self.bot.loop.create_task( + thread.setup(creator=creator, category=category, initial_message=message) + ) return thread async def find_or_create(self, recipient) -> Thread: From a7c23876f7099e69077a03dad1d86c32689719c0 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 19:44:06 +0800 Subject: [PATCH 141/705] More elegant solution to dummymessage --- CHANGELOG.md | 2 +- bot.py | 2 +- cogs/modmail.py | 5 +---- cogs/utility.py | 2 +- core/models.py | 43 +++++++++++++++++++++++++++++++++++++++++++ core/thread.py | 7 ++----- 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dda1042e6..812d0ae0d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. -# v3.7.0-dev10 +# v3.7.0-dev11 ### Added diff --git a/bot.py b/bot.py index b68e0121aa..00e478531b 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev10" +__version__ = "3.7.0-dev11" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index 8c0323ae09..01bdb4d341 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -338,10 +338,7 @@ async def move(self, ctx, *, arguments): await thread.channel.send(f"{mention}, thread has been moved.") sent_emoji, _ = await self.bot.retrieve_emoji() - try: - await self.bot.add_reaction(ctx.message, sent_emoji) - except discord.NotFound: - pass + await self.bot.add_reaction(ctx.message, sent_emoji) async def send_scheduled_close_message(self, ctx, after, silent=False): human_delta = human_timedelta(after.dt) diff --git a/cogs/utility.py b/cogs/utility.py index 55f237ab3f..9216eb7f12 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1707,7 +1707,7 @@ async def oauth_show(self, ctx): @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.OWNER) async def autotrigger(self, ctx): - """Automatically trigger alias-like commands based on a certain keyword""" + """Automatically trigger alias-like commands based on a certain keyword in the user's inital message""" await ctx.send_help(ctx.command) @autotrigger.command(name="add") diff --git a/core/models.py b/core/models.py index 1cd3ec4a6a..a834b033ae 100644 --- a/core/models.py +++ b/core/models.py @@ -211,3 +211,46 @@ def check(c): raise commands.ChannelNotFound(argument) return result + + +class DummyMessage: + """ + A class mimicking the original :class:discord.Message + where all functions that require an actual message to exist + is replaced with a dummy function + """ + def __init__(self, message): + self._message = message + + def __getattr__(self, name: str): + return getattr(self._message, name) + + async def delete(self, *, delay=None): + return + + async def edit(self, **fields): + return + + async def add_reaction(self, emoji): + return + + async def remove_reaction(self, emoji): + return + + async def clear_reaction(self, emoji): + return + + async def clear_reactions(self): + return + + async def pin(self, *, reason=None): + return + + async def unpin(self, *, reason=None): + return + + async def publish(self): + return + + async def ack(self): + return diff --git a/core/thread.py b/core/thread.py index 944ab81387..eca0e19220 100644 --- a/core/thread.py +++ b/core/thread.py @@ -11,8 +11,7 @@ import discord from discord.ext.commands import MissingRequiredArgument, CommandError -from core import checks -from core.models import PermissionLevel, getLogger +from core.models import DummyMessage, getLogger from core.time import human_timedelta from core.utils import ( is_image_url, @@ -200,7 +199,7 @@ async def send_recipient_genesis_message(): await self.bot.add_reaction(msg, close_emoji) async def activate_auto_triggers(): - message = copy.copy(initial_message) + message = DummyMessage(copy.copy(initial_message)) if message: for keyword in list(self.bot.auto_triggers): if keyword in message.content: @@ -894,8 +893,6 @@ async def send( if delete_message and destination == self.channel: try: await message.delete() - except discord.NotFound: - pass except Exception as e: logger.warning("Cannot delete message: %s.", e) From 56bc2125a133dbdbc34664ef68eac92f8382c638 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 19:52:36 +0800 Subject: [PATCH 142/705] Fix bug with data collection --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 00e478531b..3afc3cf453 100644 --- a/bot.py +++ b/bot.py @@ -482,7 +482,7 @@ async def on_ready(self): "Failed to close thread with channel %s, skipping.", log["channel_id"] ) - if self.config["data_collection"]: + if self.config.get("data_collection"): self.metadata_loop = tasks.Loop( self.post_metadata, seconds=0, From 5c8ee8d07081777dafb1542d93b071ef3c91e1ae Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 20:03:28 +0800 Subject: [PATCH 143/705] Specify exact versions pipfile --- Pipfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pipfile b/Pipfile index fb20f42c21..348c7846ad 100644 --- a/Pipfile +++ b/Pipfile @@ -5,9 +5,9 @@ verify_ssl = true [dev-packages] black = "==19.10b0" -pylint = "*" +pylint = "==2.6.0" bandit = "==1.6.2" -flake8 = "*" +flake8 = "==3.8.5" [packages] aiohttp = "==3.6.2" From 038fc61e1990cc68eba5257811d4f406b17912d7 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 21:18:55 +0800 Subject: [PATCH 144/705] Fix bugs with alias and autotrigger, resolve #2870 --- CHANGELOG.md | 7 ++++--- bot.py | 1 + core/models.py | 3 +++ core/utils.py | 11 ++++++++--- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 812d0ae0d0..6c3c48cd06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); -however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section. +however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev11 +# v3.7.0-dev12 ### Added @@ -31,7 +31,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed - `?contact` now sends members a DM. -- Fixed issue where `level_permissions` and `command_permissions` would sometimes be reset. ([GH #2856](https://github.com/kyb3r/modmail/issues/2856)) +- `level_permissions` and `command_permissions` would sometimes be reset. ([GH #2856](https://github.com/kyb3r/modmail/issues/2856)) +- Command truncated after && in alias ([GH #2870](https://github.com/kyb3r/modmail/issues/2870)) ### Improved diff --git a/bot.py b/bot.py index 3afc3cf453..901999f2e9 100644 --- a/bot.py +++ b/bot.py @@ -849,6 +849,7 @@ async def get_contexts(self, message, *, cls=commands.Context): discord.utils.find(view.skip_string, prefixes) ctx_.invoked_with = view.get_word().lower() ctx_.command = self.all_commands.get(ctx_.invoked_with) + print(ctx_.invoked_with, ctx_.args, ctx_.kwargs) ctxs += [ctx_] return ctxs diff --git a/core/models.py b/core/models.py index a834b033ae..4bd62e5d90 100644 --- a/core/models.py +++ b/core/models.py @@ -225,6 +225,9 @@ def __init__(self, message): def __getattr__(self, name: str): return getattr(self._message, name) + def __bool__(self): + return bool(self._message) + async def delete(self, *, delay=None): return diff --git a/core/utils.py b/core/utils.py index 239522139a..a236adbc0f 100644 --- a/core/utils.py +++ b/core/utils.py @@ -270,7 +270,7 @@ def create_not_found_embed(word, possibilities, name, n=2, cutoff=0.6) -> discor return embed -def parse_alias(alias): +def parse_alias(alias, *, split=True): def encode_alias(m): return "\x1AU" + base64.b64encode(m.group(1).encode()).decode() + "\x1AU" @@ -288,7 +288,12 @@ def decode_alias(m): if not alias: return aliases - for a in re.split(r"\s*&&\s*", alias): + if split: + iterate = re.split(r"\s*&&\s*", alias) + else: + iterate = [alias] + + for a in iterate: a = re.sub("\x1AU(.+?)\x1AU", decode_alias, a) if a[0] == a[-1] == '"': a = a[1:-1] @@ -299,7 +304,7 @@ def decode_alias(m): def normalize_alias(alias, message): aliases = parse_alias(alias) - contents = parse_alias(message) + contents = parse_alias(message, split=False) final_aliases = [] for a, content in zip_longest(aliases, contents): From 1b5d993ff5f8d1816264e3e12dceb68d00dc4f72 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 21:31:56 +0800 Subject: [PATCH 145/705] Use enums in config, resolve #2821 --- bot.py | 6 +++--- cogs/modmail.py | 20 ++++++++++---------- core/config.py | 43 ++++++++++++++++++------------------------- core/models.py | 6 ++++++ core/thread.py | 2 +- 5 files changed, 38 insertions(+), 39 deletions(-) diff --git a/bot.py b/bot.py index 901999f2e9..08782084f1 100644 --- a/bot.py +++ b/bot.py @@ -34,7 +34,7 @@ from core.clients import ApiClient, PluginDatabaseClient, MongoDBClient from core.config import ConfigManager from core.utils import human_join, match_title, normalize_alias -from core.models import PermissionLevel, SafeFormatter, getLogger, configure_logging +from core.models import DMDisabled, PermissionLevel, SafeFormatter, getLogger, configure_logging from core.thread import ThreadManager from core.time import human_timedelta @@ -770,7 +770,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: ) return - if self.config["dm_disabled"] >= 1: + if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): embed = discord.Embed( title=self.config["disabled_new_thread_title"], color=self.error_color, @@ -787,7 +787,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: thread = await self.threads.create(message.author, message=message) else: - if self.config["dm_disabled"] == 2: + if self.config["dm_disabled"] == DMDisabled.ALL_THREADS: embed = discord.Embed( title=self.config["disabled_current_thread_title"], color=self.error_color, diff --git a/cogs/modmail.py b/cogs/modmail.py index 01bdb4d341..638ae2e28d 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -14,7 +14,7 @@ from natural.date import duration from core import checks -from core.models import PermissionLevel, SimilarCategoryConverter, getLogger +from core.models import DMDisabled, PermissionLevel, SimilarCategoryConverter, getLogger from core.paginator import EmbedPaginatorSession from core.thread import Thread from core.time import UserFriendlyTime, human_timedelta @@ -964,7 +964,7 @@ async def contact( else: thread = await self.bot.threads.create(user, creator=ctx.author, category=category) - if self.bot.config["dm_disabled"] >= 1: + if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): logger.info("Contacting user %s when Modmail DM is disabled.", user) if not silent: @@ -1450,8 +1450,8 @@ async def enable(self, ctx): color=self.bot.main_color, ) - if self.bot.config["dm_disabled"] != 0: - self.bot.config["dm_disabled"] = 0 + if self.bot.config["dm_disabled"] != DMDisabled.NONE: + self.bot.config["dm_disabled"] = DMDisabled.NONE await self.bot.config.update() return await ctx.send(embed=embed) @@ -1481,8 +1481,8 @@ async def disable_new(self, ctx): description="Modmail will not create any new threads.", color=self.bot.main_color, ) - if self.bot.config["dm_disabled"] < 1: - self.bot.config["dm_disabled"] = 1 + if self.bot.config["dm_disabled"] < DMDisabled.NEW_THREADS: + self.bot.config["dm_disabled"] = DMDisabled.NEW_THREADS await self.bot.config.update() return await ctx.send(embed=embed) @@ -1501,8 +1501,8 @@ async def disable_all(self, ctx): color=self.bot.main_color, ) - if self.bot.config["dm_disabled"] != 2: - self.bot.config["dm_disabled"] = 2 + if self.bot.config["dm_disabled"] != DMDisabled.ALL_THREADS: + self.bot.config["dm_disabled"] = DMDisabled.ALL_THREADS await self.bot.config.update() return await ctx.send(embed=embed) @@ -1514,13 +1514,13 @@ async def isenable(self, ctx): Check if the DM functionalities of Modmail is enabled. """ - if self.bot.config["dm_disabled"] == 1: + if self.bot.config["dm_disabled"] == DMDisabled.NEW_THREADS: embed = discord.Embed( title="New Threads Disabled", description="Modmail is not creating new threads.", color=self.bot.error_color, ) - elif self.bot.config["dm_disabled"] == 2: + elif self.bot.config["dm_disabled"] == DMDisabled.ALL_THREADS: embed = discord.Embed( title="All DM Disabled", description="Modmail is not accepting any DM messages for new and existing threads.", diff --git a/core/config.py b/core/config.py index 66bb7a69ba..be53807f3f 100644 --- a/core/config.py +++ b/core/config.py @@ -12,7 +12,7 @@ from discord.ext.commands import BadArgument from core._color_data import ALL_COLORS -from core.models import InvalidConfigError, Default, getLogger +from core.models import DMDisabled, InvalidConfigError, Default, getLogger from core.time import UserFriendlyTimeSync from core.utils import strtobool @@ -98,9 +98,7 @@ class ConfigManager: "activity_message": "", "activity_type": None, "status": None, - # dm_disabled 0 = none, 1 = new threads, 2 = all threads - # TODO: use enum - "dm_disabled": 0, + "dm_disabled": DMDisabled.NONE, "oauth_whitelist": [], # moderation "blocked": {}, @@ -165,7 +163,11 @@ class ConfigManager: "enable_eval", } - special_types = {"status", "activity_type"} + enums = { + "dm_disabled": DMDisabled, + "status": discord.Status, + "activity_type": discord.ActivityType + } defaults = {**public_keys, **private_keys, **protected_keys} all_keys = set(defaults.keys()) @@ -277,26 +279,15 @@ def get(self, key: str, convert=True) -> typing.Any: value = strtobool(value) except ValueError: value = self.remove(key) - - elif key in self.special_types: + + elif key in self.enums: if value is None: return None - - if key == "status": - try: - # noinspection PyArgumentList - value = discord.Status(value) - except ValueError: - logger.warning("Invalid status %s.", value) - value = self.remove(key) - - elif key == "activity_type": - try: - # noinspection PyArgumentList - value = discord.ActivityType(value) - except ValueError: - logger.warning("Invalid activity %s.", value) - value = self.remove(key) + try: + value = self.enums[key](value) + except ValueError: + logger.warning("Invalid %s %s.", key, value) + value = self.remove(key) return value @@ -355,8 +346,10 @@ def set(self, key: str, item: typing.Any, convert=True) -> None: except ValueError: raise InvalidConfigError("Must be a yes/no value.") - # elif key in self.special_types: - # if key == "status": + elif key in self.enums: + if isinstance(item, self.enums[key]): + # value is an enum type + item = item.value return self.__setitem__(key, item) diff --git a/core/models.py b/core/models.py index 4bd62e5d90..8d1be4130a 100644 --- a/core/models.py +++ b/core/models.py @@ -257,3 +257,9 @@ async def publish(self): async def ack(self): return + + +class DMDisabled(IntEnum): + NONE = 0 + NEW_THREADS = 1 + ALL_THREADS = 2 diff --git a/core/thread.py b/core/thread.py index eca0e19220..4beacf31bc 100644 --- a/core/thread.py +++ b/core/thread.py @@ -896,7 +896,7 @@ async def send( except Exception as e: logger.warning("Cannot delete message: %s.", e) - if from_mod and self.bot.config["dm_disabled"] == 2 and destination != self.channel: + if from_mod and self.bot.config["dm_disabled"] == DMDisabled.ALL_THREADS and destination != self.channel: logger.info("Sending a message to %s when DM disabled is set.", self.recipient) try: From 3428eb3f681e09b4f5d40201e2a98fecbde21339 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 21:46:52 +0800 Subject: [PATCH 146/705] use regex autotrigger config --- CHANGELOG.md | 11 +++++++---- bot.py | 12 +++++++++--- core/config.py | 3 +++ core/config_help.json | 12 ++++++++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c3c48cd06..9123ab168f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,18 +26,21 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Support stickers and reject non-messages. (i.e. pin_add) - Added support for thread titles, `?title`. ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) - Added `data_collection` to specify if bot metadata should be collected by Modmail developers. -- Added `?autotrigger` to specify keywords to trigger commands. ([GH #130](https://github.com/kyb3r/modmail/issues/130), [GH #649](https://github.com/kyb3r/modmail/issues/649)) +- Added `?autotrigger`, `use_regex_autotrigger` config to specify keywords to trigger commands. ([GH #130](https://github.com/kyb3r/modmail/issues/130), [GH #649](https://github.com/kyb3r/modmail/issues/649)) ### Fixed - `?contact` now sends members a DM. - `level_permissions` and `command_permissions` would sometimes be reset. ([GH #2856](https://github.com/kyb3r/modmail/issues/2856)) -- Command truncated after && in alias ([GH #2870](https://github.com/kyb3r/modmail/issues/2870)) +- Command truncated after && in alias. ([GH #2870](https://github.com/kyb3r/modmail/issues/2870)) ### Improved -- Plugins installations have clearer error messages -- `?move` now does not require exact category names, accepts case-insensitive and startswith names +- Plugins installations have clearer error messages. +- `?move` now does not require exact category names, accepts case-insensitive and startswith names. + +### Internal +- Use enums in config. ([GH #2821](https://github.com/kyb3r/modmail/issues/2821)) # v3.6.2 diff --git a/bot.py b/bot.py index 08782084f1..206f4259d7 100644 --- a/bot.py +++ b/bot.py @@ -870,9 +870,15 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) invoker = view.get_word().lower() # Check if there is any aliases being called. - alias = self.auto_triggers[ - next(filter(lambda x: x in message.content, self.auto_triggers.keys())) - ] + if self.config.get("use_regex_autotrigger"): + alias = self.auto_triggers[ + next(filter(lambda x: re.match(x, message.content), self.auto_triggers.keys())) + ] + else: + alias = self.auto_triggers[ + next(filter(lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys())) + ] + if alias is None: ctx.thread = thread ctx.invoked_with = invoker diff --git a/core/config.py b/core/config.py index be53807f3f..102f3cb102 100644 --- a/core/config.py +++ b/core/config.py @@ -91,6 +91,8 @@ class ConfigManager: "confirm_thread_response": "React to confirm thread creation which will directly contact the moderators", "confirm_thread_creation_accept": "\u2705", "confirm_thread_creation_deny": "\U0001F6AB", + # regex + "use_regex_autotrigger": False } private_keys = { @@ -158,6 +160,7 @@ class ConfigManager: "close_on_leave", "alert_on_mention", "confirm_thread_creation", + "use_regex_autotrigger" "enable_plugins", "data_collection", "enable_eval", diff --git a/core/config_help.json b/core/config_help.json index a0584e36fa..970ebc6229 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -678,6 +678,18 @@ "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_accept`" ] }, + "use_regex_autotrigger": { + "default": "No", + "description": "Whether to use regex to compare in autotriggers.", + "examples":[ + "`{prefix}config set use_regex_autotrigger yes`" + ], + "notes": [ + "This is meant for advanced user that understand regular expressions.", + "You can test it out with https://regexr.com on `PCRE (Server)` mode", + "See command: `autotrigger`" + ] + }, "modmail_guild_id": { "default": "Fallback on `GUILD_ID`", "description": "The ID of the discord server where the threads channels should be created (receiving server).", From 71c27a2cec7f90a70fbe1b57922ca0df4890a20a Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 21:56:24 +0800 Subject: [PATCH 147/705] bugfixing --- bot.py | 6 +++++- cogs/utility.py | 10 ++++++++-- core/config.py | 9 ++++----- core/models.py | 1 + core/thread.py | 18 ++++++++++-------- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/bot.py b/bot.py index 206f4259d7..b85a61856b 100644 --- a/bot.py +++ b/bot.py @@ -876,7 +876,11 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) ] else: alias = self.auto_triggers[ - next(filter(lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys())) + next( + filter( + lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys() + ) + ) ] if alias is None: diff --git a/cogs/utility.py b/cogs/utility.py index 9216eb7f12..950baaaf14 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -2,6 +2,7 @@ import inspect import os import random +import re import traceback from contextlib import redirect_stdout from datetime import datetime @@ -1718,7 +1719,7 @@ async def autotrigger_add(self, ctx, keyword, *, command): embed = discord.Embed( title="Error", color=self.bot.error_color, - description=f"Another autotrigger with the same name already exists: `{name}`.", + description=f"Another autotrigger with the same name already exists: `{keyword}`.", ) else: self.bot.auto_triggers[keyword] = command @@ -1780,7 +1781,12 @@ async def autotrigger_remove(self, ctx, keyword): async def autotrigger_test(self, ctx, *, text): """Tests a string against the current autotrigger setup""" for keyword in list(self.bot.auto_triggers): - if keyword in text: + if self.bot.config.get("use_regex_autotrigger"): + check = re.match(keyword, text) + else: + check = keyword in text + + if check: alias = self.bot.auto_triggers[keyword] embed = discord.Embed( title="Keyword Found", diff --git a/core/config.py b/core/config.py index 102f3cb102..85d0797488 100644 --- a/core/config.py +++ b/core/config.py @@ -92,7 +92,7 @@ class ConfigManager: "confirm_thread_creation_accept": "\u2705", "confirm_thread_creation_deny": "\U0001F6AB", # regex - "use_regex_autotrigger": False + "use_regex_autotrigger": False, } private_keys = { @@ -160,8 +160,7 @@ class ConfigManager: "close_on_leave", "alert_on_mention", "confirm_thread_creation", - "use_regex_autotrigger" - "enable_plugins", + "use_regex_autotrigger" "enable_plugins", "data_collection", "enable_eval", } @@ -169,7 +168,7 @@ class ConfigManager: enums = { "dm_disabled": DMDisabled, "status": discord.Status, - "activity_type": discord.ActivityType + "activity_type": discord.ActivityType, } defaults = {**public_keys, **private_keys, **protected_keys} @@ -282,7 +281,7 @@ def get(self, key: str, convert=True) -> typing.Any: value = strtobool(value) except ValueError: value = self.remove(key) - + elif key in self.enums: if value is None: return None diff --git a/core/models.py b/core/models.py index 8d1be4130a..0ad40bad1f 100644 --- a/core/models.py +++ b/core/models.py @@ -219,6 +219,7 @@ class DummyMessage: where all functions that require an actual message to exist is replaced with a dummy function """ + def __init__(self, message): self._message = message diff --git a/core/thread.py b/core/thread.py index 4beacf31bc..e16c73934e 100644 --- a/core/thread.py +++ b/core/thread.py @@ -11,7 +11,7 @@ import discord from discord.ext.commands import MissingRequiredArgument, CommandError -from core.models import DummyMessage, getLogger +from core.models import DMDisabled, DummyMessage, getLogger from core.time import human_timedelta from core.utils import ( is_image_url, @@ -201,12 +201,10 @@ async def send_recipient_genesis_message(): async def activate_auto_triggers(): message = DummyMessage(copy.copy(initial_message)) if message: - for keyword in list(self.bot.auto_triggers): - if keyword in message.content: - try: - return await self.bot.trigger_auto_triggers(message, channel) - except StopIteration: - pass + try: + return await self.bot.trigger_auto_triggers(message, channel) + except RuntimeError: + pass await asyncio.gather( send_genesis_message(), send_recipient_genesis_message(), activate_auto_triggers(), @@ -896,7 +894,11 @@ async def send( except Exception as e: logger.warning("Cannot delete message: %s.", e) - if from_mod and self.bot.config["dm_disabled"] == DMDisabled.ALL_THREADS and destination != self.channel: + if ( + from_mod + and self.bot.config["dm_disabled"] == DMDisabled.ALL_THREADS + and destination != self.channel + ): logger.info("Sending a message to %s when DM disabled is set.", self.recipient) try: From 579dbd41c900fc64aeed43525cc88c53b294de8e Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 22:28:07 +0800 Subject: [PATCH 148/705] Fix requirements again --- Pipfile | 4 ++-- Pipfile.lock | 16 ++++++++-------- discord.py-1.5.1.tar.gz | Bin 0 -> 649410 bytes discord.py-1.5.2.tar.gz | Bin 649387 -> 0 bytes pyproject.toml | 2 +- requirements.min.txt | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 discord.py-1.5.1.tar.gz delete mode 100644 discord.py-1.5.2.tar.gz diff --git a/Pipfile b/Pipfile index 348c7846ad..e266f4d102 100644 --- a/Pipfile +++ b/Pipfile @@ -7,14 +7,14 @@ verify_ssl = true black = "==19.10b0" pylint = "==2.6.0" bandit = "==1.6.2" -flake8 = "==3.8.5" +flake8 = "==3.8.4" [packages] aiohttp = "==3.6.2" async-timeout = "==3.0.1" attrs = "==19.3.0" chardet = "==3.0.4" -"discord.py" = {path = "discord.py-1.5.2.tar.gz"} +"discord.py" = {path = "discord.py-1.5.1.tar.gz"} dnspython = "==1.16.0" emoji = "==0.5.4" future = "==0.18.2" diff --git a/Pipfile.lock b/Pipfile.lock index d88503c8d8..92c9665c26 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2be2574267d4b75a621fe0a7202531936a02f5bc0cd0a79addf757344a3acb4d" + "sha256": "085d6c018d43b9b4c4b5bc5e1ff99543b00c735dfe744abbc5a813048b2e1734" }, "pipfile-spec": 6, "requires": {}, @@ -58,13 +58,13 @@ }, "discord-py": { "hashes": [ - "sha256:5aac5a89eb8d70ba7bb5721ad9b495b437cc46328bab6a9170a4e0f8a568a9e8" + "sha256:f52ab61650d5fe2726fb645e4f23eecdfcf3ded74645f3978a010259e1bc28ca" ], - "path": "./discord.py-1.5.2.tar.gz", - "version": "==1.5.2" + "path": "./discord.py-1.5.1.tar.gz", + "version": "==1.5.1" }, "discord.py": { - "path": "discord.py-1.5.2.tar.gz" + "path": "discord.py-1.5.1.tar.gz" }, "dnspython": { "hashes": [ @@ -413,10 +413,10 @@ }, "pathspec": { "hashes": [ - "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", - "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061" + "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd", + "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d" ], - "version": "==0.8.0" + "version": "==0.8.1" }, "pbr": { "hashes": [ diff --git a/discord.py-1.5.1.tar.gz b/discord.py-1.5.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..31eab92a92e5c718020fdba80f5a9ac7cf7016bd GIT binary patch literal 649410 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 z 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 z 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

    bI~J_^wPCSsSR<~v zTVt0SI!?0AWlov>cQ%>N%4@`^9P>;I%qNFo1=4Ib)&ntb_QVRtsD~W+b*Bz-DApwn z?e)nYR}9Ea9T_p)X+lcA)FSTHmgK=%8`64?J!vz-iF^!gNj3}Z$#41IWN1f!qPu+< zY2P)9KvOmGS-61oF5N`Z8XhOjN*n-P>*FmSS zXR1z;=D5z9k@a;iZAs7_+4{O}*n}Q>RWA?d*@t-P_vm_5U)Fn=L45sB22I8k7*4!1 z$|%;arL1$PuJMysmBv>tm76TSU18ewrA{r?o7QsmjY;O2%Z^&)b!b~#v*S;zF%A3G zaapQUx3rHCC(lxhj zzRSt>Emm~&9Ny%d*R)X!y?YwY^xavq!!IJn)PL)tCH=Rr9vPJKEM%DL;sv2LON=7R z-tL=_b!cm)OB=YDO{ z@KAm7q|lkDe(@kf{rri`hcTqdyIi6;_9yAz^fB39yCrw?LMoT@@)lPzV35w<7WZ_l zt!C=_8wKhW$AZ33tAPfme_LSq>r9!}BpzZt_d3*VbJ>#;BRg=QOXBU5|#@C)nq1UFBM` zd3FlPeQ3*hE*znwsB=|s*Qf;99p|GK4RzZ&s{E#SqzxV%N{4OL$-LUk;BEE@v&t`< z?bLZy9Wo0ajJ45SR$OdaUCVQPP9xi=^Ll3{wpihQM;7=i*2y|zSx}92Ej_GLjlqUa zH*ClhKW6Vcv27y0-yr|mf63l_Bued1Yq7&~D17Ue&VcfGWw@^No+VLgyOzf(!;2;< z!%3_%Ji}1izI7a|3@;B-hOa^iMe**W44;nWS@}f#9)tHqYx^Vr(fwbohS@0Nzo=pU zCp8#;P{Z*zYPkGT4Q@~ISb^tv@%jz?{h}HsoKnM_Luw%V)S%g_hGT2hV82)mMKjf~ zO|6E%V%0Etlp1;msv*W#4Y%CYu%wY1)|ji|!{>BZ{x}_GT~3FS#pw{VDIHoZOoxH$ zbT~RD9j5k6hXozd;aUB3SfrBB%&R+?od6e@O$SG7Vk~N`nI((%@2^H1K+p z3NJ6F!kZnb&~t7oR7Iu2b-z@wb4rDRFDWqXY6|?hJq6rmq`;@J6tMA3fhqD7P&`Nm zzkSKDdUi7ShvWD5$*{mM8QjW}zPaxDa1!XmOacR^Nf2H(5v*rV1jjBDA^UXNF%TL$2K@BKz?}7w;NB||I{Xy@zs-t(!L1@7;ml}w9X%Q@nvMp`KSsfJzfrL5 zK{%LC35WCc;qYot7$gh~gODeouy$%F^mPb@VTB{%WZ#jn;=u^GlrjP)S&V>~--pA6 zPQziznGiS{76L>69tQoV4udT=!ys-$Ff8{7hE~UiLbJg`VcLTs&@X-nsL2qpnKc;d z+75;(Yl9%Dbr8(oI|w>;9R$5k1;VkwK-h9)AaJ7x0)0FHDklv9^_%`MC8a;StPX&) zSpiVbFaR#(_Ja>5{b25_zObNHUy#l5hbOiC!Dn_K&^PM?o%4Fb9i!gxKBpIC>GT41 zdQW)z-Ve?y{lMv24|p=R2e{nr4%dRa11aqWOM7*LO~t;@*25QCZ|MrF8+V0Si@Lxw z(=Kp4!w2g9?F|niy}`K*;6X0{y8}F&YRSXfWeQksssJIy3ql@u2Gx+xV0^R_*t>Uv z%_}`&zlkUGNbrFEcRRwhJ{{rS?hY`)u>&Y`+r#G8)YVU#%dsUn^+4!xhF^xk9taEn&iy7SPe71>`Mi4rAWAz^TD5 zuy40Bw6%5y_xNT&&ozb1u1z6nMiW^7&u2QVc1AV zcvt8EP0StO?wAJPM(x48jy+^X)rahZc2KXb9dwPZ2jrkF^si$J9mdy%?HU^>Hn)K> zqw2t#UDhz!&>HRxv4Z;rwL$&C5_a~ogp4H?@Tk%pDm=^~dzu{fU#bPO8`pv_lgz+a zFom7Qrtl%i1a7Z3hEY#tFx68AJ+qBq(-}k9TGtQ)!wq2RANr8>w;sq9dZ5VB1^H-Cy>Ii0 z!cBf==Nr7io@@L=_cFfK)+_vNm&^S7H5d6b`%*q;;d%a4t#kZuQ_t`hKA+;#lqdPc zk4yMwp~rdWOGo*YJ&*7+G>7=V+z#?b*A(%#btwOEnud3Mzn_0GZXe(F+8+Kz&qBWS z-d+6DW`FXn7w+I+>Tc&fW4H2pw>I-Zy*BZ!cW>n9HZ0(iXRha;y;;XU3th{no>#g8@qn7dcrAzpEofh+T@_*yq3>Wfuq89Kj7k=SQI?m&#EuF)!sGi05 zA2pL-eRKvt&n1_4oH>mTc$&jE3drVv+dhTgW|_&~dYH}^tWV(&jY;HNH&gLXAH?!{ zYh(EMunD|ZgRy-0wb6XVuVMVzfDwE>lVSX+!-M&UX@UHN4*mJzPyKnit{4AHNDuy+ zr7!>6ac}-inu5=0+lk-uumeAQi90{b-;M7=T=}#eE_|2KP5F7&jro|P4*d1W_4#W} zZTaZS*8HLzOMX~8Ilu3&312wZh!5oT`2|%R|J?1f!eGW5MeN;Y3inQxihlF%D$YK- zuGpoxq|lvzMp5+WnBryUV#TsK`xJ-n?o>pz->g_V?RUkXvXzRJ%@-@uQ+`prIhm(0 zsh^{mb|qEOeey)baI0{|%Uf$2_$oB(*7wpZHy)z- z5*48l&ctaR+hl0$j!)G*NtmSxX|_N!>hcoJ=j?n1zRVa0ABVb6EmJGxc~4f$O-^J2YlbZUXn!|o3uVCyEKyvr8h^`))C zoUz-5%^!9M{xkm+V(fPd=35E{H-4{h_VhmCamWE-N|i=fkVFLs!(yTFf`h_J$HT(B zO-F=x9ghj62agMl{7(pXFP{`@hn^O8Rh$uyOgblYd3RoLRhJ4``j>>Rd6$J~^Q%Jj zf->QK-Rr{8Wj6$Shg(AT{M$llqdP+Jn!AFz(|ti$^FTP&=#k)&Um*~O$AZ(cDq(fq zCqnXqr@|ld=Yso;7lNhUE1`SZ-@@6~uZ4}#Z-uh^?}Q=4J_yd|KMFm%e-?J_`yzPQ z5W4>yq4#q+x}%E@ZSqlvcHXH=-;CFz0~_hnfo1yi^&A80(cO^Re=?-2w;R!8kuo~d z&X_(wYfN8dnb7$iP3if^rgYPCGwKvji+bqDX~j-CZ5v@u>(;TLza6!p+a_DmQB7;p zEthK3dD&Lf%-xzg+_9#|XV;-dUN-b*g$?!lwJ!DZv86ZuvZZ>9>d~Suc2xevjy_*l zpN{gjr(-Ma>6dv8Xp>G3^u`?r+BnyderVm0j=bEE4oGc8FE(sU?;UMS)f1fPdU+EX zva<vO`b(KB zJv6x$O{(3R{<*a^jqmM73m>{sb!HoS(ylFCysIsJ+}E9I9=TJ?jCQobragtN?P;Cv z9cavr4zycbN4m_=gT^lNphw(1>B7UF^x@!6bjRaP^iyhQda#xk)m`O9i`^9TLy>}R z4&dqa+dR#R0lMxJQ12PubfAq7Ennk9@3-zkL-%)~1G{&n!nv+=MX)b@bI+F^jOs@9 zUw5MiQoGX%-5xY|Mi08&+>bU{=tmvxdeYe|d(w%Gd(q~hR`qEP?{J& zln%W=l&%g8ru`2G(@6JW^lttzdPp8ZjnhJCVPyzCK4>`Qi-*&?El1G73rEoR)gx&2 z*pYPX`H|G!Gn9s}3Z<_M!svsjFxu%t7=7L$oEj|+rx{CmuI^p``UXv-#}X_Kj= zY5K#_v}5-O+IL+9J)#>)mxM*q(?TR2VK;{QCyb#>E{vhRu48HMX=CY@^09QH=Qx@- zZyeRD97oGwJe4gRPZv~;rzzeO=z#?j=+KG@v|r~ax@uMw?R`6n_H&D-n=_(m#JOmy za)_a~qho0P{usL7Xd-PjXd->LY9h7!Ya;!%!z4N;V-lTPGKtD9W9h@8v9xx6EdA|K zERA)IqpRZLXw$+t%6*KZZTWb*CnKINI2cb4>ndqaUnOmnt)u~ml=K3pq8mU(FQlqy zz+M$?_*zA~xlN{;@ssKFwUg=ZHz(6NbrNWqe*%4$oj?cgPoNer5~zLCM4B9&NSn`2 zq%DdQY1*qq+OSCytrL_)L#8Itm%EbawfjlbvUW0E;+;(6qm$|K#mThJkz{)NSu%ZR zn?l37rqFs(DYVgo6q>w0g*x6%p*BXTG{iNPKJTAOOI4{y!o<={Uq|ud&)95d|(`f01G#dUije;zlj%%Dw?|7xt^@GyszUXvnmy=FQ zmZsCg+taDpv2?ondOFQ{mQHu+sA*ekHT~37O>29o>101OZ8k(royMqXj7m-Qv(&U= zj+)voQ`2A9tLexcYN|Y-rc|9%cw}AEhJ%T1CvQA4I#x#$Yhv5BH4|ro4kos3n-kl% zZ6|+!hyTHSt*+}?wW|-;uC=R5Bc{Y^l7MrfqoQcYq3q=P&AQC9qG&I>^rTb6TKigE z{wbj6NT~c|hvm6bTOMe*wuH6T1#?w95oxyxyS!=VtA`?{SeEM2Fil=r z>>7e|n#&qrSr$c}em0j*J`D77;^^zj7v-V|mwn1{>>+@HJE;I&4r%2$i@8>Iq`dP} zpZ@u+sIUHs&e2;1Q8lzcSYr>n<;8;i9925>PM5twJN=tQ8%=M_t$0gZ2D~35mWYEN z)Ug+hVM@Y||F$WQw=9eUg=&s>#kZ~R)Z(gx{f%rlHHQks#Kf3zS;ZzIu(i|nV^qrq z4wx0AS@2Kg#)cBY$m3fWC>drPx{(o3f8r68j(H$uRQGa^Zk)EYJct>i@sY5aqks8b zQIP+Q4HitrV7=M4)RdJFt6BPh&GD5jliOh|)-Z9DZ6)fH*2r%y6OK z$WfgO8J80+G}d2i=kA!ihTV@<;F%MC(vJ9BKF2Q*ctX~AhY&=X;3-L#cML=AXE2LyiwrvIM1kjC{ckku&DL@Ml5ES-B1Ok1OK*|y+SS%^g(qM>#1 zry(w}e3WdPg7|~ZMCfW^)=;>vivviOpZgGnrm9i+SGD>|m0jS&|BB(&YuC7U(iM28 z_na`WYhv1c`

    -iF+Jmry@ALQ3-w0MLchyGBI@iHW0vbmj(R!8QT4IjBw3pu9Jy88|1{LsnsO5iFs`4J#NiCq~ zlK2(x5nfHCF|dR%dp%%6W?-)}Y@>g*e>df@7w};M=;pJb3~)d8?$Ro6d`FF+qRljz zJgU&{+lu*&&faScG$`bct@g0Stp*0b0*!__gi8Fm0$$Z&yNQ%NUCQ>KJYsfa-J^Ft z^!lH3%Y$C5%Z0lFVt~L?HIJ@0DTn{{uLSNKPEP49$H%@+2WMmM_89OeC1=}OjFe-^ zdtT;|I*{E;V^}=O?Kp48P&l9e_+c<+f|&2;gX1G%uWWi&rTSiHpVe36)6{n>-aw%h zkYh}Gm8)4^r{TL=lFyUNdxkUb8KI$BnWZnecy(1Fg}O?6_G#RGF!2)(%De)&z2|z@ z)49VgZ(>0^(Rb8wcyO7UHZ&q5--$EFp(n&LO^l{rncC)4ZeG(Wp<;24FrhqwGeLd_ zm*!-|!ik|%&e=JO99)Ys5sVgQjie~Cgr$ALiOqGujRi}ujc};3ihyU#hoth*2H*7O zJ(w!lzwftTP;ibtd0$ffj_BpKQ{Mp*R!CG_Ldd{cspxi+9Cr!U$H%W>QQZ# zrnkoT?|%RJ@@SA-DySpGq6y+)K6Rmsa(^%}YCWo#0QZ6%bzZc>?SGWm3rXrRxt;XO z39jC@3Vom(OT7_u=b@|;&XrKpG%#66-oyVwJl*4g$ z>`J=L`E3dX!Zx2OCS<@)>$}0tV$})1KI;7^cxQ40z{RaiAQQ6H4CSI14NQ~Ks z{Cs$I)J7MKgl+0=8yTBvIC+F$1@OfSS@MN;weyCWzq2P5J;&tZRR5b1EB~i5w~1vr zGlp=#=Sh5C;da3coFAPu}Bgc%W@+K!BuihoG(CxV&h9FjxUUArtU-f z-gU#Y3@ckML4j&+5tVM9jw=L}P9~SSsMOV2iJqiY;IBe!g3K6E;Y@H1$Et}J;e`ip z^dy&jvG?YQ>so>9>sX|#wo<%;LAO*fJrSqdNkP$Juk|X0h&yOjPz?9XgT-DsPoJ5OQOj!ZwrPU$({2@6B1G&mbNl2O+z3WFkS z_=KGZk&pkv`VXn}wz|-F=w(8soth3GXCwRniO=aB6bGHqieBI%On1JSE@Kz`?jo1D z#wSKg@EH)XThc6X;6PBEh+IbrZ{T)FqU~s%O7}1GXl!TPU-Mpi#Y=Byx#==DE*jvsble@q^;CJwNGTk_h#?-I3UPK{DKPUuOGD z?9a95aaf`kgP7`_JzB=2eB^+=SjO}*G8?v_tv3tY09#}BEk{uf2Mo;7c2|<&0Qd7r z{;r$tbW-cy>dehRj|-z-w5r7e6A8he#PhmJy5-=nL~O2|2Zsh#u;I8KRK(}2i#2U^ zcNcv9EUI@0#@=-OOwf?KoUeql$Ia7VZg&XJ^jp&mgBsJ0KYka@EVIiSBy@8=y%Hf- z;%Ol`RC8c2rZ(gHKiyzT#9q-oPr+j_v=_)7o8kU8{l(Cgaf1!I^TgY_mTdwXJ5JP15TEWDGY^exmcP@41cVE!i<~5U2 zDsUmyX|)Nk9a?eCFGCePZWIzc3EtkE2Tz>cAXtyR{rotIM}u{j-J(?LK2>=jNhBq`PDf{<+>4iQmi!GHIS+PfeHLi(EDvu$C`e*vRXsMOm zXOI1>-#*rwP2woU8S~q0)FeVzQqbS!LJnP&x7CVGTUuB!821sbi}Def8)M-pwHP~= zNujSc@(eHMou<7lsE`?nVOH+Ma;vu-kHM$C<6Dtw3KIx%#w#RB+{fQ4SZ)2!uzK4c zxGkYfUsD9))1fy`!6(um23~B{ho=%1VGv6mtcFs7}(})N+VkJa7+G?jS@VUokDv#x;yY(YdDd}TzQxB!;GBb->v`B3d`FL5SlV?TA)_IuP6Pdo6VEp{@j2Q zIvek~eP=$9#6fPS#EoREs4L||LAh8!?nIr1FUh1F%Ry}y0a;6hBIPps3qOIc0K@7B zUoMTav1A&Chq0737ToM_S1Ou;P!5{PL5u;;>^A&nGHd%_CvOl0JMM!c&88`QYB1k| zq~9xOrlb(-hT<0$qMMDhuQdG6Joly&Ek(>wK2CAJ*951MLZlmVF=<9?+t}6D1b8_y zti1n%q&TcEW!mC)#6#Ma#5#TA9OqjwtoZ|@hB!EA^`uxM`tLb<8t$p%Qu>O5X+@}D z=N2MeX(@+ImqB7lI6xs8i)vX=cKRAJ{7Xw$1%mM4P+-!8Ti zsN$fML)FP-oJaJPBNo+j3X>D&ECT}KCAbpOEgyDFac4lZmQPKVcLu{E4eodi_twsk z7r;O{a{ghx1|PVF7g1;I$_)~x5B}DuM>GnR5&K(o!3BiQhTsh0tp|z`Q_9v*QY0F{ zu+S~O;9!2TItXyw-bIyZOWr(fLOEQSt;B+>GCgxqi#xvF>tczv4 zi3fa0#N-xx=OiyCFdVn{niA4c#ZHf9&h*QUNZySYw3Nz^IVqEr7(};j;4!;vd?w}NF z5nM;V_tj&LYacx!w@1aIWlnbyZCI!6TGyV$yU8DlK16jX3Xf7Lpyp1niST^>bHBso zJqlSua`u{xrP>MwfqJbBhY}mVhKapyecUNufbj>l)v3UKS}W#++aiuGuE$+u}P3H#6vDq{~Jtww{QN$DHgU(x4ijr3<-)bwj!L z&xtw%X7^gas()f{^*?q4(C4~)6>xXv_n(7Fm!|Lr_T3StLjeq*s}Uu87H(_|i!o{^ zvkal#2Y9Q#14nuELNqCEdy*v-r}C*Ej*>h8@qMe^(TQDMj4;J;U~}r7q-mPd%(~Si zA%=fM!;$~ND&?U;g2+0vJvzlknu=30kI%rheBO4F3!?ag1$)MvV?V~&qb{LG!kh>P z8C7%(oi63Twcc!q&V-wY>Y3xty2vE{jrVVkBXh?IjKWxH7JJGiBqy8k=pzNkr0_4K z0;VUVC0v4=c;sz&M`#dSk}k2wuktYXZV5go*%pQH7c{DrwILYF*)yk+bbdU5h?>)$WYEq)8|N^3iM=^~j*;+#x;^gc**r8r`>B(MzK9lBf& z4``VF*PK8U{$4&Y=u((L!hXhgGR}0sN4X>vZ?x`jkIz0HBfC@O5;{C(Qb52RZ4+AI zEAH)h)=E08B4&^55tTp*Jr%#WPF%%#dr5FIWOwjNj&-mue#vMN6xAil=iKc?61V3t zVps(tiW+a)!E9m3fOdZ5g0!cG8{V~MkI!G1+OL8xKD2k4eP4oAz|EFztIrAAOME>KMCR{nGKB8QXL%-f%RTwf9V#;yGObyN(3YC{;ksb6pTJ%iIhJA)f~N%P4eOq!4Q1+3UAX z8Ro0*yL`BORM>tD!?%qaCncVM%4-i{M&gp?@Aod5--Jk-kWk7^0%e)7X~?2Oflt=K z7+OCKKh8ndB_H2f%sfOb9c_pcdw6@<-5B37eYIM?lR;P0tfMFXp)@pk*ZWmZf>K+H z(^s*wV~BsF>iCI{IPv<)BtXoCdD!&+pY958#!Bp{n`qBv7pmTZAU-DQ=^Rd~*!Bb_ zrFAy|9y3qgGX3nA<3v5K-=jaorh`cS{>RR@N_kHAj~shtlGmzVzzlmM*|n9&P%Mq} zW7oZ`Yl=olPX7gxjB~=-J3Qaqx0rwTb|QGk^M!Po*~chP3Op((Q(_51Ovf3DnLC>p z8mpFJw2q|qu9w3x=(TN3W_wFY-~Hh_ByPBSe7BAJH8wu7|9ifn>x z!1$p9xf&(U2Gv0RL+92~C9>&Y<{!4*ME(TbYL+CK(mhP9Q0_4ish{|ahQMo7-j(M) z`45BJW0lCRgP9?0zlr=Qy4Ng8WTgS9*p!@b6jHX|7u}5l#-SAMo&)GV7;nPqBA0hD zOt5SJQ67Fbj+I1K9-xR#DF~M*Ws|`u7cfquaQ7Nu{lRz_ZWXzFh_Q!VJ4ty+XPhmG zsjqjoL9M#S!^iK~LxW_yf=9GLg z1Rg_Vwr=(cmhV}?uz_I*1Gr@OVZCI31LMO6UcvaVgI6#4PC)APP`DJG*EvwIr;vm@cvr))swEXBhg>K4vu9d zEctv;_HmEe=QiHYYh<&-G(i6rj^!mR`F&9KbB{XUHa@^>WUFI8K)(-~WhW^4x=;3b zhg#qUv&$2~p(7Xwx`xLT66s@*dWJ!m`frDbsv{^k0Q3xj2^8K%l6r@XQ2g%(iK^?@ z01)&Hj|mjnWsrJ@iJ1EDhKQ;wXdnP|3k|x31KlElZqY!uSfE=x&@B<@mJD=D3A&{P z-7YQ8dsf7HAX?G)e>-B?FC8f<|dUqYR)?7SJdFG|CMc z<^3Jhl2S^M0L+Ab?gC}egb=dh2UU+cmzKT%vVaPdugfT zWN-}f+yGHgvXEeZLY8tjjZ;75S@3ZS~Tk~&@j#{heP z|87{YKPrMB3Fa$5)xDS0@e?=(*h8$3G%(l?0>K9o^AVcr96@Rs4^+ebpHYBtA89ZA z+c(N{oTwTD*1jyT0ZVyK5>*qx+DF<4{{~NaP90T~4OYMgBIP+#R82Qn>4$$qrab42 z0$0QKWq}P;%5%Y}nlG?20RM(gdHy4+hK#K*3v6Igp3CDH1(d=2sQy?krti~N!+0!@ ztg%oF_A944*E8dF!p`3tj-z~gv>Q`tZN?~{aoYPAeRqV$bo2C`1{M2s_++jajbt_T zYOOSlN2!EJqgr3k@3qG`AeM5#Y1MO^{DW`nKk&ZOLfPaPvaR~*t-X7Vp;UkcDj74= z^_lNqu#@c3R5sAv_6aH=Hv8jqIOyi<`kJ-T&C%WMY<{I)cFBID)B7GBzVnAMS%f%^ z#&bXvUiM@+hH&J&?b{Es=4YVJF$nQ)5w9sWO zXa@cj3uzv~lr-`Tnw@4>wZN*afX5=4xk;_r09#vc`_H<@Zu>R2?ctF>++V(ruO@Dt zo8uD>uEv+~D20-f8=jgsxf1<1=Xjaz)<>l}EM3Q1dT_Ld4t(BwX3)(p!p{xV>1bKq zU#GH21FpsG+hFPV&?n2z?#yEEdH+s%WwvG{d6ESq`ikxY_kW6lxv#}P*jf$q1du0JQz z8FR=-=C10{Tq9ZYsrv|Bg2fmXjXS0Z%T$mElrZtXrRI8?EjXPJrJ%&{qd4NRMI$K& z6Uusaua_%HDyfj~2Q60S;(&9WD7V6;M}0r# z7S>V5)HELLes1u2X;K5-)HrRQkp8Oq=Z_9#{t~RH?-BhrsX3mlSNoo<90hDZYwGjD zcc=dkS;tj~V69#z8ij-(FWs^YU+1F@J^j{GFzLPYn~z~P(VT)na4H#p$is;*27kj1 zP13>vdDHGPQWViUq>s8<(9DrdZGyS!u|O#523L*IGyrRP;UDJfLsQ6Q!nx5YqlKrR zljO6xkwr?<22LNFpkceh=Jf@Dti?Qu*jvZ=Iu^#C_0EN*Bnhr>65(U#p+n@_Z4>>O z+8k%qVK1l13rdcJ1kvLQ6IC%gHkkWTLhSBO?X|lTF?ddRpvXLxW-|{# z7kP0H)}Bi4UA5Kqe4{JRts3n59UoRzTPBRbWeSvvN>SfrW^r$Ga&fN#jj7npm~9K{ z$O4u{QNO?u@iQYY+$B#Uw8Q*Ck3yDp3b!tbqJmm~AE&jaTQ;G#o|0G?aKZ6VmeW_e zG!)Kefwfy2g~fW|+W!wB`@MAw%npet64Z_D&6|mw($}UE{k5Z8L!DtW1{UQ%WFqWs z+NaCSmBLP(C8=?#C{iFrNdOrzq$Mn@zLKtsgL-&GE(U>sMBw|h!O2{Hy)3^A^J${j zX+`4kbZvjM>Qqcjlez6|{0pF-cIZcF6d_+uY&CM>dTuA3)dTpQWNtRWxc^@?{OOVk zHHNEOJ%t^kcCBTMw~V##`~X`&ENsquM}`!CbA>^t=V!$U!AJrHO%(BOz{bWYg;NI5 z?|r&!)-HXqT8oYHu)C`32Umw%Ataw+PFydnuHo;0p*VyDsFtRl5JF17MgH6EX2FuF z=w5Lz{22O}I`$;e73_jAxE-$X*N=z!5m5~YuPzR&rfYGZAOzR#+AKwV8tHt@y?XBl zfZ%>vcN2WJ`nPtq;{SHIY!TUmjV0nRcTBS=lZ+fXf2?0);r#mB9@d#`(wv=r1z56Z z;!)(21Rtby{?1w$cmMp5j6UaH4X~Yp|IxuZW>V&3xg^rJEz%zvbqdVe8V+Rh8+szz zV(FzEWZK}|aI1Y${$rLz)T*=mhEID;o9d(0^yaH4-|{{@$LVv= zFCTkm6yL1PQoH#*#s!>jLOHJ@1n3j2QBMMDeYA^5GUNHpnzQYIQ_jEC;znTWA8^;a zd{%~1%M1leUTiSf>BIUe7#zD_=_IdzdP+(@sqTC zja+D40n0{+f)vV!aA||1;wZ8@j*jydvS;f|s!1MS03d6l)BgB~8ly1D%uJ%I$KTf4 z+Me#;xX4H@xot8h3)1vhB)jTP%r;d}_zI5z4rC*NJ!pns!L#UH6sE-$GD~(M5*;x1OIWIHP1S#YzM=9qBw5HQt z+E&u1Zww_N-nT_k;Do(zJ-`6)&^f4?#_@X1MxVN!rbe=|1WjaOE^HgMGxM|fEX?&y zB@SmZFjlnY*qf98QB#?kInovvS%fl3(DWAU|HpEh61O*miZYfNIV(1tdAqkY(M&?< zqh_J)m;6&zxqLRZYR=|OMmjnPiVuQ!cCmML3Yy#>1z#Pd z4cceQF!gNvxq@2x>U^a%QQ{JmBIv&c_w%-OF|$@F8#?UONK-4?v=6gq{HRrpwvR*$ znkGL;C_JrTUR8wV2-~A=C>odV-4}yB7iajMIOgI4X=HB;n$}cL+sQdlLquR1AHQdT zyL?w|PAuuqjVHNs(#EAwVRm+9x6~@I=ftdt5;#=bY-x#DQ3U-WR!@-UM(Gb)$m+9h zinJ|KPHSs`GvK?YSZk8$(3Yq3wgF6iF#`YE59JWFVJ-D06x(oI%uWW+M|yE_wY;5t zCoBWzkBk?n$c9;~CLh3?!M|IT*keHSRjhY}AmK6VwKdehleGA$Dl2Py*PI(_X{|KY z*&K8Z6`PNb8l)I#YN~3g>MGmvF#x+uN*WrNzF1f;b$Ob6?$UnL7Z(mF5aVDUGhn%& z&G*hsjz*2;#r1|T$<|@fpdu-Gc{tT_n*D~b(xA0rCOJo={l^lIsjiPvz|MIpHiw}I z-x^*Wu`(R36t&IRi=H2O@mR+DR z5R+Y%UhQD_V)`46(69XRr)0jEi;4&*58>pu8mF+T+i9hu-kX~qe3$hZ)h^2Uh{&)~ zMieKDcVA4d{;!a?_SV+6);!9V=Ja7srZUB9eV;t<2j>T(O`8;*)xHIoH48HScf-%~ zLpw=C<2(xQht;R!;kXMov>1{#eUJ0yz4zn1e#ygP5_)YxhsXZ@ux1DUmi&^O%jSN` zCI|oP_n)61gF|F??#(uv&1SyBw{kDYoq{20s!6p4jguZ91L(mdc^w|m^&AMYQYMro(Yi@;P= zm-~M0?)**gasO&_-n>sNsTG4t%&Q_H0io|YTN=X0i#)%izNC(rpQJPm;|$jt#~O)< zR~iydnT?Ava=Q}t?=lZ#)+ISs*GJDIn$x*J-;p9V$25|>M3XBFM@n>+doE=34sWI4 zW=#nm+SxlWXN|##jhh|cOG=a$e` zcOoA&qdGxq5v3Rxf&TuhtE_9R&z-|Q8V@W99>R!Y0L(I&GP-Ot0?2I$^7Mq?D|Zx*9?f)W8B$zQc(w}1 zZ^FA3*P+9=n(B5Ajwd>Y^@etH+g-k2iG|El>2ldX`cSQD0_`h$$I&-YHUSEp zl0&*v->I!FAgZyd0V)$oPS==ftj+cGT0U}-US|Xt=j0hjq1swu&mCi};kPLJ#D?H$ z6aMC;KZvPQ?>W7umj8${3+rY9=7)4I9kb9EO#Y(inOIBKhoZ4lKASdL@vHT-Gv~oxAVSmH5E_^!wxsI7wg>{5m7RUB|lbEJCpPk45 zkp-@*o82uAIVz*e`l%2vN$*{@&Ro^v+ZHL-<_nu@1KHx$HBUbjmA~a^nD@!q+q=> z_9JmZm+2arqFu(zC;7>k5~({$2VBuXCD5^UeKmJ#SbBw_IooTwD`=UU$ItC#0q?QO zpZo?8>AvA_v>?Rldt1@y!z|=}QAWriRA_nCxYQIQl)Lhh{XY%jW4{uAG zA94G-;77Uwu>J@wDy!cAs};D#`*@6()oDHTLaRp7RstK9t=w?-4@vT7c;CyWnXLO| zc2b(dR^4c1hM{`nrK{hVeet66{vV8VNr?i#)SydTMOMf@m*@bpYi7hgw%a6!S~}SM+8ON{*jFnWZ8mqCdPk^PEd0wzcN(xoXk-a& z4hwm^KYo1Gbad%=$Fwc}_h=xI8Ux_Dgjs`8-;L>mB-!?J734KD)EL3oFUcmGR{LqV zth8)!Oy&VA|IG@TYWL*zi{|UBCHS4?%GA};VI=Cd`_k4S2wVwz%^Lbk+0QjNqW8vY zOOuvR2%}@2$VmEgNNrRa(_kSHYVi43 z<#Yk4(9+TbhlLd$>6@H5;lZZTS1TJk7QS>Bw?bj!r2=5dbWOv%y2{tK1if zb!%b#ueFsiU* zAVVqQqB4VV$WPi zqj}3umqS$1BTUsl3!z=R1GSu2#%YGfO#ettY&~f6xUL_ggpY7t)${9^L~6@XK9GP| zN@XtN1LoN+Ndg^R&?q|@$Yzf01&>*J(WhwDA5EljhR4(r-NGDU?2K9IVa~L7*Xo3Q zUZJ-=yn~7zsJJzQ=7lApuW5-j*)>j+llZr8yCo=sRGN>oCH>}qs$pl-y8eU@UsfGbSmd*^;GQ8U`KEu2#CK{J&Sf|P97K4# zzRG`GXW3Tti-5nrvfybg0hX@tcv$eTb%Y5>ipgfO-HUX5R^_0JAyc}LIP<$iQ{p_a zITMQkkYSARbxpTptn5&iTG#*&ke1;&brX zYwPbE_AiZ=uM{zF3WmwaWz|~xokWx?(x)z7Zu$rH(;V&N*{vD4pJ6P`t3kma7<94gIqi*J)94b$&EiLK=U{N67!a8-r*$&7}o;)~}vI;i@d*PH82`N^)^Ez)zh=-nFG zYN;t6c>SOGd&(Bot4{B)bJj_z`C%M}s;-CcjrdUHzwxHxwFj)#YLigH-Rm&-W_(x-z&?#UaTpDXLq zfheSS$-F*RH&qE5*}fdLu4h$*tX%#wpR1YQKNNM5jxI+bP4N^T3s}p zvbT>DwHSWBWUHpGxt>#yaR@nii_ARkEsd3@7FB_>tvjXlNx6?LYM-eVhbLPe;!?_& z?|t%NRo&0Vo0EFq-eUiZW^@*KK9#mRFlEB{_hOv5Bz?7=Ef4yz*f3`N=#=IU&j ztSB^7+2X|vTT!5ITwHY%GBO>V7lkZ3?~g`Rj2bn^@*5;vt)H)Q-8JJILtY{ zObU*_pZI6OjBnRGc6S@NaNeh2W&B??2B|r+@5SA1-R^os7xVUJ%=*rA(7KIHKJrw@ zsIy;h%+9es!t*e?M4J+4n|R=Au~~NzH$;cd)IX2Z-he)6_Pe>hc#Ka09d<#d?=8yk zz9KFrVtyN8YsoBn?=hG| zS+C>Knf#R#hh=P^rrGX#^SGoKE-j@nVTt*KN{EAL=BceA}I_B9&X;c#4falc{Y=ajHU*Yw)Og9$w@CnL#Ol3WSn&HE}EomlnAtv8wXx@gp@g1qa8H-T^!8iB+;q|DivqKGf6s zdVkYk6}`BwPsQFpz|ZFrK9|W@r~2jo`Z)4gD3i(YpIaji9tNB;E$M<%qk{v9W)e@1 zBtNSE+N|os^LWwvO-eg;g0bP3>|kT3YyzwgKLP!7b#e2yKi)Ol5@Dmme{dWdQx|;@ z@+?hojrovv2QS2ANQl$EZS_W$k}8DL9i4Sd9*Hd^r;ypC#9A0++eRWVOpPqe|1q0R z3Lu^$TwU$DO;04rON^@nfw8{(B;$_ujcyJOUtNr~-5UJN6FpnS#YbF6F)Hp2tk+Ak zx_7TMlfbRbZ+P_euS~?miDZ}wc$h-&ug{Qk%Ege^2m4(sly6>Xfk(vwTCCEG1Y5%s zTDTg%7pqGSH9k+rsj9aqW|rN(@e`Krm+SRL;lF!D9pH%Kq^*pc3Sqn@1-%#o`gt5cYvoMTD5_5a|s!HhJ z^wv3JH+Q@n{?wNcm76aph|>B#rS-LOoqD;k*>|4~w{T?AzUC|2+RVnJIkPZ`3S&x6 z7=kQBCac1e;zuHJ_xik!v8j+GK*bf6co_Q>Q!y5e`iSRoGQGK)F(k2fxA!nX0Nr^$ zv5ahjuX>T4ouQq~t9xi~V~x)6ifbpfaL4ebVG;I_?8&2@zAILJGxASbu$@QKQL9A? zN{(yky!r|51cGXfBIqnhKX&g855IB}Ws)p|j3?V^^H5-lcUiR;TlQJAfxuXy+Qx!| z)JX|$DSkzlqSi*~&BPhcn%rD{?QA^_^|1;P?fT2HFl(=e-%~i*1=&ezY8tR=mv5F& zPKRNqPgq-9{!3RIt<9aASpk6UiH{|WY9f6m?}MAu_c3V}CjG1msVc{E&qw2rKM^bf z`W%VbECvQyYC>hi3{T&i=`4~H#zbC#nq7>1Au=ZM!_O7wqozu{!>fn2R<21AGxLou zFxo{~RmEq^gzgM&)+^ELxDpKcsgfxj-tUTv*3`{S@jAnaxFkO$3$3jPnL1MyOt?Nf zB~!A*gBKI-P4C0{n&W>4H$hMt!VC9prJas=-%HY*(N$JfVh6$XL>w11P!RrI6}6d} zadS;eDxKk~_y2@iy#9$0VJi1gO)@4G(2C9ws;7GI-JuE#i*B>84s8(1_|reJn!=ag zgJ_eZwgj0z$B_WJAK(g$I00+g29u7Y5NO9#yMH|HieA=TX;u``qf%2z&h)dGn>L`t zi^NT3OITm2)9jt}!&m0j!uy)#wLCF3J0D8@ltl@#jGtlg*o7{av%RC~*ea384NEun zxPPRZtE#EB@+f$WUw*vs#5& z0snl#@&{Dmat7j9qFHW-d}iqvKS7&7KnI_tzP7)T?~}S>yg_k?j<+x8Tp{moH~AL} zArZp{G<4bK&Xz28k$mYqW%`J?jo?jCczJVg2hl7F*EQ>0ZR(2GLeP2RDgW{hn%uNa zySKP$KkxE53Ejj?q4XD(Hm^(+Lr>E z)M>d%-3HtB(ps;l2E@BOWK9k_L?SQ3w;_-v^!!F=N=A9q<+u$na1@as5?pwsJ4-(-MkV>}S{3R$Qa zB#KKOJ%uRKEsD9-4yvjMQIVtlt6hz(=O4>uLu11GR@>kvZxdIxA6!w}Y!Fj$M<|6Z zP+JBVdWx7GnZg>pSr&&2RiYG(U2Zrs06e%^kjo8IIaD;bEo)|gYf>=P)DYR$UxHD~ z60!FXfl0Wo#<_Wy@X)Yif)}nXpglvtS~E=BR@XWyKCbC9G-fyL?E4uj+rjNJG0mUJ zoY~2HN~9zE=Flwo8>RtMgd#7A#W36ZatDMF z{&G-P7hDgIK#+hyu};R3_?F4JYthk>kAETd9(fdEaMN+akafsEIyLq?8S-gpEYQH| zb8WVL_;(QUEshOjXt8?tPk7VrjqW z#$a)AvW0O(AR>U@14C;}1zOl^2|`!FbAWoclHB18Zvg+Vg1hck!ZO2y1)S@5oruh~ zz0eKVcGb6xPBovauPR10nZyrkRJtV8c>2$+OQx6nPMS4=)yI7MH*lKzQI9Y}?&YJ9eUahkJZ7U|7 zVLJ|3)mOWc;D=UR=Ql_5iFmZY@;m9r!*%!HY?gz6O8m8V%O15KP@-uJO)Pw8sGK2gqNzNLH`E_yUmAX||<-`K?a=g6)Iwy?{!d|<5 zga<8|Yl)4c{i6gb%=Ewz0oBnm;P?LahVO&OMWg3st*5IDK5CXqvIuia5XWR?j+rEEv5gsDU;h|30Of zl=aF^l`)zd{EYi^S(0%DRR1{nkZF7qE-dRW@m}B>QeUVB&}pJ%M(BOtHCFVSVEY-w zx%j5(GwvG!;9{IWX~(>X@KU_(!&SKZ7m6!g3uG>3h4WUlbyfP0%WX~g9GwN9D2*S{ zNP^uzE2rZIKk#_7?m{TICzcw$lX*Lia85=_ZL3TU6H2lw|dOn_Ld_99K#71|>7E%|}kjy+Mh}_Xm zK}`>r*PnfpHUB2CyooQMG|ypsY?}BSaRlhakMv^b+Lm5;j^!-G2 zF44{ptY=iKk%cs0K3m}%M3d2f?jQdJ&H@K@?nr_=xR#*?|DAg4GaLQ99vp?d?jQQ) zh{%P{tdIY#U5FTpg#TOr{IC&7gPqvF0w2=tG2bwjJm2Vaob7t{vUYlZhiAFoO@R1- z80w9IR&=9AiHD90c`_9f^{)$s;mvQUlzJY-8#0vG$>?7wE47Y#eN-txKGe$Wo|?E@x!7XXbly^hjmrU&_a>1DJ!LVE|SZqvA}CHSlyDz z;6g4fRtp_ms)%CYnH#!k)O5rEUOt>G47s4x^rBvqq7_Fm2`(z&aH!knoRR6L>+;!+ zYfHBZsxEOhH1Kl#SNi5*k0h#f329C!fPEgMTM)_}Taw#P!uh@zO{ib0(of1{w*_pT z$oX<;os_CLX=Y9d576NRS9T8}>bB>#y+G%^uZkD zjo8h~Nbkn0&sGbUKVQb8g&uiCf$7|ba z?_~F7`(@X6+ZUYi6WHz85!mV27Le1h8??u(aoVBGQ|kU7L4%>@R(f2r`yU?U*%YI4@x?yy5 zry;H|0N`G8bE`}>;zh*Kfp!#!G<>xK@Y~k^G4+)JZFNnUcyV`kN-0u`yK8ZGEn3_y zP~5G!yGwC*DN+bdaVHSm3A%Z|-5>k&-kftX$7bf4JJNj;bjiYVDT0UDEsE8&N&pk6 z;yNhx^}8y;Px113G%W&UL?p7m6@A25tH<$G5A(d0>u4vM1h#emlp_HDG#O!-qBgNn(0=5 z6+Z2qIe5qG`)^-LqzkU6Aqookf?C_a$L&XI-BpW^Ib61U-FaN7b$3)~L_L&P&k4E6 zc#4Cj!==c&?jop+1b_NR)qa^eDv|r=Wx(+B;_ZB2v($~>{~I%d&&MG^Kp3waV(25V z(8Ou_c7X2vSr9MHV=UNAwrQIkR>SmtQlr2CSSeSh5*B?wzdgb{Uoh$5ewKm3Aiwha zP>d%>H6LRVGH>?%*4^9Y%-wr?&RwoPA9ISrtsplLlN>(@{^IY%Pu3Cs-(X!#AwS*^ z=kFQtqVU`~_NC!yf|X_}QKXI+#o_D`m4&v%$-+@~#9yQ_RHoG>>2C{+3P}}~t9LS4 z?b>b2Nwdy$hMtD(B2O}ztrvf9NOQ;bLGutgRnffGkuttkhBr}Gnk{H>H?!#sWfItV zpQV!aiZ`CE3UV9Xi(@=%R_%;@;=X;X3D;Y+)4i6)04`PRRO)jJMelD#`*P<%W21A) z7B7(`tbUQUQrFmMOQs=>D~Ae%&gyf2mZm;la3&tK3;lzvEC)cM`78BEvBL^it%X5= zyock8O-Oet-X3>}TZlQJUmu=}O^*zVT#P(S`;9?0NcEP$6PNFbpza+82nYtg<2}B0 zoxdX$Q>y$>IkR3*gA`G*Nj56Z4Z7mAn;frx=X3DW&zM|l=J+bXi`X?QEYa2KBr%(0 zrM}acVD2hXeBD4lv4?+#P$FhoK*ENwZ(#J%QqG5-5%(VKg-TMBxO*F5es_)zWS+k3i z_kcE+2%Uk(d(B?9a?jUD-abIx0cnqy-@A^_f>}PH^He5%z!B)XyVr)8I*Q~Jvpt&~ zyICF=g<7h)@L5`u6)5h7 zXZ4?ERGwR1vpYJQQoou6nwHGYHf(*e_?9^5;8p>nzrb5lAtY(NNA2cWVn5kJw5DmBOhXN{ddVsb87&Zt0y4!?wSz{I_g#6Ftc=J9a234`2J3mE<0qq?*6Rms4(oUUph;Qs-7uJ4=}S zHG45Wfkg+PKcai@cu?*Z>#X$mM1^(Zqsv)9CCjaf!Tud3Pcbv`34D+2R4oX5Y?b1$ z&Qe;>+NJ4pe4u~%S*hOCzm-${gJW~2Jb8%Z{7;;Nr#jlj&SanH9czFQ)yl-e4;!C> zn*go9kgaRSoa+q{E@VO?T(?^Dvvg?-I8-U2l2?a}snNWLbKEVxF0DYfuDQ3Y#ch3_x=?oO)bE(KIfk;fsn zW$;U4ndIAKmUh_q-TK)0q_#dac(^@3?OjY}pK-UYF5ZE%A(l+I%69r9*VT1x#y zesRg}F>ASi_Bs`dUI0O9Y}=fV$p$hwgOckkXEayIPjHN+Z&u*n7m~{TEHBTpGuHd% zEN-Tmx+arE--h_3KGhig7R`q;!zFc)c+Ey#Iq{&C%U#t{)LEK-T1)R2cE|Pm4lx5w zs)z5MCrxE)f22K5F8G8p49l0MD%i`{+BnWVe@_~RIcaFNQm?i$wWoCw zq}aTQ%F=Ra@tg+M22F>t>c4VU6O4b!Rot^J|K`>nN&b z|49Nhcm3yT?rff5$Xh6dc%P22e7@l`Bt&?qAzX{MfTv6OP~9k3-$>5)YNu`VSI&AF zfVIc=u;#giaMfZOxVCiwwm`fveNXR4J%s*i96? z+|sUUbEcc4v;gC(zVX&}w<I5w5Gzzx+mf^JT`*CGuBC@>cu_0fLXy`_>=n} z1?z5#ol3pU7I$-&)T-~MZ>_q};w}hP*8(!|qBy+v;OVxRwfJME3Y_0}HcqMjep3E` zQLbN-LT@GNfQ4<+Q~wlxucc@^Dd`z?PxGC?)(r1X5tQz7u17r}0rkM+%xi5DuhbhM znS%7^ZUu8Q>HCJH>YuEp9NyLX=}orOGm~)}*Ko(G)V{@qO(mtkVQVkT8vGN8@M_mL zIj?GI+`LYEW4xQa#L}t>sjWXTUK9ZPaduvB>KcDNdo^4pmhJr0K31ZxeS&)IRRx-v z7<1D{YXPu6+uer@D z`2t)@ADgpmL>3r%HM!a7oGOL?J~sKt`0yN;mG#vQP2N#;_2G-?Z4}v2 z{?-4^*%vePhxpT7ZEIDp-avfqbMDGS%nV3#t1f+c)6D3{mugYXuCCr-hC)U+r<0tl zkc^jQqgozq74yvBMn^PM5jI1lY)K(pMy$HPSJIQJloEv}8`G_nf4jH;^s49jW}t;L z%S}vw(A?2KtI_h)gD+Q=JWfd1Pps6vJ4u!b2}{ZURPA&QF;-_Sd$}OexeF7svl^0( z@_GgSTd5H~f%g#~`ZfV`U6JMBK~%kHNd`8XBLn+|Gr7TDAoIt#jthl%YzPJ84K;mz zaAaoH5zPNl_o}+)Kj=?!Or$>eC!J?gIgD_*5O+GlL(^+6%r8`P%jh!eyGi9P^~yBk!6ug9N>gh+Je(;>14rcIEi z>8voWGuJ0WX!&fIp*=#*6l`NU&)5Wj1&tpWl zY9-mM<4?r}qTWR@vzU$><@uPX%?2K|PspRX&c8ULJL@2c#tZ)45R_tt>XL5QEX?e? zS=J?1(p3$N1dq`5?5`$x;{f^9^>wk;`MK1EKh4^039RKkw(;}q+YZG6JEz5{nOG~G zR`~+qc}^~=smjsT+{am`*#^7rNfr6tcGfNK3-L3jrrq0{MLx5jBdRt{b-u-7LtZWs z*uJJ;_O8hFX|snn& zaUhUc?uSHgX>D3|JY@7(XrZJV@Vy!j&%Sc`=jg1*6>G<>rvPY`+Tm;1vVw!&--EUz z*s#3%+Lvp4d!h~M3Hx~>dX?;`RXh(CZuIMOD@5juFD9ZHsmf>K_2rr^u}n&^$4@ZH z4E#AlIh;SAQm!gI%I>`y8Tf-vOPD__d&G=05wk5kV1#fJcvvgdX_zcOAOAYS;r8Js zvgbMW&?jLCoX`AX(8>Z7Er8)x-kIMD;UFIgDnVqe!@`J6<#5X)5fcCrB(m=HzxvK`cSLyZDHeNma9H!`>h?@Npg|R--f@ z(YK|Yd>^xPvxncuLn>})7^`liSXB6vpWsc~n#HJ5-?D((>N>~$l47p4gLdknu@Xq# z$oE6pN+_84hGRg%_g&|{(;$OL8sf5@Y8_m3SodTT5$}O!tmDGzwC*>8yY7O}0guH> zVKl|R=~1y5YKy}2)|YfDp`X0$;CpvcDJrD1!Q9(c#=O|^w~%E~$z<)^>wS-x(wU#I zH8dNs%AsUElLeUp?Bo z&jxe$7{8OZ^*9o5`h^z|H*BBqgt{IjDU|I1+9K1`W^&5B$!M(+sOTzOrR&sARL1 zmuIU)DZIKGJHQQprl(U$;jt4=*a`7%85!(b{Dv0i6{R8(mxmwb8m}B17mb0Xgr4Aj zMa*OB?92hh8d=GN&-1F{QXefNDCN*jqOl{fLsVm(F=+~{RXSp1`wMpR*l^i@rtbt? z_caIFzR$gtzA8Sa-?N{Ytp0y5L}i~J9!1^0fwW>r>#tGw;;qc#C=WCXB-yGpa#{P$05ZeT7&gb|`j8VuWh2GvN*a+$%Rh zJIy2QH?fSE-&i{|60E_;WS=gjj>53R5`S`FnXyVR59)<7A!8u(I8}-TVMlVnnt=_# zSWAAEB-->laFiUdW&P+G@MxweH9_3JVO#q#o8ixX3OmEZ_oMK^6V1T32gmngw1+4c ze7%IpD?mF!?fiM(k9G^=PYolnjUh!X!t~N}Vh-#2J zPl^h>v2qWb%1*jwbqbta^|q(;A2J}jT69Gl!c_gu7fzt8m5l8auylzkILy>x&8@OLj70cX!1J%K9kdYOO)O3~YQwM@W2 zW$4d0oB>+^lV`?=@IQqWx)?k)!VtuV(9rk-a24e1l4% zyvPCwju-^)5|`q{(HtmdJcBZ!XUI%Ab+p}*GYiD?R?F%?DI|Ci_$AmwsYBI}@o*Sv zN@(_}|4Qlx|0aaSy(ouMMrKXO1Gpr247pz(F$$ z&6}fa6{8m+ElXbWSw)ZXv?YgtF)4puX%c^n{skgsLHQ^WjXiB=|T~B(s7nLYyQC!LEM- zmQ_Rc=;(e8XoG)`rG);I;%Zz&Me|gP7%8V+k_jCxmkqX9$Y+GhQ|$}TLGE`0FFTQ6 zsT4~}Br^U=A8L?(h5F35lyK@IO$BI!5IF_;t; zxJ&W#5)K&cB#GT$gL^?({GoDJpGi=7;Lq?87tvf{FN1JXV>N#^f4q#vO~oZa={Hc& zWUS)fZ!8#Pl16*%PtFnxb(B?#{D!O|)7|>V2t}SGsh`q|Mh5n>nAQxJD$1^t>0AL_ zMGmPoW#)HD3Rj}|l+EPWZ)VQBK$NEkN`Z<87^gyU*x^9GP@8wb#KbI|yyT^{$-Y1D ztwWz7^;@mG7dIiFG=|=4Q{Kr|g@ymZ(!43_XHdw!w@tm*+xeO5a!)2*OknNGUY1|p zJjOsCAfzHnrp(SbkI17aR><1O)5vwGl*peDEDKX-jQ@#$#4#W29V{JO98}n`cT!RF za;a;VBLBEn!SQz4O!n5LnG|JH^Up{j4RONofD=M5-AF6zqH`ssSGd69S5;RPiv8~L zskhY{bHa;Z%jD>MV@go`R{RH(MfGEq_YZ~!QrNd_*s_vu>Yu;9MH0LloqWuf7an|z<#!(_^J(skyw1cU}+)Dco7vr~eq8mFaaN@a@2^=3-Q{;P{xk;A}r z?~EaQ*UY@5CgDfuZmUGqX+3FWRz?tWu4u}r)fhDY%}1f6 ze{#j8YMeS@2}Ny1#xy!?YD+9r4XA%fo`xDY@OMuVcSH|Iysm!lKkPCUYk%IYC-BGd zMtKeWGAKnep1m`5bALm5N&(J2Q^LK&j>8^_5sA(j&K)tolDeY3a+XgXHW3g{qwk`* zN%zutWEuTv#iIOi`V%F~Cd;&G-;U4em!(%q09|0#c5{I|hasPK#;%)zLMle8^f>0Y z<9PU|SkX_O9JkfyFUy0J$<8b4dVvt1zbGnuWmmit*8ZRA6I25-n5Q`S?>`JL&kY1N z32A3A3o(>r1mJ51I2@j%*hApXHWG5b-OP8s8&YTe|(a`MRMoTcJX|YP7OQ(^}K&pIQ#q*W^N_rpJN7 zt6kzRTh=8&{Cw)DzP|=}pMl~I+y;<{YnWCntP^we>~Ryee@sV=p@RU4tOw;`lU|z^ z8^($E%69D^=XkLXf+FKH7n|4CXtI7x-q2vNTM>q`C&Ozs1uHp1MMs5~gP+&L5JiYA z1X&uD6b};Z5gixJsR=wwIah#|gKg~NRM4w1EJx_2m(1Od*^Cj04l`$>DpcVE-}ONr z6{mNr-4K${Ei7u#m zemrE^WFAvUQZEy#top;1F*ox^KHT$o3~N7OSN7)X;|=8ID)r4(KHPVUR!%2~fj+3( zj6ZlN*Z?m1vi0{@u#!$sX3=JmMG>%QdRJ@#==DT?+i`HS@JC!g%vaS{mXw_(1tV1@ zNv9I5X;_2C*dN@0@(=BlRXeW5)cptz-jpu~_GU+>ok%1UXhyLhsruvZGPTA%@kY!Q z=O$NY+xYaP7(dEine&xR0uf&-zbH9QF;3-V)=c&lHhy}ak3Q^X@(v~HwobO~Tw0xm zo$|igz8d;;i;99{!;QU-IE|lI$QL$yuMr@c5Jm_kB>!5WqbazaxIUvqH`I3qk-kA6 z|3_(CV>zdOX6bs_ixK1-M9sF!RTZ%+d~dHO%kps}z{#uGL9?alkm9JYMpbjOGOQzT1`s3C2W> zBqf>GGD>;k#BV&Y-@|7Nk3OF=ud|TuH0eC)m-3#jJAO`Rp*Qdpdo!G^;DBb&t4e`S zrI}c(TCVb?7hki;<@gOPlxp%FVN1%Afs_dqFEs`%P2W)3PC@De8crYK9f1{5^gn-A zr9Wd}!|j#&q!;IX%%0CG$}Af3bcRQtibgOJ&4k($T->ZFzyhCYrjR?Qu_(Ey;Q=c@ z_ou4ulfc9j+FfnBt}xFqHHpR!e#j4ccz^paM}HcVi3d>q-qv9P_Fvr3*foSd@PEiA zp9XJdZRhq&9MPlW-(R(gLGw*YvB)R&Ci2KlsRo3OrH!ADkGTdy&>^t&0icR#ExYzX zYP@lzl>%JMM0$mDxtbD?W!v|M{qg9%Xq2iSHP~x07@^Xad@so2Br6=eKcv*@|8~{e zl-Lv=@y@EcL_Rj}|KvhngnZUZ`q6cYKVcs&5%x3Na_FVKzkC>!0mR6!OEyl=MjOvB zPzx>%ZV6r+bllYEvi=i2KVnVKU2)shVE>PTo;9Duv#XGJ)tBv^Kd`_n=|}x(OHK7l zZcedHy_`A}iB5D(sGq_h1;_4yN8s|!haVWn+2q59)mO#A^>V5uEQVTMUkICnO=(AF z(kUS5rEpy^_LpDsf5fhRMkaJ5^h`yjH%sPEW{^uuDj}H@o^zW+>L@kug4-wEGfw7G z;IJ*YMG%TPRHJifHBEHR;gIx3N;ew8ANrR;_YwPrrkm0KV=T6H3|3@)G+hef#DT)^ z2=j_AU#bR#6t&Ar;%|h1iO7j+WFWG>qT+W01cH(2(ZFa5dP=!o1O+7dQEKL11J`e^ zu<{w8VlaGe@%Ggc*F^5vRMt{WPp@{$U zcI{QKc#^)8(W-2e=;6jP2(p8)$%K&GV1zjn{|$e@xS=2UEh5YNM%q$ro~}qMrC|8R zC@BZyzBt+uTu&kTedsT!cSIQ4tjz}cML#NXRor*Wo33j_fBr!7ETVZx)8ow}%cH?# z`6CgeHFz2h@@{%zw7u6}6>_C@N*{>k%6cjJy1>zeW=7QzS0M-nX)al!piDIjOC3!3#O^TvHnm5$qxS)>1Y5tY zgsTMQb-E)V(+||4-K=a=YhrFYo#O}G%kw+$0Ev`&6nOZZXrA;gtr-Ni-SsZX8mP3q z$)2$510DQa46N5Q*Lrzc&Yaf_Rz()?DQ0G4*4XWwoGzTUW<`)1{{6h?ZSL!MjgH@m zACC{9=-a%Kk0hW1KkEN!6YO1f(X(b5&Ri2L7idw&d)lwf%|G@3eM2SCht(h>xr}JU ze$t6t1Y3Q=+qJpiA-k;837GYezc}3Vx_`^xWO@0^CJMg`y8*Jo{1*Szl?h= zGvcaXM(?~?kVtG(GB-ld>7u*%Mh;|@>$UeUUtj*|W_**$FCQFG=B2fj)$0*(^2`R- zc;dO|zGGn2PIkG$BvzyZ3(U449U>KP;B7=*E8vn*fkoB>{2nN_)#5$3)&fi(UN`=j zYF~w&vwMmnxU9%0USFLvb*gwU`D)+Sfc55^Fn3qAdhC54?l)($&wA=F0Fl@tiw|O3 zApy{A2`?KRv3ad+pke=Mf7x6N@Olu2Th0dq3ZBJ( zKGb`P!WFl(4E*9KDt<41B0eHLpKw1r>nyadtDXt7AUyCWa3CJ-ViHjH5L&symzuNO z5p`iBfu@0FQ!t8kXo(l8|5mF|D_<+v#k&{y52ye-|IE-(MDrr3438dRto%w^$R(WC z7Zx7UObItYLW+)CqdB)k^kXNljsPQFY{xT7nX`UHf3T;EB{F}X>+lT`j4^Pcv5fK{ zs-6=bbkQb8aZ!LIgC^@RnUcz|g^^Xr`mlnD0mb3i;2A$ca&`#`c-cHQ&j&BpTS3 zl55%t)a><$Y|w{ZQ*{v?i-?`dZpmREvKIjc z@y!o?rq}E#Pk2E!iheB${8G%A!Rl-k)!GEpD)6hv3AH&|d@?#f{OWkUXOk6?GCdg9;ivA3c^)ao{w%hc|F7nO-_&gHMgb%W~j`^~DuC z6SqbLKZ$-+f9DWe3it=2neXT}F_*ot zgbL^RxwxVsAto_@upTcT=dOwLpNu(hl6mh5yVj|NF z)FXUDaL0BmR0ooX<=+XMmjYNj|8NJ%Bm^j317PHZKT8;+BsL=04yxmpkWrV@k73q; zaBv#Qs3YjdxYB%w*ZMvJKQ1r(w`sFlpIXD+`B}Joe|3Glv!U2T;gjv9nF#CIPeFiu z-1XN8^+&q9Va2(AsL(>WMiy(_BBa^+FeZ<3eNnM^5t-P6ZBh5kgyZ@}jPY%}+WHgG zMDNv$@94iNvDcr(!d@`(*Ea6;$NJ(gw2vH@E$@x-nTFwF>~85~z#)+2pHh@vroTs1cxi z=e#bwyVDIXc%aIt&6{M98<=S}>-}s0_*-`U1)uuoyvaTf6D(#*IB+#UR6jZbw)|z@ zhFKYQ`bsBy?-}*zhN)a?Oh5FSYotDh^&bKC$~`>VX?qTa--@AJ@KVQwG&*L&Mzof^ zV(|)z@G#>FiCYL`{nb)qxw^o1WC-ccjttRJ5PWgp7C zY6jP(L#UrWXz!T!Aw!Nn8HU?kT3x{uB&9o4811qK>ygghKRcMUX(}$y!(L(lJVo#ugU&d7N#oD0~hb5s%a=c&iw2 z@9oFH8pdtnE8b)6fO!`l1IPbD=&T!=bQ|%{xIV6RC?8hYQ!*rxMHl00OCDtoA#tIU zwuFkB=nSXUkw{GW2Y#(IVx(&(GBf{x@6adok4;b|?= zOiR#HOBkK)kW>MtC@MK+v~7&a-l9=9nK_+sG~Q`k`d67J+DkVbbfC$=(h9kQ=$54Y z3hnABa7JI9e0LZo-cVGy+}M@h2d2EoS#*dcz?&T|rh{GP{w_#ES=ujZ5*8#^ZBwmd zTFHaM35#92Vc*kiRRT~lvOZ}NdmTWQ&)r;@hR820f@PnX@;-{Xh+NYJdp(OO21Ud)NCoVov@g<%3Spud^#@ z>UjLX551u7rzw^O_CIo09NRhTgsdY8GlLP`>ND!PHy=pXwXP4+cl8Q3ap*>>xVKlr z_nxUo27K?Cz?q5=t!-;rbYMFCbS0^`$id~yX3JfcQX;p~HYl7pFG3ag3ra=ujsFV& zoxT?RNqN5tf4H>+#^?_BBM2P?S#bjsu{nDH`-F~~{^wNKe|L#__9u6P_oj1C33LW(Rd-??GR$S~AcHw#lD6p{hdk={LdrbAvjSt_PaC zuDvE~raq(h&!J7dO}xHN|Bx?V!ic9-3JxEl2)}nDhz_zz0MMwT5qz-3FpZcb-iTf3 z$3Qr;pYAxsl;!!#p)NVW-8K}u^$064i3@kMB_E(|N$5WK^w^VIH?ray&V{o~n{A!_ z0$lg+(0y?*D>|+ExSS2c`P(G48;c>88VhDWu_TTimfkM}8G@3QObvoZlPy&zgXMha z20I67IPn1-XDGL6wlAZIDdGzan~DtiL-(b|9RB08T`&ny4+9UrIdGFS}nO;QWduymKaA=w)Pg2MdFfpx{u+2~B%!gAP*C*9MSxplh5IcESk8zh%{EBz^D`5vB`%geL z5|p`XDtu9C-^+G&EoDv<4nl*Gg@8y8ZQlR-DCcX`Qy4zpkZyzGiSx3dLTHcla8UG6 zD6p(B&vz5)g*y+u&@nC!P9B||r*prv1+clehaXn!;tGST`0 z9>BCu-4ZVl>!rru>sua`bNq`AhQ&mnOJ2m!9irtp5Y)w;XymfnRk-=N12nvbG%(=1 z8K5leu&33pq6lRqwSU}N{znA}2nO>$1?B%F&V%lbhY%3|!wFDE`LhN;kn3)nL zhps+yS!jf&7@`P1etjc_MD0Kjwo}++pzE4QaM>9jD+&WRkK2K4C4we_Q8{?E07PBI zU(5P7%r%f#mJ{ZY@Bir<%<5x1C%fD#(0lxRQUx*F1{D(L{ecB}V+c`sc~38Z zMSdH!OPnYAfp3M>ds;v!VL25P@q5F<8$j$Fzu15CB?3ftGI8_pGk=FTPo>a--u`zS zJ;F*?=Fr3RQw_h`@McH!_rC25EoX8(@Sm&QI==lHv& znRGu2QIloz)s22&z!#xFWaoItxc{BW`pOgXGrr3kQ;gSL@Au3Tq6qReZx`z2KrEsB z$l04^wtb<9hZw5jSIrW)z<&a``wV?>cj&&whB{>VeCdW7TEG_iX_X;{pX!EiL%;dF@LEg+p%%o$-hcVz1$TyMKc5G^`yz^PPM5IU%@iUooyswDW7new>F?87=+zh3&y zy`g?|oARsg0Jm5VlT5TdREH7KkH+2pc4W+K!`x_qUIp+lT00rfxPNlkcIJ{%?;d~D zY(WyNaqZZ2R_=MoV5pjHyY)x*o*o^$bLr=ARvr4`KA`9Gqhk3-%47?tOkE#B-WgPQ z4!*VMN{ZMeO?tp;KFoDav{aD>d<9_zfz~YcpLqNE0rnUc2hdQnYgAtY&)0psDw(Z0 zw}E;_+=t;Y51Q=~%tdTT%3aqDALSk=8*=CU!TLMH?V%Hxyo8Z44}$HS$6C_e(5+op z?geh1O{^DxD0k(DO7(D3t6QgSp}>-J3&%pzv!OsdZveeaogfToY=?A79Mi4Cimku| zr6%7HZSg2~lL|2}KQifLzAyUQa^kVT;K9?kjcIAuj=U-vVEj9d55T0^(BwnTo>Tq6 za!>B$qSi9{W+1HSiG{ZaR=VnWYpbN%TGuR)FdSZii-wDR` zh|(!rU7y}gARjQ)1aJ^IZ9X2|UZI*GD9&e6t$SEZ1O-y1qXCtcoWi{+zoB1$5$eNt z#)L8(ng~!^zRtxPw-<+RvmH_%k@-FthWr4_&L&25+x1o7=vjyKv4buggub2fe>Irj zbwVfoz**wF$so5Xq&yXVp?75?pI(Ybh$cGFt7z)o41?!AA_tTWp1AoCl+QkT=`X5$ zEovy4a&0z!lNRn<>u?3Iql)bfd8OHg7<_RRezAM0lg0R&{@iY85*qyk{5a0f2`rYg++d4VUNhrfv<*ReU^}%zok0U}39rvaGKKhkE!=;-VI`DXTo7cwf z@+RNolu7O3dB|dSD4^d>G1kzhpI^d-~W6|Ne z@!x3(W;#PJoX{3&G3cT@{Dxel&l~m3dGo;oMs`jTwDcTfi+PvWG!8O`OT(r+7U<`{ zbI0g;wq;x1^AP^Ei14ybHU!|cV44+c(J@pq6aIX z;Osp%d=~&x;!iZ`xY{t~v{Y)SedaA1`50krSelkT&gf>5b{`3m&KpNvVvK=ypF<2& zKJfv5KNP_S`#*d?1S8K(yI=kvM8mBQd*}6D%LOOqaQkV|&KfLx0tL?Aut!Bjx^>_q zu%w&21gg_D*Zwk-6|ME4fcbmHf6TMMB==~BLQ!8*94&nUA6k)vCaf!%69)uEeLfw? z5Nt6_?r7gPydZK1T$;e2%~>PrTS#M3RyZK}5(e?<2(>fI7~~FO>OZ_OiL5aES@<+` z-isF5$SWTbC1Z*Vc`cYxt|^1iBF0;4Rs)#^h=5Xa1pe47IlT1UXmGS#LM`m{u(+Bh z8nrCL7+FJJh_S;=mVA6?T@q+R>~)-2UeujAesVV8k{t$w{D;OwFRO|Wj|ntle5uqw zzWI3-2ptDp8~N)Wa-(8mx|7r-KFtPlhgPT!48Lb}g%%k#6J`vb7tMZTfje)7(*`^#@e^ogaXw^mzq4kA5Xh=)8_zWbS9x~O(v`(-9+NUdx&Zb#D{{5{6D_*V{NdmQo%xq ziN#QvuQby~FNaFaL_bC^7QeyXIvoc?@|Y2M!x%)KM12AOpQ+~$jNXF_&b1B<|0nS` zl*;#pHl<2{YQ$q|;nSJu3! zn|iIi`^Y+%>#7TMicG|Xo?gBPnB)Mtg`EvK#sAnM^zVsaT=zqP2?4<;5P0mKH?x4I zc;&5*yBBH-00|#?ylspV6w|UxCp@aaDDPqvjpoTv02X`s8WE}gFpOyr`@|rVAVyv@;&Aq$7{w!h!2vmJ zejYBYujg}PV%s{3^|kLlae2HU>o=p3v2a=$_Q7l=)Pf&C7yNRGQSZ>63=mWU8m)WL zMSM~BM|N)9icBoZIR)D(dGNi=7*VN$E9lazs-&krGAIW~-l7C{$#2h083QcBoc~Cy zQ;wv*{b*9T-~N2H9Q0%)YybE*&AV6YSULo(nrYP~m?unt6MYzI9>L4z6Ww{UJ~%P` zmUO%Kb~zpRW!rst+YpiOPakvZ^1{i{Nh;>jXR(w}WId=|YOP0jdC|;E@?S2*-tM<` zgtnxev<)zztKIG}f4v8T&!0mEc!87?vyoLMOpQhf9&xdBy95H15+r3uK z#Sw_Fb-JzRHFu7-9EfZ7tYbf`lGdgycFx7mmATUH<^E_st)jYB$R|l8y~81V;oa4a zil+&@^iWb47Jos$a^4b`|ti{e57#NU3 zz#JElV9Bo-XhZiG+-zHzJ3k=6p(9NSIO#DOIW`>_@J_qbhcem~8yG{%m~X;;QRcCg;cEJ=d|K2L5i(L&XoLOmZH5hob7Up%tt+)5P%_I8fAI{ zPE^qR6!bKelkfb@A6fe%+_13)2fh3I8~+Fs{%2TZ6o12U>1CGyASa@rT$|`B1lP#J zv7$7hP_IxuHmbyH->?i?CAHYxZDwe1qAWN?&Vr4h5NjwhbMRY7kwNF#cKg*1RtG*y z-Y4x!#LA9rcBILhpo^ zZeHj>C&V1Og#YY05{FQiv76_g`Og;KZ^+x^wLd|{){!6;c+o#}-r8sc#g;(&|A&Io zp}+{L81|8lG+LTAM&>I|f?Fto*0*nI5n^?JiuWfnL$!BhuUys0 z0q5<#uHVmNH*23b#_qm->w9EdHN$YF@Y?U}cH}7oqkYH4k-02BR7c56FX&+BURKxx zeAwOhqsXIjM1J;6oxB+VRjUIFvl-Y#ey#mKkM=P6@~ZSAf%tX%m}_{Oj=r? zeF*>&Q7?~v?3g$ddJ}>C^6vPEd4viF1(jF(q!XeD2+CnR&yEj93w zRPHqfGqff)$dJiy8`3`H=0tnied%_f$GTt1F9gd+&g9qvA|F~N6J_Entf&g;3N-T?Q`AYh?M1dR1qL3O3pXCuEr z7EF^8-YeeRD+Ub9_Ke5|n9DCfN6`=gw?T>YtN^Aq)5;XHO~(rBuu{N) zF^n-E-h@QbpL6!UO_;6uLgDUH=*5e2hG8y{1xUd}k*5>Bh`Bst%*x%otX+E!Lh00@v*W-V?1xS+2Jyk<^C6D?izB5d(!miTS&d%s{ z^(BI8*e8iyC0I0H+Q7qE8)?@c$JsH#?qQyI&)47A@%k8&r~*{U-xE^~(T+%1lA)?K z2xz7>!L3b6NZT!L*)G1DNw#Tuv@tp@{{Cze;3(gm<=@P9J^KmzU@70s^JG)|F#G8d z)S*~Z`e;*oGn;iYE6`1^PxNe4do?@pY^|7+$Hg8Y3EIoh zhnrc2N1L;|*-n4?=A}m);l0`py1n8SEBR(^h>h?;G51dK-M1lio7&r1-#J9R-2=;KPd|_r1^TH0nxF^C+kvNN3Q8qq7s9R%^^N)(z8Mp`N?1(wdndhJ|+iP z*OY+0D2c42V87kI_iV{J7`by99MCe1EAWGKBy8f4x^RU0xz6H0W*(ENd;~e|Du@&D zG(YCPJxoWwwC}eYUALt4K@FJjDu%~+o3bzcJ8F1ghX25&n@EXjDAw52>j`ROl%KV* z`MCn_Uf9I4a(owpTPt+bqdIt_OW$Ce9TVw=r@<~j)t7e|{?^-ytU2SrXK*vA*s~I0g{zy{S83& z?h_&3Lh3h)ty55QiHoGxIpw3is-14ma3Qa4r~5txJ8Y-AaUpvEvRF6kk6O+dCBr6rwz(zb3k6m6w8d9Dy{+@l2+_ovp9aW6NrbHL zN+dodQQr)ZtSLg$UEZ4a5lDI3h0Jw%_56B(JR$YU_X4EsdL*#toJvpixf;74a0-&O z{4GF^8Y1L-0J%fb{J(a2+kI^}*qCG+jon_))(((S31<=@EfQn~AfJ+KYv~%_lCFbm6v$F8z4ue5#$d6a=$}MRfi@s>dwp>Y25i!z!{J@{9CL?>hF&N zWJ1#XvjBNOlHx@ug4Dk*2FOv#Hm>M#PYbek@A3LE10csGes1j{m%a$JZttOq5Lfp1 z0VE@p`g~8qV+sEksY^Kj3=p1Cq>yuay*gYEkW*66ZS8eW^sw<1AQwseT;J=p@De~y zO4M)n;k>`sT?=400s*8TL5{NxK5nV60AxbK`ED=u^DgAS05Tx;f^~hMd8t$qAafFA zD?pA)Jn!xEj!i{?+$-tuO#pe^l1A7*_p53Y^5+PVEb1Tn+`KyP%Qq)hN-g+Jz`0oJ zao-2XMv23p1LTlI{pD9c%qG#=1dtt)q}^9|qpuNw?3HjbS9sfN4j{u)&2RGIydNO8 zRL{o%qR7z&Kn5h7M|}1C3qX!by>jJNx$_mwo~>((=VrMKoRKoqH--(ol}6BLF#B6lwj{mG~t%5%S2D-f{3pKI-RP1*N39!)vbc;&cIIy~N=NKn_cg-2ll; zIxGU@NlA(~`)a=XD$#F{wz$fjzf;KH`AU8FDz98C2cSPop5!$H?%8Cpjj4jJmj^oJ zdb$CpLy}^Az&&M5A=d$9K#-xN4<-QXjk4tj>DL`(OIQ%j|6shKa1xVK6 z$Jy7!epZ}?oHj&N^-`Y2#&pL1>;UfnuIOq`C2=&3tI}iX%s^`!*+E?~Ar7@|EjOp< z5indR?9_}BpiS9Y#jchUeh`-Br=ADdn%~BoZ@wAJ&*pM!MV~b+Td$}y6D-8dgP1rV{E+Rjp*J zc)5>SYNb$+Zf=pFS%wAG=M2j*O9?fn7i_hVn^h}-olvI@(4v;J$pI7h3AfqW8ls!U za@E#Vdrr4Cx;2|})06D%ZExqK%b*v-rUY0C!i`?iE3<|URhP_4Q7af0ePN-*J`mJo zK>0#JD_bD01r4X=jnb^ZzAGu=Ru!~H*h+S#dfVtLNu}&%YpPAs7S$sMX)v>*tcXnm z8q|vA0`f5fx-lz6#%XoNC}3OW%#sD_lYj|z77WHpc6LJmN-R&!flSbz<*J35F}+g3 zddM$)hRPAUy_ccP>b81Nub|BAwZszFaWS8>E!L)bDQAMQkfN4xv(CVvL%mp@)4&QO zM0MV<=Ttq1>>Xt4>Fn-oO~Buveb8(!Kf~LAJpdy`_NQx#a|XAvWLG;{g!{^#1NfX- z$dgxXOtxIrvdyByZ_X}wBp^Li?i?Nwti=)-r27o^fg%-5%a$NMZ7@Vf_Av1z9f(}> zdR?wL#K$$$bGcfuumcQ@jAqn{Yj>%;)yeTa3C>Eu>*2wS>{axfYU^N|;5LYzRVsQ8 zJ6p1?ts~{dgnD^rL$MizdO!LAWQ9MWuaq3LY8mQsOJO$xS5S7VAqsKdT5d^bb}uWS z0kHcDI54wnC(%csvtlnCj;Nl5KOK$`O=5wR<1DbZmh(VZ;16ZZ&dm`bhE|aAtU2gV z2b{+|9y|~^C+$5m1I-WJUUOwaM}fA6dO?cZ0Xa0FBX2p!s+}=Nb>wfusBi?WYMV$(Docl_ zoT*hTosOxC#5n0t4_cmv(HY+BGbGx{vp+3d%W?2YzX_-bECj=#X<|DCjsn_o5h#dN z1aHWwolvW#!0I?ys)7T3m4K?-Mj_k?9NNJX=!G~(l*vi+vExiDUDzP*1CAGu@dZnb}GKPxc zL3aYZVl(DlqY^=(6}ququZ?h@ z{YY%Iu#DM~#XxLGqaa@a5{R+!+W(f71?A|WFa3eL_!jI2UW00^P!#YvMotfZ&%%L_ z*AOd0R5BCr{%U{^Gn^?h@Dp$vBxYa+8TO4uZUrNyzzP_cLFiLxYlI3YheN*CBw*%U zM}XvYKP){Q)V84avRS}U(D!n5LOrNe3=DE%)U?f+89&b0=+yRrk($0Nnb>iyIjyWy z9zjD~A!Ad!JRQsdgFhv~QNZho(ILsg;W?r17@XXx4rVgyuGY>3MHw6$M##w6?!nB6 zy8GJDSL}^b`D~%e>@`5!)|^g82C-o&ETDV%)tQ+fEuli^PLaO?UbKe2XbXFh3aTZj z0xxV^Iy0s2>hxE@U$ln3@Kt3D4R80?L!hmJ(6$gu8rs&Xj%`zSZc}&lc;S0y=WKOX zuNO?}BW1)lFa`~W)YPUAW&DNkU2t{yhDgt<>=a)P!z5%--I*TaZ^5F%#oH4o z+qOvY_V{Jn6Cv21V5#;5i?ktfkVr{qS}QuW{tM76OJenc6sy z;9AGfe~jt}^@1h8m>LA(amcn|Ox>d!pt^wW3L~vuF$)kJ<_(jC@el^vbACh`V{r=& zs0k*RdvW6}y(vDjFq#iN|keAo)3VBg2l{HUPEV^FmE2+Ep;b5Xpw=9AiZh&S)iTc`VRRtZ7+P+y z4W;$NwUS0+FtmgN;Fo*|(*|e}r+PNY9_97cuorDXW-vVuQ7#x6gaYktQLiI=0*`3O za|HjaS_KnA!daB&bBa*W6?xHMmuHLsA)!qRi|}VjXSptQ`{+cF zZ?9CYC9`t!-UaTYeJ8LGlP_&6;!Mh^G!T=I_;k(}h*HsKtKccYqtdK+fuvF_O3pu>j%kb)W!amsN>0@M@S1rx1_v*~JO7Snyk zi~+&~qqs3Zi1mjn$sOCPIXf8TK${kBmHuHl*g!}xaEu5OH^GR^Ce899%e_URMPtlW zD`7HAo*KL-_tb&t*us{jcLYUmV&=e)6FB2=W)ciPdO9IY0s?p-$;WaI1`iY0ISNKO z;ilR!F+>p{lGkmzzD7n=0J$sPB1)MghlRBi5iT=VG);R>oze2V3MuWT4o&UJ4DCqv zbV+aBMLwFiZ3}tp0n?yK0`Wx@k#q^V(Lpae1yl2twF@3dUWX9dT=eV9oxk~Bm8M}b zqCxj5Sb;BDJ}2lEYXymk08I#(VbcaC9_e_rEqFSf`bmtMW}u7AEl$G}B0&Lk1-Uzw z>UPofo2te^^4f(#m#&ubS}C`vPA}TXFNS?Z7-Sh){zw+{2>afZZQ9HoA#Xikp_!c( zXV%PggvK%~*DeT3V-B&ESQp^-P&7-XTC7?|&TUU&!J8o*G>x1dg1~4*)xl7rYMH^s zVd0tek=CAeiEmj5(SW6OcnQJ{ShN!eIq`6mj@#MIDq0Dsy`ZC`pms|k74$qZi0Feu z{A-!$oY`9y?M~p(`wm2{prIHuGkoJhZ%+?sobH=oJ09@3kppAF9|4g%i`9Z{;6@Cs zD4B}rr-E=~8^ox;TB(>-Tvuh|P-tPcp3=zLym}2a^C9ni7kooR=cqA~@%H)hv;( zzsY+>^QJmmFsEVanTM%|C4+Jl#C9@)?c~E|11fGlsa8;VbjzV>9x!xzPI{y8G8#@4 zSI~<(#$PHLEzW0Vtr^WIK)WW?tEbeFg`8f-$<8GB0o-JDr6V11dypRf!GerqE^BDJlRgC;z?|3 zJVk9`iUQGw=P*FbVY`%dqrImKEz&lM7|fFGDOl0GM!8OQb$4{8=;q{PwNx+;=$_n{ zN=*TRHe%Ta^hMh2jwcZikSIq`3x-9SM4j*Ia8a~;-a+w{<$InzCD@)NUm-O!I)!J( zr#*`_VS2xo#e(UgHmh&bEH^0fzXI5H@D~#!Os(GMZHr@Ut2AW=C$#j+8K?9z?~S-Qq1)r%CKJ0 z?VuMb2vN4kpuuF~_0cOff_M`5BxELV`%BrbSn95Bap7=eZ^khcY?3(*w>s(-=wb$t zLdB6ZhdF~}$y#@@XxITS(5Y2Gzbfg$H{$7p>a>LiNs7*a1kw&UkY%ADwhVz70)!fp z&j&+wh9 zEOug|(W`HG!L z!R1I_v<{-Ww7}7Z7aqkkfk6W_rA=?ZlExIW6iF9gceS=VgQM(&{9N!B@VMDlwT-)3 zPhJL(c;Utt)rpI6FFS8z?CI|KisnVUvuF=JqC*uac1RT2Sr@$k{Zou~SU@Gmm-Lkr zKnEE^Xf#DDA3^gDS2(@iEW~`qwz5Ng- z2Q3Jpb^Hr;HkBT|hA#S!Way%=;LcpiZ7yZsQ0Vd6(EExw6gn($)A9|h;&$Sqw!pn7 z8~G!c4h$Uv#Ck8W{NlUvA<)cBf<8D0CRxs zDkA4RvVU^DGqJz91D1Wj9pJsOLdw}oi5*o83PtBjLo^x{1%~T^b+`w zE;n*!Zbj@tY=VHU$cg;IyrOU5xe*ga!4Agh=IZD!rwh<4B~Rlgxh1(}U_x8ip`&>x z>hhDKKViR9skScnZ-lqDc67EUl!e3@_^IL$0OXfj$X}A5wl<}R8SVbou2e@?S5I$8 zcQUm)arWnb$xq&}aM>nVUfkT8>`b<9VSp{@5-k8PQ~&Sk>I&)qt!dneKTTA;B3Ld$U-qJ1%^?5dQq8$pwHIxEeb|! ziaDcT%5qk3QEXGuN{b3a)ewm)=ClnV5AdXDYggm`3`Di(pdQ?tIImT7z|Je0Wtlkx zBDlPgH*-~-D3W=!f|Ex}X@bF9*)YXQY-ny-yBf&kb*-QnB?VvdcM4t%VpeUXg8K*z zG9b4AQm#-%%{Z^ghbajOs0zvx4OqxL#0D)2a@wMh{k8a8Cz6%%h5&1>Makn@y)j+2 z0catRs1%q2QMQ;B#ey&mt1y6dBCg9{3lSH{lu@ZRQxhRPKW7#ZckOCN7*NwpwNe72 zIw_PlL2ZQQjSy=f1nZtLVL~#G(&5DgBoMdyu;H-HwQ2L9PUNADTrwe6p-LysP<9)a zy|U)OV<^))(;84VKuMY)QUy7H?pDG`Ucq%XBJdx(CF^r^w`zPHYhkY4pyB8bB0PmKTr!%**7dTje7kQv!IGL}gKS%4`c z*TRD`wPSE}6ltwpJ-8bLm;_3b%Fy`4zRC2}J2J|S@zLQC0B#!r-te*mN(cMe`XLQ0K8HIr*sBOYZ?*|TE=VMuWh{u|1q$H!2Tq4BZIBs{i&ppzM=?4I=0 zNQ*K!nVte>LAuFtAb>iBBIBeMC^$Akt3iD$QnLUGKJT6y5x5y1861V$rm(b#on-!G z?P|Khs^B6q1|A5SselP5751iT8wHC4aZ%RdZ?47dkdyi>>6~_Dku2GA%%WbL)+-X~ z6ec5)K&}9uLKy;M+zB&KnDc<0EARs>P3mMlw*LMk6-qa@aa z;6Ge&0GE-|VKR;O4n<*B3|$hO9WiQN3#Qbt0NEI;6@VP{LRwd!X4{p%EMqJK zh)HB1>ku2Xnb)xB^Je#l0${cQQw3Bebgp8#PZ=jOQLS)&9}&DS%axtve`NR5qNIMM zqyhiR?#z(WD&T;rtC-W!Cps!ZnaF$c0-uPo<}{0Pk)+jD3BMgz)ZSQ3YHx752J@NW|s6Q-ssj$A7d4Pv#YV^4pGGH4Sl5D z*+D;EKDhmP(}(iR5m+q|eCDea5*h?)5SJ5i5JYWpJU;Rf0}R7d20bs;JV}6-3-GuS;*h*f1OFj;D4}2RzU92*9>Z}K*k?s)lafB% z2QZ;9+d#YMlWDS+@j0|))y|d7`KD%Nv!~g}meIVb*=|L8!3wE2kdufS`Orem585km zU_mu#Ib2m1N0`WwMa$uulU6dgv1(4c2*X%b!OIjKRpYKnOj%KF*Eo70FMWZP%U)C( z6$87HD;sO;YDqh&83oKax)g{HajPCi0k|iTDnT^}HLyDIur-;hM2;$hVPgvGH!y5Z z>!`L$6?JDSm}nC_Bee;PG+fSw@WZ2<*{V^3WDl9=)xOcDR$(9EaT!}a?5R^`TELJI&YHU%i-{0)%U$k<1%b-Z3 ziTv9v5)o0G95qO)VlQJf#oD9a2^E{908-?iqDn(+!88w4ad5t+nl$n-Hzv|oQF5mp z_@Dr!V30Miv)|^{P(;Q1af`Z_$o1gAjQoBQFnDF4<_@pWpquC++$MC45Q%8zCRzas z;Sq?IqixaL9Hc(E8Hg%z)m~I1b{^Hp19hWhH{sjs8yT!|zo4s26+8(_M{@OF6?7mj~Inq)q4e0-tMg&Vr!p zVuBY8*;Ei0)dCg_jRnK4YKH~}JYCQuS0lmSz?_@C8N>&NES@iN=@xL_?d%D~jKxl~ zqNi=WXn`G;$Ym;nm09Akcop;d^qgrP;C1YwkEj!sT>7WNl)Q;fO&T-$g3W|$Y+*1m z5%L0ucX}a1;4Wv)%AyxOWdny^pg5s+fX-bR^t8evz93@)X-1l2!V9npct9WbdE(}2 zq`KI|^2biD4(Gl_bjJLJFnQMIHSl!BB(0;V+0C{K(l-f)l4OZ%Y{nMRf|6HbewLMJ zahke0WEGg@*8yii>F-w- z#rOC#gg4OA?DxFM$yg)>g!iAz>q6cNUwe8Ll4YcrO6Nc~O$*K5S_2X(jTS+Us0&)X z=Bn_tMD1%9i0x({fR1;qg5`Qxtq3NK>6RfD5tzjnb4Am7!7R<8s3if*!S!e;FDwh58anyosjMrQmIbnIkhOssmKnr!WKakr-ixx^c zDIu&FdS2ettx_YH%mTzMd|}_DJNBcrz;Sqt#aYJ$cG6woQot4Ch7FSPB?5iAr{@FA*mk*b10%Mx)p7L zPPIuP7f#R+mZ}S*DsXMY&wF+kSP*oPFZYm3dZQG{6l7wy6+<*s8r$VkglUUH{NuE4 z&+9s-s7fSK<&IRy)|Nan3@YUQSgbgkVoQiR%RNJlfC|17Z7MG$#{D`ca+6c-05^7MX_`1Lh2_t7?)uvJj~wfzY)zclje?We(+u+BGK3!m@py(1XX?SV!P0 zoU?W>&E+IThB8KOl55T9|l3&GaT3GCYc%PndcNt9^7V7AwR{0nj;Dp+Hk} z(p!ub5F_GCrTK-0sTvH^=d^=-?TTFJ3}##w=eoQ&jNQ0o*e}k6>9TB7v&iVKP^K^Y?l2^vpw|(u`oFrcj<*~|s(ME7I0gqI}_DNxiCWObh6=G`pp75n; ztldixhp*>A5Q1>1AyQSML+h8i3Ko^SNkAc5&vnbQm9nQFm1 z&D~B{^$W;TVNofX71EVyjYZv_GxHdL&#=1X`3|4cxSNgflY1~=RUrIEY#qNHSW)`0 zqP{GCi5G@!&kDThyeC9>D`ffNx6Z?H&rss2M&pz5)80txn}qR=g#qjIQrmlGEGUUM zH^mm7!RuzjwvaeI-pMcExZ^}J!b@jE?5-%mGZZQ5iK z@hy+R-wJ-yyj4`?2vj1aLnKA-GplsAM}`EU)uLxzLVlhfG+^5{h-$rt&yIj&`B^;= z#^0K3_cu~D>&6q%6bJOhc^CvXlT#4RClFy;3XUb8_v}0lCejf^1f9+4Rv*1{#f3#> zj+}Y7J|C1p64EO*mv@pYE>>I$CAbz|N~j3OgV1fYq!v@bTP`K1uhCHkyA*UIG4x%; zZzsDZ6Rluv{OXbR?BweMYMm=#pACOJaMn zN6CvBkmB(qwu8J3(J4={k=d4%7#V^gVp?~74cWScS2X#(v%|5V!I}~~_%p@!deL6b z%PBa!peu}YM<4E<^0>kl8nKXUP*Seco7JHy93hWF$4YI%C{~LM7p%%Ma6keI*|yfM zR7%t}_CsN3xDdsAQ_k3->DeHR6ZlfClsQ+1_>RUFdTa`0U=D%jusq`{b#va}JWG;L z0WUEe$)X?-ed7WOI0%|-l&j^Zw%pCp(8?tI<3S|N>!THn?3uz5r^LyTNH@vuIkrSq zQP&@zcjbmi@kuk|7(xR8(G;iVObE=XWrb}h#}5G7O2M2Jh`P?$Z6*AcQr2r2(o51j zlGQZYdhBw}H66lv5DPldRn&NwGeItuyV5?@*l8ptN`Hc_8<7B)9}SH(o? z=@}udY$;&Zq_s*)3b~#oCo(D&VoRA*J|eato-rfWim1Xs>F85DNWnL>f)&u{78|W7 zw8D10g&)QvkNM)bEl%b{7YSOzR`;lim)w!bOgKx2a-}1Vt+*Z?uV>anLm|3|Mk65- zt+1%XiB{;ZfW$x!FXnQC8ypB(Xd}cq0kdh5BB_I1pWbwfED1{o^$FP`PZEyiclzA9 zkN160GNvymh2xgHjmd%kglT~AT+38fLiFp8Eq(I2qI`NVJ}RU)o zgfD1h7-o?^i?G?6so)57Vo;dgpRN`TFy<_U+#p{r=x*gA4}%upn5-4Z(bg6|hjcp_ zFNpl4TIkkeFnW2ugi8vjEWU#|xOgiqO_z@SXD2DoQeB1((FK`W(XKylG7bbG6}rhc z?~AH)(2S;}5232oRLbQIQw98Q93zD81^8wm&wWp8hmzM8Ed(t+h<8^)PA7=pO@@0q zwoSu-AQ_$^tCno*bhdblM*!H0ypjfNtlSyYuq#aQgrs+P8w8ih3P=s?oK%~iGjeml zs7@TAp#IYuE<9T-0%ASCjgie?q@i&VAvN|A96B8hJbs?A1 zebJk7{X!TCrYX9#MoGsmlVts_h%1S{ojLo1gNjfcSV2m#0s@V4wK6LN8e~N82WIg^ zmYzGnf{tk&IN}kAHUl1p|4qI;#2(NWTedo5R4lun%pO~aO8PUEsvbM$P9P^iLoS^e z6m^}&Y#1a~3{9Ce4&q?5NFzz|B~xixHk&0Pzzi09t>!-Ss1lsWLBl!NEu65WJ9b## zbt~liP%$W}800ce@v!gmk2PLX(otX<1S}F3!I^=Roi8a()e;HI0YF}8WCAM~4RvqL zbRHVSlbBmqc}`Pg%n-%{Xj_x4@6j!;&JiQ-0$F+a{1p4z0nS0mbW4ZG)Lg_C$8U=1 zw@lDGsxgoru!>|*%#a0;_RKptS(GGVQkY#u3hs+AwZCZ6S+z8whHv^g8Fxt;CD#4*`h?;YU2@b3b#7|^=y`sVA&jb)kI)~j4O5J zgHVWNgA8f)<%5ujV?-QI1A0f0O}Qk*!f}MqQ$}W-Vff5uaS+dD$uV1L-k?nBwwpr} zGskT5H&ZRpfCj4HoM*1l<93**#G%aTk$kviqgB)Zn#81dNnldGkcDh^CI=)m=w0Y6 z#1J048^6&da3o;qD=9kgI1+ajiW`6Db^U-j9PFE4DsgmN|2NDoC?O)qFyra`U3h6CN)}dIuBm7PeGfID!>V{jiV`z zqFIk%10?y^iFoNR9`llaJ#nu1;Kal9SF`W706`Vh&R{wv%>|4SE)bCGZ`gLiCg&C) za=lJ#hq6g&!+*L`*(+)PEATj%C0MIRVk)Ha!xKs;#w>o*f( zefxv4*|d(I)o=n&g+c_$=XZ~56)>28-c@ays4^J^~M?%jMYDP^?G_|cx~+9RMNs5+nZVgmBqbP z6PS5(i0nADShG0q-zs^45Ok`p;KXNmiCRo1&KAP(1%r&}N=xe(H8fy&!I))# zo4@kcfjWcVi&w5dQ^dgz?F9uKuCBcM4npG$+_LKoOulp*KZPf?Vbbu7`DD8z zV=IZx#4dcwv-1Z1LcPs|H*%3FlHMP%C`eXXIZ1hSum#uDZLJc$N*HKZL!?>^c=;j7 z03|KEJq2$`@^q!aJWJ0(Xir57-I{b-SLvMQo+KuXds5DEN<`;Dle0zKrM2I;7XUw_ z)0ZtT_7Q~5_?=pIcVpInd811JEFMkM40 zxVKBD5v071+LgE(HY3zPR!y#U=9aw;GDt8Hmjv?G$`p4PqRCK{UqXbJ1#lAjPP zHkbp?M!2TNk%cn3XHqQc-a3Cv$~jheo3kWBj${dBJ?kRTo|l@k-}5qn>fYelFOVQ8 zHF{q>(Z+mOrAfYhQ_>ZtKSiHR)|`ZkAjB&#q?;gy=-r&ldlQ6owdvWbAkJO|@xs0e z;sttF!?Zz?8Z{^nk3CfM8NE`$Y#a=dCNGTaPUDgyu0+u7@chbgyycgz=GH>M-EJ?g z>3Yr-l1r^X3tk7XlzR!71o)@RYsftU&dmklg#^;|1M<}cFM#_6eu*y+a9f5TvPVCj z*lg^obqDfGagzWZg`;=b(w!XY0evy*=r=nZi{m@BW0WPNMtUQ1Su-j%*2tRn`8r-M zo**F-{1V@}Q2Sj9+>MG?6mawReMi7CZV6rJ1*doQ!1A2aCv6pb`gj@7mU}N{$J4lU zJeEg=pc~rv%U@7%?y+}1r6BYP`Icz|*BE^>6tPcGJ(hQqTe?y)~#`Bt#Fy zBAj2W-yFDh#J{T*n*IsA-<@4_a9TIKi;@R5nbS7-<%2T0V##4IJ&d2-GR2D%*f%V^ z*B_l$av~z9BHpe}E|Iq}Z)%e5g$m{t$S1ey-o$c2%Q<@hAvp z%4toYcTzP;QD%!$+r{ZYDkkT=MD4~Lz`g|rmOggW5Dgz5Ti9a_Mvulvkb}+qwlj4> zht$6<=h%o&&Tv6wI*qs1ns|r?4G>;8+WgxP>^xjitS)WSy{mXC%E%e$O~{2D)aRJw zKprKD+*!W70=dkC)!*mceOb$GATDN-jc=aQ<7BfmeqMw?@n|3gdFpuK+$wU$4z2Mq zvQHXDy$92Tp|Q_9hCV-M(azpe@O)n+;9t0lnFj~g!3rfkpXiC4@CMgJb{3Ly^|+hh z>}>+i^)`XCC(7%7qWpjG@$aP_0Oy~{l`OyMxu?%LuY#HLuN?v|nOd<;+PEKwew&Gh zTL1wYHF9_Y8NY~Fv9T?!v*~vsMZ7Hecek!(PQY^yx#SEyui$i3@csn)bIFYJ+Ma7_ zoYxbS8$aD-GP?rve^sW~NsfB_6j($5Eh(HB(zqJ_#^0~4+~(*RVf^pg$o)wK3x3~r zrL%NO==~CB0c*V{^)yq4XCkTRj1O^ny)%{)<{T}{MUO(yul=USGd8#NUbk{~rux5a zrs|6TmNYGNYkAIh*6|J#dTHIVO_H1$* z@sJe?%bV-Qh?ht*9hUZ|Uq!}A8lIqQ%7yH5qr*~@XOo15qigF05e%>OL0&K z@=n!jS}yf(H?D0P2<+wx9)_hX)pWP4{*HDKfpm}^TRu1zinUZ zOg?W^a2Gni$Mx)Fe%UAU8oo!1aIVgwMr%q@PW=3yK0|96WjvDSIvu<*$1}erTX*?2 z+qfgnfKv1_8Zt<*X>Vxb(-T3$mz|ued4dQDHv-{Z-^7w@$q59LcT)tRd!6Wn*HHyN z&{;H_Hpk3(F)U-V-qWA%I#l_4I(;A?mtj+22gPdKe|^d~8z$4kVr|pt=lU&PssJ#+ zh{^RZZHArv%MfTFmsxm9R2KO3X6%lS5~k};RS0k%VB#J!DStjEh2@HIkhFgI@-0pG zs+t|ekpIeMd5tN!69BjL;wlV4@SauZvAZ)vfn3uBf|EEPw=xPhy~Ryy$qgC-cM|Q; zN_qS`oG|)AKQ{|i!qf~2S0oqYSzz{@e#20Qp7A0pr?xR|6byTjnj1aSZQF7$f$kGOEQGI>OlC^>#t~j3FuXGvSF!hQX{lOvaV1fz6;$^Uu2w=T z2_15z(ZIPNUeq9_2B^~AJxiEmoh^ay^ek|~=%*aO_VXFbQm+RRG?xvU4S-c2l$$(! z{|C$Yh>c-;?g1w07hlsuAu_4*;CWiokLAhJ&6~bXDs%uVW}rLxMeFVDp5<5fBi>#O?mZl zN2IT5#e`$}7EDOfipwBGkIE!p({@p z_WQoac#Xa|QmL2~55Y26p65zAS3~{0E&O*qkQW3~aj*oM{@c-|0#x%eMk(LK_7he6 zlqx%Q&*`^#wNdAJ4F4hk>79Wa37yvgA5-)48u9hG#@!{X#J$-@eAmJ+*(qveuABuJ zz>;(sz)R*d*FVMaK79T21vrf&T{?mh?1E~wQix(^(1HLw+ZQrGlU}VM3cHGy-GmXu z8L26$lB->@T$9jAX&d1wC{}fI-RFMK&t&iHJnuQp^L&B*5~g&Xpns{eHzFOmDkMiE zVwCQHkvpLBi;2WfPPAK*?&813ae0aQ1AxmJqn}SV2 zH!hpxbDGMYDe_5CTejhwc=#$_ON`b_=&C}}TD(`yWz#5$)9Ik^O9Bn|Vq*ta9A@2a zL)WUGW6zl+l}Me({b-86-OjKPvE}$Ej-HDp5#hbIJ1PDl=CS-x6=jAQ+$$ssGU zJSH#h6sXO<{dos6eIf#b1yeh@o~AWUGm{XJ0WfAnGSRm@$}Gfu@WZY3G_Ib5Ny49%8ryl+umY#8vtt7O@fCj@kG0n=pDNQ4M{NgQc3Y*sp zg=MoTKGIzN%EaVRjWyxNE0#m)B=PC5NZiivsmTgJryE)sTH@@_8U0CaNp2aK&=z*+ zT3)ZzhenG2g#AvX+Pd7o5#HL`(b=9*7S4nMs(A7T$S=2$za&3xZAuZdjQy=$sgAC$ zp5Bh`Wa?}${9p6KcNdfwH@7A`ldW4AU<>^;0Kk{0|95qD1^55fj`r@ZHc$WWY-@x5 zpE}$B>;7}8vU$^Hm__6Cxewy`naw>2!C;Vtk~k0Cna(Jq5J#0PU1@>`5-JXv<;99I zJ7+6Rxn`ve+H7-Msx1ZaZMkgUj2II_cG^;K;b3|Z!d9(h>k!q?RCJx~53kI^_>Y;a z65ga;!Oi>TH113x8H2T}b3lr2s(^YdbH<*>I2>-1f!HIRP%gK1->R1=4v!D$MQr2 zB!g15Fz^LVTa+Sba|VCwM6z;qx?osyCfBY;Jj$T5 zXU7P_km4ZxHQ$SEAjGOH98Yx|4w&5|~4BkTwNU#&1ScEp{`_q&`c$ zArlc)F|RH9%Hx+q58^^Gd$CQk^g#w|;dhg8Bwk4TMiDPaC-eoHtEFhz?))_-Pvp1k z8!Jp_^s@=T@RThy8h=gFSsX~Si~Q9%dE)QT_{^CZ{&HlY40BlG*0#|%jybT;u5x?e zUsYv>X6xjRDN8bnG=n<2!w+%Hm`=l$%V~H-ONTzA^z)vB+nGk;PrcH_KMp12bnrHz zf@*8l0jsHCnq{8Ik&}-2UWI9S#lQtiOw-X`n#{n9B=~Y#1Dnm$#G|vX(VKp}6b2!f z;On?84tgGpGni9vPxdNlWwxq|dC5?^0!hX%J^;ck!Z)tu(nP#|A|wA~hMmmgY2jw) zlOY_AmH84990?BuqT-txhYGqzf{|)j(PnUW^JRHjIN8`j_8E}}e$x_R3;>)r%cJ2W zZH=a8my%gdR;nen3N}(PHHyD2U5u72|w%w0jKTm4B=ZOVKkpI@lq5rEgGCiyZ1N=2cX$`U;ZIcT#(cA zd=4h>!*}#jZe=xc|0GpO8besFW^BTQ z;$~f9)g5~S6v&;{AWT@X^@+KT0{jn)k5@Yot{@Qzi7l(^N z3O%lDnk3j@H_%kfg~j;&2NQ^X@Go(pOymrElz2smO*gC({}fOh?g>mEp* zWV)b`k_r|De|fVe+y-LJX_b6UA8bxTkD0}95#u#tByD9w>w%RKYjkf*VEf3DwC0>y zrJdd-MnJW7Xxp@*i@M#JRKQJ%evVMs5tOC?Px~=6svcb7p4aFuFTI34*4bub=_J=9 z-kyfjJX5&O!R?YLGAU1TOL_%Uc?zEy66520pJ03ft?@F`I{t<2layB8aV(lOpj?aO zb8s)wY_*_O3X5oRU_{j%W&*tuQ0q=GZOD1!KCR;dOUdg%z;-FSeRJxoYWv zO41&ds@W>(9o4eqdqdub(n*){Mvi{ebA~&%Bm~Em|Ht0Dceia^eWU%mYxO&z_M1b} zrC~|7?1U@Is$wgN-a3wtFU{$4y-1LRDAXju0;FU%kNerrzReW_kd$nv%_FbGmVm)r z_w3oTFTb58IYi`|J9Bo= zQIU>ex?xK3{K0jeqT<@BZiZWzM$Rq841*wi8Y6H7BT5e%nPWNiP#% z9x-cd9L^}E`Rs>Tpa?&S_!|jPtrjqPQ7;f!jxRAOjZLUcTgBt?WUURlUgNC6>MPAw zpc9^w%kIWw*`I1_inMqx@e*2HHeBl^gieqjx0W}ARW&cp1Acv;!Z?R1P&t}g^OXhh zaW>5pKZMei)`+S&&pm>&pP{S<)zHkWSo}o8g`7POFEB!?#?CFt@WL?{qcju8%pXpU zU%dME=H%A}NgQX{GDMg*eOT9n|#XZ?!`^utv5O`S8%ueljYu#j+7e%t8@^Szjbe z#P?Tw3&*>r%)WdQ`_N!pvK&84@?}z>hOC+>`Bdz7nH7K|@MAcCbI%lY20LU0eFYxC z)+D(*j4Ks$tj)8W9rabf5Bmg`QCp4&j6cH+nf!df)lwji%uFX#>#@%Mtt%F}#qU-e z&V_w9GVO~*AwAf-JYIvhFU@YOgYYE1vKPEE1beQSGzOhGRLv=#=|RZ=&$OoXr6uAm zq8ES=>w?oq$L|cd2{}=YGt62+{FhA|BKELdbB0D^Ah7wQ>@wur`vkRLL2}_?JkDo} z6*0;n2&Y^4|6KvY$FeHqh9b3`)B$+kQs=qtZ>SG-J>wYIvaY3=AM=v<(TupgVa;BW zdR1Gvnkeug1p{Ep`XzAAuF~7%WT}HpSV1kd@!%M`or0637prnbL3xqtEmV4?tTs%q5{Tu zI%f!c@d?(%T;|4qSQyNjg9DM#WC;qG|3s3LAU?NNwOk3^RrMK-D>=;7El!71{&SU) zo5b45)ebYVnx*~KoPa4uQ;-d|IY{_3z6-8_kY*8m$_eVRDwrUNSX?ZoSz0Oq0Miwd z*941J&f!1G$7viqA@~&P+M158VJGSu1uG`GQZkNGz(dZ8;Yg@;cG`#-znHI9DAg%p z(r({lT_lxy!*zlr`G%29M?@kdODf@~oTll5k#U-iz>LHJ*t7WzM9wkQ=z@m^dI2?j zpXZZl+A5=GubxA##f2B@*?4AegqgoAT{-G99hNLas%yL@GNaN|UpPg^qjAL5hzm#Q zwpn%N_QFzi5v5ywAWFb}KpGvSeGrFBlE+NnEBZDaf*nTFATvS(+%9RmFVPx_g}mp~ zO=HOP^=<@EAWA#@ntY?_iEoO)Sgmx<(VoA2@ZKs76%ZMEG<*`8+zpe zVi+Z#`2yG?njGXst4o9EICq8jYri}_tSL+Sz2FD*ruvo5!Tj$6Ob#j_E2%dh z`3b3-(Qay;dTaQCJqG=B)91o?jv___={bNVVpp@ARbsp#_2RHr+WvW9} z##y;%wQoINKT94@4LB}LKAPvdBAb#FgD!5se9P5hL3!YAX&St(Z9Ju8%yg!}PL%-E zp;%#8>&5Fp)`c-vYGwjafsX->s^Vi@H=VY+tMO)1zjY(Ee~#Sk)U6YZ^&i?MN7k0< z(ovfh@{E6h27o&pX+Gia=;nk=Qi(l@&RDI`tjjW%Ba1$2OJQgJY!*CO0Q7gN!t4QdE3I*n$GfnWLtFg1k0(e@<$C_Jx|K*`o}djK?0%jVysQ>p^m=9Eeu=U zbXMRRnGzC7>#Jh#jrF~z=hEgzv3|cfBN@l&s?L#ZwOu{ZbZ@xFjTXJQv>T zajHaRxds+kxFK{^YEQ9c{yjo=U_GI%*#bO%FeRXmHMal-;4gK|xmUQ_A5VHgcq442-84YAhFv=A;~}zag`9B(^3av1 z`LaMawy_re&6;hl#`bZ3DLoNIl;ajER8#SYbo}y;{PvD~*T*C2Ywe8^r$kA`G8a@w z;{@PsVw?_FlXmNge5;KFh!8JzSc8>Zo<~s&mb?}Hsfx8?>nc3$1?d?48c_+N3RF-T z(V&5?z46dMaD!&usLkHxT@$_3LAetn6;RESwsp;&07XH|{C$IGv)2{n_n39U#f&3# z^?i5~apfi2Hjd0Nc#{Vj@i!_;&G4+IVi{hEiYM*T3_o?QJjeigh&7!&kY4@WOCULE za3LJdh5>NhZBGMK?VsPo{?1L{r*2k<9cH1q+J-s3_WIU%rEoZAkqI1M z4}oxc1B@Lgmt&}SfYK?2)sPUumv1-GRYB>K@N0p_Lz`<_NZ8dh)p50!1VSpz_FZI0LI>lT8bp9AG^m+8l2kjYdPj;tE0lr6OkR6-MBswsr zs*(9w`VhVi8F#gIOA=C}o0!s;+t6>UmhtS}N{3a|>ePY1i9rIIy~y%aiSR*Or8X=J z9GcF?o1=~dvvrbJgB@3(e8F?sI^2@%v~O5{9Gxze_Z;1jhACUO zGKM|Un5?zte``H;1_xyH50e(B$4%>q^6Z z5iEp}|Ggq&vIKhx){&mI(f_K@f=u7WQWyK#qw9bLl@cjeJE%(TK1S>&T&y07I)m8D zQa7l08==8luZHDAp#9(S=~OP5H7qHkO4^gy{u=oiMKx6SJnehzzMn#`-GaHXE8%`& zN_h?giCse*wZUCi?F6ram7B8VNXyD&OVLmI?Z73q*7PIHO)2?F<1fB`N1RjG3GyVW z%O<#zFObc#`z=sJW4U19HQ)XE}_;Yt1m~ z)rplW@6gjHC(mA;e)l)_?X0-(ugG)6A$jut&&qQ>+jM$6ZtU#+!2v81DM1Vr#E@(; zwWi)~UGz6`o$TXE80$1mD!C{~`4t!LKN z-hxxaazeVx{2c}<0NoDrC5IqygjmE=K64I!9aUF~rf!UI0Ar4(FB{P4C7zDulsV-J zGGgmxvM#qiSDzXubLvf^pv_@?#MCAUo};#f%B^7VDiyE2muYcsMC>gOmeTd3p-(BssWM+;MDUB?z$jWzD6Afr?HYICD2MO%vNRl7mH*xeN z7kMo`%ieRJc&2gg{gI1zUs8H<-E@k6ZsNaFbHr zY+4ZrWcV89US?eGyw3Z)eZE~0XrAJh`VJ(7RgnfJ@v=aNGHXjn#wQXVDwR3lp;b8z zq=Y#xym(28XER+s^AS05jXmSJx;0#)yiU$)^VTvt*rT++l#qZb%;p5dJX+d4tzOZI zh&k?reE(|MnTbPJ^AB5mrN0Nsfu`MdZ?X<-3JBzKedbt9dkDX@Xm^-l!T(J@B3apo z644Pacz_Rr?6D=TEM09@Bp0ju3te;2tA+Dc)R|bCjau;EKM>Cz7$FB;;q{*{0aW)O zR=Bko)#pDKD}G zA>hukOpEczLqAD+wB2#@m~dq%SW!FsSiVafnklwEHm@_bTDqib&ruT$X`B*^ zm85^cO<;$Ouwq^OII-y&RFh7pGXDv3pruB`5>^+hI3*`AjQxAj#cdoB zB6meE_qn(*UxC-_NpEDUKxvn$QX(Xr#KC+@gd`c!#jeWtgw&(UGiHRGFI|}O$UL2^ z$#1ba80LrLOWj&bu#uRQfw)vU8>D?DyUPevDJPy}pzKn-5i8cBu!%=h+%mm-i^i0s zibY`U5T}RKsZr*WlanjV<1dr}igno%Vs`X!kHmYw7Tv-dJx6cDzJ_M#IE6L(e%FO< zkt2qW?|f-#@LwoyU;$^8QK)ir{C^JV9n%Eg7|E+zF9{513@lQTwNtWZ$UqVRYoXnlc_s zsVU`e=9*#(UO`OQ4PDbPKTLvDv|~(^*Ib@V2dv6jw2>mUR8eD#%u3~$f>zOPWkNcP zWAJ_yqo_*O#J#;Ho8@hmp;)f#f_R0Ja*^I;)nJtwS91{7SZ4A2&;%;vo_d}X1~zj$ z%?J0yW!V%+gZ8II%6gwU@;BUnFHT;*{_!N(8GlBFl+8qfoH)mWKWZO7=;Cx9KB(*Q zF5A&jo9W$2tbezixyg!u8)PiUPJ**WH&~LI6TDz4S%OxCZaHxNp;PzOj9%??j;F$95` zaAnKflIHZL3sqmF6X*dUoNyRAWyXj!O{#mqRuog&gZ1tP_Qrg$xBsAFWAX+>4@5Z6 zCh1r}7hZ6L+!&kILO_Q_d^ez{uIWE+ipyhyIK^|VtKKVZJK`*5;}oMd zZh>fn<4MQBNU}JMmHtPwe(QdSlVDy8UJulJu6!g-L~KG4wAw5Hg)C=X+jC(=Mg$mJ zT1)6#hmV;FtyKtyOGqv`MlcTPun3h!UGa8w5jy4|@^f~IC~`zCU`w>jB`G%t(Vw*H zjk`P8O%;I<(j=(`^u_7>1-s$D^VQ~P#b&I5`uS%KDvy>UGjTa9k(lOeatrI{<`ZYT zaoM0HUXQ7Lt6>oBvI7^&ThSM!^lMAoPzo_pJ2fnjHOjJ)`)cZ|k$iJC64<+X>`TCqrGr6fo|DTfUwl`Ln30T;IZIw9C}GTXNr zZJQIpQPgW_qH|nSXip3bNn74%g-^{3Trvb2uYVs4R-rV!1;*Vnyf#r7HGI=CsxX;*8h{1eWJ%Oe-M1b@;qn z`xxnUq;$DMajHrXojU{xyDi`u*v%S6v+=%z(^G1OVvlTG6YM7e8*QNoev}zC2Z46-^N!7Sl2wk1N=B z#g^Jli`Rws%(kQ|>YXjs8TGa!#Zhr)2x*}YVz%rzyc3-Tp|g1&9f_5Z>rGHO$cXTu z&(GUxlEP5a;{J`RiMaFRX@z&Uc1^E38z~HV2fFnjynQE>`m>P*8ExtdIj<$V2JKv> zlc&R)G&Nzg@9^TuSS6e8uEX^q#|_NBpzC{O1IX$DCzy?a9bsZt!NO`pYT!urydvKp#EEnq2gF@qL$sln zb0iQFt6mxBarFcvJCSTd=meSpRQ39{E7&p=<6^1JsM@ZRPo=X>gwf&9 zb|L(1>~-68Oo1(G#SjCzoj$pmQ_E(jUv&4)VYEpxIG*&1`EajwZz`M-CnJx)|@k;eBi$(yD%Fx`XzvvI!Xj5+h)Ox%K?Q*CMl zhc1Y2Jiw1R zo79I+V3vgA2II3-VV%%X;wjMra!=|ylBg3N1&CEtF8q0!wo@Cf%%hiM7(MgvPOoop$n zMLDY43V%*8I?{N9H{cwhY|mED&A$0!9>oW)xmi1&x_C2P4vH46Nac>|<3u)$fU;y+ zzU-`x-VyCsYxEh7UF}|=WJ;>y3`({ z_CHlXY8WPt1@NYrOvGQtckB*%ZVpsr6>WV<8KM$cpq7|GCj_VB%r+gTQW!C`9OL5L zBroGdRiJDtepH)f%dT~bEm!br5Xmev)_ZQ7@%2}c26{7YXL0m=NYIU(k-8g;g^F{br&$pIKWGYERKv!JxO0aCJ%!5IG^RpQ1j3!h zcIS>$;|XUu2+5cJmQsm#6O||f_CSc)|5+HkfI3xNdldqTY=E}>TLZ2nZ_xyf$_zFS zm3U~iTmNTLz!+O~)*W@K9+^tisabCfQo;$kHnv+YlQk+$ruiRRow`I2=%)nHmZD8@8zK7Dw^u_*H&>*`n$9Jn18@NMZd(H z9N@zrwPFlfb$uCJs#u<{X2TL~F2wt^bAX*#k?Z`GsfIfGNvQ_2{mg`S{{7i6uYP#_ z%`k=Q7L;Yaz`eHxnb8(KGGpM0XCJasUPs8F#_%Y(1f>a{XjHZn+^R+t99u{bwIK8y#ug^)e%W^3%`HWbAdVHlubmSFb0Q zmi#J61GGIh#Y^)cz_@>9Hp`|-q4UJjQKgPe3UbFN^Uz`CxtXJRQ9)%egb%D7iXaq! z-L)kpOB|#Hv=XX42AL84ao@yo+;zhMeFfz)R?Rj=&cBD}F1y@XO|h9qpWLMI$CIy` z^u(O0%3qPEflYuUMUTDS>)c=!?FS=U2b3T68NzDPttDtY@tjf`#Hrmp@*-UxoRRM&zP#GQ1J?pc&e$I1OLcfxeQ3gT1H3dg8A#P{#`&U+r4X9sEb_(~~_1y^AA zFuhQj%2k^1Mt6~V1kN|<#oLhYNQm{?)%f_Efod@gg8Ds(2dZ<1YtT+QA*$)YD{+nL z1EF;bvqY`DaUZkqr#>)jMYTAFeeS3hu^t?8GB=k_9suUDaTFAyB|FPdVBo~rXRtYj zipeS;wzsn|8^Y-Yl-==q**Yyf6S8EfY(}eF6*a_l44f7{6bX z6o*}|NdI}Z;v{S7-0nnTh`;4kUEQhpIuN}=iP!ro-K2qTP`)Cf8DbO=`6W4fwN(%2@S1{Mx>yZ9vD*Pj7XCklnl)Ds#ePSG93+-Z&diQ)`;A z$~a08(4EiEQDNo!qSDq!q-=6_&n_8>Sx2Ot(MVu4DT;XtDW@1^ zq2wNMN;pp{5VS>^)qIYqg9E`lv&~mPbb*esNL$w{fk{IIo(Ul`9e?*1mG;iS){R3L zQKE^4v0$Vnryb4(c_Lb@%5!8a2zHT3-eJpC$W}nxDmm2`&BKs}NCKo>BAB=GDu_fI zAr|=_q1N5kXOc3Kk~^Sx3TB&aW~j2tHLgwkk}$_{C0n7_eFXi6GR~TNzD}kURf+*A zYun4_7a3(5-Kt5htQmsX`H+9BX&mqR{7YRB3dV|gY(=vU^@HZJ{15Y4_`lO^?yBZ( z>G^3W5wuy%9~GSHS)G?!Q*?E9=CBbJJQt{8mc~*N!MctjJ?!pwu-29DD{34lVJ(DS zGb4DC-4R}`&dzL!lc8~~oI9LE5R*@0Fke@0lKRYp?XsO=yHm|4OtLa62#?|_c z@V8Ypv|BGN>j_(JMr}m{D&#YWd-m5vzPzM9YH#*TYYIkg4V%}A8<#;pVMOJk= z;nmZq*z8U~f(hE)x(aOFqkUtJyCgd$CIlvD|ER=!pw3L{b;eE24ot+!tIYhQ7X=&) zU&5Ne%Dqc1??Mb&$6Iu)e(-0?@EMsUrTQW>A_WY?91i~hXG0v&Mo|e{6$Rrn*BWf_ zUofqA=Ls?q)d#dkapEB)+}E!jQ$a^e19JHIV^l-50?0o12zQptn!p{u2XT=Zw;mdT zrg?Y$uxCZkw<3h}ZCoIY{~P^^IR|iqm+2-4F{)ObT5?JGo8~Upa znlLN(Ldc``Lcz(%St2B>y`e9nEGy6uss5;fj)4wcb)P8xuX>GD9N}Lqs|%8dC4tux zz3q#wGPLd@N%}io=)U61x|^VQ=MEIUbEigDRPJ#VaZ%-wsF4`i&nwm!PDgH(mxK)B zNsi(l_K8JD_J-8H+}BLHpw@DeV=$F#mEs^wG(k&vm4gL_H>4CWUOTAg9y46CE9@B7 zA7Ag3y6)z0KBe@wCz=j!_=Y`frBiU>!tA5$N;_CAO!gLLt1s$e^SRs*@eXBjE)yoq zR@X&?dfRk``j&LxgmF!f>@$}1fb948v~W}~@}&x=Lq!}_9=cI(tDnS?ZnA`98D;JD z$&BZy=OvqbK~D#vSeXgAv`J`{H@EaHf@JwZ!cqX`*;-JzWD%Fhg`; zE~t7GFdky9zKvchX{b-++F$1VVN#|KAM}ywwXujFgD+bytOb;pM^Rui#aqOVs?Yfc z^@VGsN22y@^IxgVFLuOvw930);0<-$YI#L(oDoBg<*G68kj>Ru5;@B>g4Whe_rmHcY6_`B({UVTcN{2e)1q{t zjIXep&GyBWlzqM1P9_?u+saqnVnUzwNUbhW>-sF|;YTM6iDT6C<%i2`j7hwA)H(T@ z)}N^sEiN!|ZYv@f;n>|S+%>U(60K`!ZtDp8v>F*aTiq+`$D{C9W{etvL?^j~^P7gf zD?ySjP?4mn{d%X1EN;EJikrEDHb#igQpZ#dgP(;yufY64XqbvRpif|ATg6-&b*e$C zwQ8y*y=|#shvl;cEnY(cem~DIue_GWi^VC_8d%ItBi&_fD>LspT(^qFsGk?vB%7Bl zNpVP31+HIjoWgG_*jYj*GOl)*LTVN679I!wcvW?~i+B;?U3x5z!WmtaB%Bol1@yYG zt-T!DI$SeSpXl!5%IUY{tN^LWgj>22y$1HFg#W z+E+Ar*HX00B5va9SnO(Q_N}iC#}0}MB?C2Kz3Ka`T<*r%zr$WC#z0kHkE^>RTZ7TU z5EPOb^$Pr*wwKyil|B2KHs2K(yV<*N8O$+j{EmBAsXG!ln3t4&QYb>I+kxcOp0>C0 zJfGinw)55E%eEwDBciD7&lJtfM@Dqz)ZBH#%QM%6z)ebHH zSn7!Sggt1t7DYPCRdKAR?!@`%=e>ZaeJ&b>~zHm=hd(-B{x$W5h>J~(Z9-0->6 z{UhhM`j4=ON5rp)FX69RiHmp~fwx4+(9TQV4_ZiIw`kPYhKDy&XyL{DIK>a*->2%_~Ob5l zejA>=Ik@r)IwfxYs@zF^{z| zVT=9F`4iuZ@BR6C^8N=nD%0Y3pXART|Ec?TZ|~rt`5B+@?>{)a|GVh@?>@ty6=KXl z^B;SV|0RD84x$;#!bkfL_Z~ca_~lm*9>sgV|J}`>|0REvYG<*&yB{CM`}gF*y-_~R zR|P!(IQ#$M!-qBdfB(_mqX*vpKRkHw;CIp9&Hn%7e{M&2@7zU?Da-~Ht(IqZzr-ha zD$+59=h=^^ucD{fD4l~8+J;|9ta+R-)<%?T*^F}LpnoN~5ih8FZk_tGii%bML_GQT=9U;D^AQizH zAzvb#0WvbLO1h9P;0iE<**wF4QySS~HJoPUIpvcSUnDr5@gYqqbP9%Y59CoetfyE- zW_*=Y|2R|xS?JYnxC@cEfAP~_PoJDTiEbUggx_y#r$Ek7>#Lt4Y*FeuJ$Z?>{dn@?@elCp@wcZ>Phb5F*6F*`SI?l<=sT$O zIC_5k;??Qn*H4dMM9*Kpc>dGN6X?JbsQ20Fv+rI&GbcZuJbM*Gv+yiB`78Vqz5L<$ z=~Ha$55GTt4Fh-qExm{y|MdKCFHXPz;Z^j*Pfwqmz{77(pl`?DK0V>KU|f%%9-sc$ zjh-C;c>Mhdef1Mm^WqP`$8y}k=;t3!@ENvv4F5fTb^6mY9LeLKp1pbjzjk4uFJ9?y ze?EPA(v6N^oW6w4!suT71P$Pv!Y4mbE%4#96Rrm5J93rr z$Q*6cI4wu8Mbsf~>ejoE__WKQqddNmyNvs1M*a!-A zqSBN?VG}OhHEP2zO0CswMPJA$bTS+ptH;Yy%gKXuZXRnqc+W(~ZW$2%X!lcYnQg0< zZ@!7zUq*MhXeauAqP_Pn4nn`5{!`CTj((wm8m$?kB3;@39g{CvI(@`-#MQp{=jq0F zbXGy>6_<0X0Ya5}0u{7w|I*w0=HYvjXvlQVs|SNO8Y=qwu|<4GUzFeA8k)-7x^QpR z*G0QD(2qbyprR?=5pI^Avm?=872PQFIil6%XZD_~Pxzpz=%A@9lij*PeET|`*>CF1 zaJSCj>2aOD>^Zcu%=^V8*n?MiE;(=p-KhRIJ9QK6QrJZk*u$NOPPb|>QA2l`n$S{3 z3RC%aXl9UFWz&oWd4gIe9LZ=}0-uuRz4YU7DlUuF$ngT?tzd#qUwr>9cRJWPsJ-1T zqOZS>_8)elKSk{c{`@8WxK$6&%M0!y2;uPe#Z`Lv!^^)0dpH>aUsb|P3@!C#aaCKP z(ZqVVUH?<|bN|b|he>lksmO+Y5)1r9 zeLP4FN4!v`A{or-MeD6;TR)W!P`zWQ=JZ0sTz*=8<3VLuP{ z9zOi)LGzkZkq!M^tP0?SpQw{x4G+H>K5XnH7ujYqKWR@N?caa+W%D-YA{%;&F{W^t z{6xJ>zuHe9-f!$B7ujY$KW$f&@&1FuM~z+OBAfVTJ{^CeE}rd=9_*bpc9Dy0#Wp`( zKSu|TMtf;vKe@<;e&z+D41OxoeE29mIA|tKDzeRFe$t*MUp~0Mx7SRWRAfU>;ePe0 z=JL^l(f#IQl8bCJm!GbiUww5j-mv6cWJ5QnsFqF(lswj-s;h^|VY1;Mq9VGhrc=q9 zJS9yZw-cg1)leSpJsN-6ETC`^b4}$Q(KvMPwpfx+x*(6f8hzEwd%1|aAkK1Zxfq|8 zvJM|SOdmB14qU`p4ntU04>!uZpHlug`0}gq2Kk4IY`*5KKcPJNRgw%3H*g#*vel*W zJe_^ATg1crU)}%Cfp{bf2f-3x0tL(mgKpM~q#z~KT$x2$CG{?%-dUetD=)d+Tc}fF z@}1`BuFYfk!;P27Z{W|3|JRNG*Ny+zjsI7`|7*TX-=o7gVont0H9WzZ{lE4eJUI0I zzaGIw>c;=;#{cWa|Ley8>&E}YjBw z`UfJuC^&v%7O4tDVfZ(sHNw;%Ct~P#^W#BnvHnEiOh_KQwo2*s7=2REOF?Rm%M)fM%7;j8>cssyPEq zn3IHy_&9npN7@%Flrhj$Vui9e!?L6392X_-Xr$98s~Mm`7|g{gL$SZPJjcLn1T5@@ zGH=P)RfUzvE-t0kyqu=#qJ8MO^T1(}hWvSGWXq()bd9P8VC1Vp=ZvHhW(7Lk2p986 zFL)#}bc-?%RQ=;(kAAoQl3#`kjd& zoPW1w{lm-Y_}l13s~N|&Cg$e;e{=u8x&Pn%`CoDWN0`-d`5EHB9^Bu1^r#a5wRdoH z|G&Ba-`xLi?*BLU|KH^OU!_OGN91E2NAiYXn$$xH*pXMt@~Cd!{gc^Zxjw<8%DH|c zM0tJm1f`nZDRhHch^eub`{6X5*MGN%Wla|m6UO|;R}>xxJ$PQ^@7MKOglV#NBV6Rh zGX`$e@5ieJ&S;xU?a)Vf*>-B`>^?Kp^Y#~I2P0Zq-KZ5KKz|#Pjvswd;KTMibcHAP zcKpfYnpNG;mg%f)cT@n?J50e^EKB6O?N-0l>3H3ma29kuJNQeWe`dP9$=(oVNYc-B zqWy4MtHEz}M9DH=0v9Z^e`$O<)u@|gD?M9H1=A-T5rQ-(?pP9*F0f)g#~y;nK}Tsa z!hD8wOzG}FP7Cb2BxI(%w=zA+JQ@tl5@O2Bgs_A}eTF^^3C2Z8Y$bqyPtAZ25 zW_b2yrH#~!>)qH8!a_ki+y+o2=Ni8SV$%7oE4Ilyh4iXTOa-i8VbSQMC!jv}rV0W4{L-d1c1e@WLtYl2$=BYslzFkUmFYNWIN za3rFltI#E$>DH=N*s0b1it+rMkAw`62e$n3Kq_8wCZ75hY(D3HX)kT<$g2xr7>Zc~ zL$O;g!@}8F0Z=}fRnwUMd5f@2lp8oMlfd#SL75jItk}MjEN74iq8`y)44j0_Brv!s zg#==N_<@%2=tM8^3#gHn4WiLWAN7=ilG;ct{vwP$8BAueNR^Efk%6pjiV^x4Kbx&*{w}~&`<-CD* z^}x5R+WS|6MkjoIciO8ccVpI)AR;zqn&ah?)bsPo0qQuI-iBj?gs0&eDGW~t#g9l& zBhmnB`=OW36vZX*;Zg8s(eJ@2MSYV8G02 zaZ42VHFm*+u5BKNz(s?cwDNMN1-LZNDqWc6yoW1w^d}m)0x=0dmHLKd)CPty3p4}) z>j3l1$Y^Yp02y*H=j)g`3V2WD{7YvmB?e!jkBkbUDpD~Jm}@#aP^ z?VGoiwWJ3B#4S>}H!Vb60TPr(#BCg&M3m04vnQvei~^O0ZgsN~GiyH5h1{65Cl?m1syNlqKgq_w;? zi>w*{w(D$P){LMS1185sg9g%Ln(=Gb2&g^lpTV`^bGy#mZC-hF2F*@<-JcUV`FYlJi z_0%F=xUi5V_i9<1aJZYY#mlg;sF#hs-=OgeX#J!j&bj^*X6iw(^Y+UQ!3(YyXoG6X z*JvN&u!n#7;IIkopGvk}v0H_zP^UB=z(6kei;vo`2DxLs>N8!pday|h3~&IFem@Tb z;AHH<{r_BTax34nyV3E&=_DMv3vH3r@uBAQMZr~ z6ESNI0XmpNsauoz5bi==ZkLhzV9MkBp#B_8AJ}Kid^zvDl4=MjX z596Vxwr4uxUKi#xnku+bpp!VvPP~HrI1ch7uP8nJ54bfc^{mZ`0t=~>x1VP%Rcqnp z#2ritK&|B@qtuLiEYY-2CkcAa6e%=>_ir(E%L4xgOuVHI-!S*A&igzwFS^QYlmlG! zzeG8p4Gy6r*P38DZ;@W;)V->PKxXm3Nkf2R-gInY8Fk4Q&$FG5UHiPPe18Q+gG}=^ z6%ATF@12LNKIg*_f3!}+58<Y)hMuje+8r)g4@ zOwE|MUS{9PS^uj@n+A*NK@Eeb3SUO>y1G4PS80e1V)cytX;v;n-280=JJ-7f^9c_a z1FJ#zOSZaA+#O?RspNkWbAMxT_c8lGZ?rnTwdq@r%4hW22sF*+=@AA)`>139sX$i0 z<1x-OPo9K*Fi&U4k>3bQr}0^<;H3l!SD>NSLN)M|nkq1$z^miu^AvMQSkzgbD-X?a zRxZ#Je=HT%b8`N&%EI|OVB-8kcLRs_-?R0Z3;0IA58Jq3Ffqo6IyWD)O}n!jr?KmS z0luN1-fqFpfzE*Y@Rxnbw}C`HPT%iB`=?ZmA^%}|hORG(l>(LOboRxse-Ip8X~)n= z>XP6nis#`1#b1(>74({?I=BOF_TYcY9^^%8%Le$YTXBSfQ@{T7e<8{*44IJXCCheJ zh8%x3jFg&dUvqG81EQgQdeS`BjYDVw!(Mzo5fT@8N4X&?=p_miJ;cPuB})#(Ua;#> z)Dq&eDKH9<{mV<@9%&_4J$kYCdVUbm&sZf$fhh?`n!T+Ri(J}U9e<&mN7~)bnY;7s zY^gm2Dd|qKV4$68_Aa$zeNae?KLcwrI~jV#s~2BEH0Hs+p=zt%&TW^Vy3r|?qn|qs z^0GF`U-M-85#xiibQj4?&Cm>&W|3opF!F=p;oBwp?rpv0l@-AJ!+3&#>+r3!Avp_i4?08Qh0`n|IPIFn{&7#=g39g+OdC2i1 zU$j*yQRkz@uw=@oGhm$JhP9Wwc20Ct_HB;Au?JwB5kKk}OxR&{820OU`7hLb1xnci zwtVaDsGc|}@#lZ#^R&JE*OB%#R1f3Ta@2{lGM8M5ooXvJ{^{E^UZlV_FFWJ$C4auFiTGsui`(;o7tg zRf>ha=FsArQBlx~85aH;xF~S(8wmIt{I?tYw;TMon?Jur{I~oc*++qY+kpSJ|M1}c zfsg;TcmL51{@V@y+YSEP4gT8={@ZU0|BZ3oVCSYw1?zTrcbAmD$zf| z-(DpXRSNc?hKhS#riG391tr`1gH8?n*9cAnsEE%#b?teQq74-HNzP2;GFkH`5XBB^ z*hWQ~5ML{E%hkxZ`Hhk}*LI#Dc)gwY>ls`fhrk;lbq=sv0< zo1x)&Y73w`I5fxXF(Pu>*7#vf>TzE+uIQbV1mimW{3~mPPM=8eBK_woD^iL#hU247 z7kT z7ztHf>W}a&0;-j&IK|Ppsq=OZOZ5TT+>+=O$OfZxRMw`G!p66ntg`92-#njG24>S* z_F)S1G{K`?jr1bPrbu!dhiWRpv8vCAeqfpv2pTZPUi1^`mXfLV+CqNm!+{Y$B?o0; zZx*!}s4wzp9;P}q$5=1`#V6}~9AbP1JLH_%H~BN0hJYa|Col1^`nQoB%b4eyzbprq z++ibkRdKsqx+LTdS$q6h7LdR@=x?$mpc7V+gW!lisnx3i-=Yi!gbP**Fo>G&R;LMP ztIJCc=LA+zMLr^}n`#?ILO;gY*!TUU&&jTlEYnH^DnV*M%>97@;3)*i2j-p^8uL2;~=Ca71x zVzV>c&-4m*DY1zE8PkS_qj@>cFVCjQyA+)t+p}cRCO`zMLPbk&-V%JN_BSpmI@l^m zG*p55;bOQi+qB9@*2**C9AO#4Or^r8S&vYfa28yhg%xX+4SnOJu$!xcBvCIN@%=J6d|x!jbUI-cENTCuSPamI6sM#8$?fp_iecheX5k@`ke9g z<&1y(b<+D~k4W_c{*aA7eA9}>{6JM!I&ponZJ-eysM}$td$r&BDl=B+wNL1%rxojeOprd!yd?M_dPSHM@~{y0HA-J;2K{!EwNbd;RKh z5EF@cOR0DZ!(BA&6Osp-anj$za#6+ci0cVhPncbQMs0focP{g$B4Vr59n!5 zLWK19%s$Ox*eq@Q3CZhi!z5D`O%z6A9#EK(YAu=Bl4(OkZ>=_Gh%&8dS;*PsS=nEe zcvLs_h=k;xBODKbeW1wNu&^PY-1{{PC}8ETP!V1!!JH3$$tw~54CN5Z@Q=Oa;@xPr z)&hxDP1mBP82A!Dt;~2bU$<2Sng(!|HQn^dfyiz$kW!1h5G`N{;BsX?KcWNQU6lWU z+iU(m_C!CSZ^aKSq<2v$oaFOHYLlJr2S98VqGe9&eKoH&9#!DZgtzLqRi`m7&)0V4 zrfE@I^zs}v4y%RICnc+Kwv49vWH%46@A6`p0gcYx9^jNIt&GLXc&WGxrNxmj@J#18 zthkb~*J?f*tqQ!aTf=d+1_6&UD+8RJ&yD-h=N0E=vo<=gp{_cjH97G=0rE>>-rSfN zBE2rNX7zKJCW|0ZocFAtl>fUNp8?() zJxy_*=!_&kPLOISOQ*hs!NU|-?mBmT^slk$kSzWq_8fNPnmf*nW#fjE`!Xx`3Uh~c zPMzRcBge=a5d<9BfnL7dxUI3D+ihyvrtB%r+f>dif3x4%=5PFeZtVY`+5hLO{lhPB z{C{rzf5!LH`D#{v4*#F~_xB#{SNwk--oNqxx$*zG@&CE;|GDx1`Az13#DEFq-ZKJ9 zOxbTjx$ocwVZ2-|IQpR92RdTQF5g62CvZF|(`@T8=R|o$**E0bkDPVhdG^;F2=zre zp)4En?Bya&Fst56Ht4F7X_1{}BiiXtF&B$ziy=t9%cfSArxt#_D)p~V(z9eWT^?T~ zaJcBFFVZP{@|$oYwqL6(7#Duto3WO41PCFCZ<^|c#$pFPUSzq zFE9VOO2$9rz@zlzXRvF-BYa+@vurhUD#5nGBmb_*()rl!$E!4%{fMz|1rF7nSzs+3Jd_=~a^ zeNlWvSueR3eG``-?KniPj!cl1+NiQnJsstHL%Q72wA6#n%DxI6%8PbB{D&H_lvUw- z@CLmdNZH=dRjeLtqlq>UT9({t^5lAA|GNDnc87+Z&(jAOi3 zGms$gRB{2dXGBlUFR^wP1HjbED_%ntu2KA5y6!5|G&^~b<+)TzO8q!iXVS3|cNP4w z)7scd)E+sXHs*YB-`$R0O7^@F=CZVsZsBoH5&alM2q$fkuO{b}-c)lKSXFd(=m^!- zJO-7DMlV9wn(|H4HSF3eOJQ3rAUp+Tfrf?H}u=iS$L}TDY7~;qdKY^Tc`)f znN+3KFKk*@_&gkk>y~vl3{72q#b$clGM3(tO0@cTFYN1H_bF7+8AQz|raSzN+r8$G zXspg>^u+pTv|J@q+2iF3gwu8>-o$tU93t*ZP1HI(K&EUeubR=UR{?hvOh;DrKxk7# z{-nIY9=;|1Lx)Z_k1FMO9x4tZXs=Ai*KbeN)UIndn35^nC}#87w*QOzxoUll->dUf zQoT`9k_KCKU)n2ct0mzx{*h^qkl9dt2v3yP-4RKmOjMO*FjbCY&gj_RIu(ASz!Vg- z>6+{=Vdw-BS0ww(7lrbpQm7zbl$g}TuyZqafn?fvw5eesH>u89n2MMqJML6EGq<(z zDl=70Glcpk$*4SAEzvR*`>vE@6rfGjm7L#O)LHe;dn2K>;XqI5*CQpcsWFBVbwZz+WPf#v z=W6x2q()`k{n|Jr^&Mqf!9PdQ9zR(W*#$by!jpY|a)I|jE^{D0+aMh+_{n{h&zrAZ z@I){=;Z!N5=0ko`E)iLdo;=*fx6pQbVGErajdg2vMl$FCnV&FbzA5v-EkjVQei@lL;J;^Rg%HItQQ^UF|~Wdv9hfDzloHO8 zugd;qS}yfBtyOs!AGGxAH1S^J1M|AfSIcwzH9auzM?eNeGBxkzfs{yBUi<0FZXaH| z6~Jq^0t^C37P2$2gnl3erulpf3uId02kP_nc%H7UxBNifCbJS`tZ_0^Z}kHya8@Mq zcW0|YF@ctTAO(g+@~>=a)z1&)?Rh?*yo3MsTlGNR7pt<&66TJuT%Wg$qqB21%{-r{K3~*a-r|EL zq4S-iXrTEXoDX@CE!T>NU5$_1qQ!EzVO5llbwl$&eH41bo6fmKBzK7XD~&TH5^ ziAw#mX||}mf@2lfpL=i!!yo4>{LK1Tze4|>zSH0}rdSSsTOH{hmKphmj-5H0=j6rc z&JN1*a#!GaxlV^FI?~OZIwR$28R`_t0lHV*f~9NqNCRm@*9xL83Xya?l@=-RW7VdS zdFU8R=40!XT5R#lQme(?AQi6DfhpODkb~n7ip?a&JK`?zZ_C=eq$+nl&k1%7%kocB zL4J0opYxB3_l+rbr-lEj#^z&cYd%&F@;+RK`e<`o6+`!3HowRi7@YW~{Bm8csamo!h%LFIa%mYf~^SU4J9_W(lY3OcEi^GMwh4cj-95 zShD#jp8B)AzL?%PEIa|cBZ)JhY}3H9ZXS7f-Fx_yQs_uV3J->uwWAGk$U zbFUB-IaCXvW6a&5!yR|8TErvoFZZiOoKZoM#)vq@K>ed-3Tw4mQ~^m{Mj6}8u@^3* zcy!FAx{dX@thCoyAD7v#KBtEtp?^Hb&Gm7a=K6e&-n-^_efHnG=6Ll;=$7M znJ2|`G=63uHofgXgR`a5*cPABq13x-C*93(jk&L$YQ2w9A0C0d-G^n4#ol&v&qrl% z$4Rt~&t9~Fp=`4u+}XSSqF4v>#`?C|5Y8#yyZ(5cBmW~1p(7vku0LK^n7BTJcO{SO zGk8}_xjuupWt!ecpl4eE`WOeUEiLsv0zJE;RqvzKXUSo`k5M1UW4kdyOOWer{aIDG z>s@nq`;uVqn!DQ<8++TY)`zNt011t6P?l_pJ71!A__B`%`-C30qZ=mdoVq%qU?HO>j==I!YCe z{vhZhYc$rw)ueyEf;I|cL7bf>{c=WHriZR65D0gMNg+yfiYGjx`+n8^VUeIZ74Mc0 zs_(MtG@~ResKWWO@;;f$%Y#E{I!%h{y04Oj7Ib|+P`2-6)))Ms{XM1mDA(mOoza#5 ztA`4VueqCZ8wT>pTk;Qp6JyHAOd`iQRp!#g~@|FHT7 zxCVTS8=Q1d`+JWp)wb=r?3zL6@8nsM){)te@3b^+Z}s|zET@uPjEkcP3&`H@mh zB+Jn`KT$?(4)Hby>wLE0@OH9KU(1%`dR@EPU`+=~_hm1>nsUA1mgdp&%y#wv*|Ny{ zR3;mldg-xiK?rzeJ2f$f7+c1O5qfCQ6RR4_ZQJ{tHNRDTC!4|5p3^QVuB*3Gm!$3@ zqm5o_QZ|Z`*YyX7r(SK!DH>f^&=Ey@uvqAy$0jcl1+XK69Yxh>OiJYkjN#nqiZ&QP zH5Odw=@~||pC#F}#2@VJO6pS}#bj*5)yXb(TxT}8&Ae6Cw_1mprffULdB(QGXuo-9 z-WT@rB@25CP4ne46PmmUoxF+vzKQ?7$^UTk=QkSvjc3Tm2>{=e{{jB<z}OK*|!+Vn5q|&t=2}vU+5eKr?{&zm$JBq zb_LO2C0iXODBZVd8CUs$#RrjK>dhehQCVZr z&*-Ar(k)(MHfKapS9u;3Yf^Y;+{S>fnEKiYdlcpdH~Xqw(Z~t;%pOpJ5Oo+Ih}?0N z3X?*(=f!H-Jg#T?k9m=vQn>5ZV?ws$4T_=q77_0=WvJk~B#n#3({rMhP z{AIF!mM_0U$K9qrA%t3`TWXH%?s2wjsy8}c4aMCpFM^YQnGQ>IcU!6;t269}>23w; z-M)Q`P7R$6Us;X9dMM{1+jF?L2eG=z5 zYwegKypCEet+m0am#}Fa1Ko`-kP^o#=-C<%24rCV*dxj!`=_WCW5oPB32J6o;CEi) zNjtu{O9^fL0H1KQE_WPzcY#5n^h;~!7+of=^!*ZpWdlX4&2~% zI22YCDaTE-lU=^lkeB4H>T9_G24%rlCRt7xg1p&Y$a^nShWbn=1=N$X{7>d`7bAi1U_EEJ@s5V(;R z;^?tDu_$i|f@Y%7ND0@)lCfNsO({jV1d8-}uAE6yy6$n>REy9Fo~I*p$`xEns#P&b zT!K}RRyCV}#20G$x{4bHQclPMAL+tg2^pDrFHhLGLU`tjewgj)nIcL(;#v3;RSW+}J6mx|zm`UhXBU6WaI? z!HDe1NEe$rvh9ZQ0q~1OF zsJ#=u^)f9k(t^XluiVchI^5ffIPSvXs=M{q&g@o!mOpG9&FP#%`JZ6A9`CNvG!P1e z9~&`O?lMt2hcgV#xTP|ys@M`V{1IpXrj_Aa&=Z|;Y;y;XiwP-TcIl*lRgfx35u~kh zBA}MKe{?#d^xOuP8b_A}#%M}1y+VE^1S0FEz4?dz%C) z>VPAS>AR#(p~pz)^o;U)+_$W{`_A>Mg9lM8!Et|iOqTCImH zF)va@sHK$yiKOKVvocrc!zMpANE5A>YPr53?~9kLjF2Tm?X(DXZKrZe*svvx=S6k_ zx2H)uKBaKg@`WU1{1}@M7FDhqs9Ij=rf7FTTgs(~mVMn)`9m`bCKTP5@f2F1;$%&G zg+Kg0CnX*%PT9MstW_|=***PHc~1zKG-3CM38!<;HE^D~{UGYMb5g<$43YO~ftOmz zmXx9{XAL=V0+stg=1`p9%R$X+PBS}7vA~wRy%rJ#2af`|BWD{zQNXhRX z^(`dUzN=y8q~_NBj40xWWHw z|DX5EdmnNCKYH}2e*gPF??2c-eE7TQ@Mizt@c*0j|GfPF%f0yE!QuX+!~Gln|G%C8 z;|&UKJmtOXZ;jpf|KX#qWce+~b?@&Etz`2UUn{|*1&$p4kb=xX5r&Hn#zHXIzf z`~Lu*J-G4z{~Uid`Tr~W0CI>GIsD=G{|^1ZZ^-*{na;^Ee3p+_oZt5>8D&#+oKG2X zk9^Mku(y_wzzkg!x9$H$^IY%)gqqgf~yG?x=_2 z#^XOm2b#)5sQx0QknZZ6d^*lA=Vjo{#Cmpf{@?8XoAdwX&&NCeIbq5bg8?_3{|65q zc<2BAqlXXnZ_fY!g!BI<{_iIK?dmmkkR#OmafGwf_OY=MZGtGuE zi11VWxLli0mPIm3hso%jeu4lK>LqHitUkzDXG{dP?*4mB1^Q$5J_AM|*8^4TB1j`ypn$E~)JWsR6qx7Ts|WtQe8h*ZbZ zGWWxYB>EJCJ%QxhdIy0Bzid8Fiwf_cKEhbB_ieq4+;?^C2li`Gfuk)v_!4SX?c9D= zVjf?%A-5L^hGc<&b&iwSb3WsD2>4EKagWjuhyYM5OBCJYd+5cj_?8t2*BAEsB3%@{ zKvMb|z~|Q2l8^Z=^6k5_V&4!TKwqV5K5}YrTdl(OL!DFGoG_hUZ77zzPrHP<(3git zsxgo)Q=Rdc;x4<mk-|iK6H6f z^F})igx^y#bsL_@d)3bwC%gK3n8H3xVWb!NJ1l|o;+ILz5Y@b~h&|)sBG%+X0g+nb z(G>VUTua*4>khI%yEuU*Rf0qF%Q^N6o0H{X{1ElL)v5WQtox#Dp|ixYZ7_ob^ulcq zhv-)5qwgcMfB~Iuw}6<>Bji zwqUwNPMXYy<0OJzz3xTtqdy)+>&>tzja3{`6;3A|@`XcJ@r+R29;sJ_&vs{X2fa${ zUscy`>ri`oO|jaB1AyS>q?nY*+umK`Pa)Q(zi#@@8pQ?Yo$Vu_ zjrqhvltH-ypQFy8!t7|5r59abKQ#*uD}_fGm*-C5m_mIL%ylh^Q2cJ?5Mn_`Ia#41 zV+Ar#yTVPk16ZTaR`Y3|jLo-g{Zl6hwWfo?0~IQm2fMp;SMfTE2f_|rlym^_6^O2r z>vxMKHbpc%(}5+xWIS^4(Tz=?%5u|@^QE}invR>W&!0r?gK)ZE1ndhj4u#q+NJpv@Eo<7gK zDd==bQF>(P#@bg}lM+)ieO-B*k}(;=w>E+GBkXWpL%$ztNF4=}X+DI5fKRj{ouHOf zRIFC=QG6?#5AQLKR8Cj;aSB^5SrRk~Vmgdbuy8AvySKluj@?qIWX@(8TAvAvNZp(0 z?LcFSQbd1h!5`#^7)2mCGV{Zv)Nm(ahAvj~h{aOcBdR3JxTY%FkpzaI66mnHo0_B@ zPnp^E_cAIZ_1L@nR`2S18|&03Bg7ia=&DZA5i9~3-*o|)RFs+EzOu~bsnf(ud#Y4_ z+$sCJ*z1?cyA;<1q`b)#RU!o(w9C}G7@{f|{QwloMJ&oQ22#Rq66;|R&jP!3!I(^a z47e1F@WKdAPVXJXigRhcf(qf!NLVyv_qnEDwcpG3X!*X=t5*Rm->WSe|8td0IfW96 zCAhH@%A_;y8+Ys)c1pYy_5llvZQ3@KyDUDnH<~GLHXDKapr(cHT1OS}7Wd!w+fBKD z;JbM~ziT!w3593CH0VrYyegp~>)=NEvfojs++}^PNUIF2tkQ>&a6+SZcSh>v1VTjK z6)Nu%e}u8CtfGz>9H(KPPX})0r-EIo>MzgfXeOd2km@O-ozR7LVebo~Wf`*&bIfTwT6#fWR>(=PxoZeY&nXhuIGrtW z#6clyxy+_hI#`)+Bo;!nGf~dc$XP6QLc1g7ry;dmX3UJ!Z}fV!hGa~*gA5ln7??$P zRjks%fb4aSG;UDiNKdU<0~1|DI9n)pgtudmCrwq(Mq7Df6Dey%YznhyyLv&G%FUoc zwtVawL_hC4`#xY8bgpy{yGa?hcs}6cTU)Wf*Yj!iF4gC(v(R!_l4`s(ECDzK)^7=a za9VHR38wIiP)nqrkp@t4OZNqHi0js^^SRn29Ljx=Y6hmbz%bK6p3B5qrie9}LInAV zp}7#mP99_kE#?oJbpT>1uu+-KjfxCt>df3q1o{~*J50Yzhk@Am??wPAH8$l0)wTpb zr<59YwXzRk zyHypBxjctHlKEt_{HM%E$qL#+ncFbHb2V;K64Q` zV@&cn5kTYn4Kfa4=a2ME5dg1gf+itNW_NK!h+62$zwU5Ld%RbZ$Z%ne2t{TETB+&? zC~wL#SAr;Mur@=WyoOh|(v1y@Euy?Ez;cX)R5V(4@F`mggRBQZS3N|f0<#=C;*sl$WnoVtVl;ox|)*4iXexzaOmDgwAeSJLmpN;!I5GX0{e;sdo=>#2^p`O1i(Ny zlcOLi$CLmm-)Ml=%GJ*wftE9JTgvEKoLS2i+e%BR%NU(S8rUicVVss#c|e^aVcV^h zL>ZZCr246m%TY>Hc<3lcGI(k}O2;HA^WDX+OZlft5)nEe*21oEIvXlOwC>8ikELMU zapJSG%vWNyNRhy5i}b8FFx2_A{_&dt(>3MjZp`G36wQdI^)&qg#lvckEUHn);ig8F z#}*$l$!N(bq+B_;&Wu5yu!mzzM?HU`wnE$A(LuxYtLiu%6SnGxYhDlgK49r;vT1r~ z>HaLTtzkXIuDmBNmrcyadmZ9F)T@ude8?f=?yl^IzS_Wm{84;#4rJZ38W_>vyAGbP zOyp`lO?`f`C8H@~P1MffH1@7@r!;83)cw5^2QIjp95V9xCp)B~fpV12lOoH@{}hJSv{8Oj z9L?V>+p;vzRcj+hyRA*owN^#EC96V?jv8$(mHY)TC9l|KVKKmDN))}!E*z@`*Ln@B z#ID5UFgn*HfP)D@$YY*~x7CWs%%pOXU5M6;heJ0XHjr(Mr>h}j*YFDo1 zp9>d59sVpPn)~R=hGo1|j?X8~pO^juxeA z1?bj^AHNM4mUh~=#-yZqf;O`(;7*PNuN_uCmnl(qMcaNVn>L&irhcnlVsa$jvQneH zUELZ&d$&f}a6Pi!l873dzXGHcw)$*i`3YHncqxRG>WHXG?v+Rfqv|Tz&dB19?QV$6 zq*gwTzD-Kj%CY1|w*8V^stnhKpJoVX;ILBhwI(Vyo?DA)G6FKE+*lyIont?gGG1}D zf$x>3I$esbL3%glhSlNRbR2y$u1_j;S)5M8fly)efhA{WDOgsQ%_)CWJDC+aE5&i# z)EkfAZ+`^U_H22XyFL4voCD}BnFGnw=Q1Y^7u-nZlADvllE!KA(IiGq#8q-ovSYo- zXxReLl~-+;;Nhe#6`GeDF5U?$A#F2-o%mKYV`M*cFRl2s&HF(D;QJd#&Z@yqT2!~g=XiR$ct#J~(SWKKNMNRjwcZ--%GAwb5Aak2! zzO(ygQG;!CbL%^vYsXieo}By_(Fxh4x(zG6y*L5r7lvm}Hp)E|e?r_0wo0blEZ|Fb z&nZ98Nenj)jFx8i>tHy`8!CoB%8~e%KefpY{XY%a5n;P@_kFr7MY%CCxr!xelBaAC zmkuF9oh7^rM>!r>g8?T#lF&Gn0q9C(x2yOul8k{Wl@@1w3SG+4CDI8iU8<_&etMB5 zm`D7QB6A(Ssx%eo-Aen?rN{8T$Yfy-`4CrCE1xp!Kv2RP&A0@G5r9@R%75l#mAO-EvMN*ENu{ z)i9MllB9c?dTt3cJBo~Hj+D-sP@&L8nyQ6DDM&V><>#Z}kSOjkA!ZTwB4PXw$C;4S z=(~n133;QFxfeN84L_?7?7{!-2eGtU^-Qmn@`TI3;dMC2P zNCGAz#>sdmn}`EU;Wv_?L3pm&Qnx`U#CfLuqRJ}v#g(|(D#@2m$jaFvdN2B4Nu&%@ zl7!6IWQJ%Q?T*UST@5&JLuPd~@VN}K-`Os@#$hnHh62dVgq1NJc_= zdxJxPFJpm^wt^yv%7dfS#X}=>v%*8!Zd47u_5Wa%MT&`@L0Fis6}i~MXm>WvCdbTS zRhy^OikE4cQw~wX!r^$d=Bbr7-Dp`=HPCnZzH5Tr(m5QrAXcYs(`e27QUQz5wpum+ zqq?OKhAhe?>Sg5yr~8i`FVG-?IfePlP`%@HYE9)E`qa@f^~qmJx&~W6nP&fjN`*U2 zvtbv76uauG{sM0+FxPN~Qvecu)B>5TKoIX%)mc?11g&>iZP1~G^(WW|UxwW&WKLI< zQD)?zE4USPNQWWJOyw-3((6+8X>&QzHzCrCQa4qXTk(fEBNEtkL%l%zHMANc#d_wU zh{dY@4gc$s3k6W(&Q&ynvZqR?3O`oJ!#ChJ7b}ptIYQFu@yH!wb&gJe{6NVrc}ewDYz;Qb~0e@c=a+pR^mQ( zoANg+t@D`NJJEpxeY-Jc!WU=QQT;iu9J59C!W{vnvkw6}+27?wjY%_JF@xlJyo8H8 z>Q6YFS=mqoUyF*|!y@rw?afJzQths-50`O1%a`BbWw&W6I98i;VN3I*y{J@nJSAoR zQ(Eb!8p*0aWffVN(iOhdRFPKyDY7AUtH?OiN9F-db)wV;3+7e@4UBo;g8a=WDWRzG zdLxs~M0(pWD`zs>62#XR(|lDL{~)BP6nRKetYa@;#tme#SgY~$ zvRG)>4ktIf-iuVRy}I1h`@B4um-aWpg~LpEGtazCnA24lrpI_#8n51gEUm2_*8-(? z(Z#$%6`5SX3UN>g4Hc+_I0L~!bcx)N38jTV5MvH9 z;4b64JRPLscEvhmexxriphI`b^HCIviz0)g@iH&o;pQnZbJ}O+0^H>rE)eDdA626J z)n%}23SYk(54?>ReH9FFk>Tkr5(MoR(WAmmSsq)2ArCNesH%ACRrIb(<7DfKNZ7Pg zPNJ3Hpp>^6bH&f$L$ku*cEr+}l9%R@Vk^=m@>uy?dVqkB27Tlm7hbV#^c%NTY#O6UXGTE!!{6L9!Q(YB6UX05zlE#l)(E&y&%u~qF(E|T8vSl zFTaK~ISuAM)A8Mnev5Tataj8i+UpvOfYlSp2ok#+1T9QFV-~a#1At?!&dwS}ZW~SO zP+>#nTB*>nxdM6Up!Z98X5dOnE~|rX7E}hrPZvP%01%=M z-*!eB5H!(PdQS>CAx0a#$+YY{b!ufnTTxir1cD#^b+zOHEo78nak+;2sZ>UQ)7m zH5a(m3Ah)-KVfz%T*c+5jFB=ek0iv?51$P(Sn?0#2+50F@Gun5GX5Zf2@^uoOE~xW zG{3w%1zwF>*%by`-h~_cl5Q_5G)>M3?Zz^2G@=xNKp+Jr*N7G=Oxr|;DeO{#;W8Hz zl4}l}ilWx!Xiy1J_&A-c5=sKa9_1ukzzIzt3~K03U@imgs)QLbsWE*rFhNWh&?+Gd z$vXsADpCePi39$#PJg&@x=>|HdRIHu2j##v`u z4HelSa?>*4`Jaq{5w30TcID4WVM}9=PH7H$;naX5#!{LgR|pC z%c?I}k-@;&5b8B9lz!;Q$~>fVjZpJ*`)nL7DR;xPlml9lLtqt0_*WMtjU$JD9n~D( zKKgvS0#Vf!G;u~a34=xGM`I&Biu4!Im9C(JADcRx67>5$sv`6aRo*+m$vWxRgEm;ghFuo zgiLMIe%);r%Gklj?ZX^h(ALnj84GvpqaqWr1*0!4Zm`udEemAN@_;s|*abs5>t0 zGSrd>(Jf$HPGq1-{NPpJ>1;z*I@g9Z1^$-zZ<9Of7G1|0smx^vI?Pt(L@=>5&dt?! zC*m+}Lh3E!=x0GkV?kW0tdQ5wRq&U6SJ`waxX3(< zs1IP3!ZOdN;@VY-;!Ipft_o6>r7rOuFoNYnm*`gvkx&5cqCBPweXZ#p7v)mtK?46%#I|rKGf#QcmP6rz@oziBxRcmcK+?`#|!I z6FPPYyI#gRU-LDMSQKsEWKMqBD3~R+m3bw(vI^F()lH&$)y>q>sF+B$fzZl@Vi=08 zCeuvWGD$r)XM>1`N}%H*N_kbP!DHW zQ7(Ul%}T0+)X3+?qY~FK<^OGFr6>;RY?GG z!h{m^pCT>*oK|N<4*CW{6NL9$E(D=mSrV1iA$?v<_@n|1eNs6Bgri!A$4?Q)&#YRK zy)6sJdkbB^7jMb+xS})y;G+h>I^Y!n@YeHuf#MJXl2_F#r!e=`3~mfFr@F9%RiNMY zXr2fX_vs1xBS#D=njkgD5GMo!{OFVIv|L2#mEoh;y8;iD!;t!B$&nj=#cun|rZ$lVNl46r0L&dT$T zZu)qd&uo{->srMJoe2L#9^? zO^idQYb36&Vz!Hduz!M>m{jNE7)m2;G_?iYTWg|fV%aR@7%MSIn_k)-Z+yU2Y{Z($ zir^nVV~1~=4(F#PMFymnWT#l34-uzdKQZm*1O5PkNpXoxNR`fFnFE=i$i&nxt~#pg zLl?4wc(k5SBYNm@o|JernOUK$)=*^nsLMNo>C9x-5pxyR_>OdW+EY{U@;qCpucH@8 z@jkdq#+Fet2vyNg>l`_I6{eqyWFzu#2SJlVf!7ro${#+^pY+r8)307+@4n3;*8jt_ zu}y#K{@vcb_t5?f&+p#7|KPJfB=7$43;bDuh@_go?m_-e{@lBlOyTs|z58(c{=;pWf(l0TXs%`dm^rVrA)pYnrGm1yv(77acH6sh^;`)rMe4xyvP^RqS7JbU=Tln`w_VQ zDbeM0k#l;;Yym!#eAQJ#M+GA638)8AcvXkEYRdRgRpsgOB3tCFkF82|frX=XT#i;& z1_uD&imnm2UUG?Bz5d4^LCiPgg5YbuerFQsEONNqa@=?^8%s(y2F6m<{VOd zGbEwz9~oUhzYCMPL;{CIxMgU0i-uoo95Tr&+@rs2Z9W(gJz_-XU-gOF-X1`BvPa zqO5oP?LqSL`Pawa?;RZ^hcA;CN6-I$`1s&)a%=CU`u$cv`Tp?u+vndMC+dr%y=TWi zB+tK2_MZKa{O$1B<9>4RUoVahUcUVJqvuD-;nNpS4iD7B!)NBI z``O18Pf+YyZjK;nRNd zc<<@nHwReixvJ*qR|Hyw+HYHTHI6r?H?aLe+DDjfBx+FNd4MZ13fx6Wxqds zdC*Vxjt*a{&Z^NJJy#9DoT?(vu@+VE*#T7p^PM=$qCSD&zk7Kgdh_^T?}@7IC6tz5 zr_4`2{)ppv3j}9fn%{xcKK=-udeQ-gbLoiR0SN2+Hlk{PAbf*lH|dgu+}SVBp61J} z)3?9F&%$oRUv!~jA>8i)+Gs|fz)c15cj(FtN1ncQJS&&EweYZ(X}%~=vXcpccC9K_ zUF)nx7&?t{1oN`en&tUw0Saks$zfOO1$+i(o>D98rWwY5lY6Y~CxK3)kIPgm*C_Y^ z^mIzEa1$z@&rurT)xzH*& zh?h6@wt#!*)m9yJER%ZqxYJ!@x8f!3Ct^swh9u9nwwL8JM~hk4Ou+7yDuFIwJ*LKf zBKz03GrVhu&{Tg^AO5|kgtc1A64H%Y5~e$7Wrz#ZaJgC+^lEbwCo?Id3KMlp#gdGh z47^MMnFer~PYf4yS%!eW$vrY)BHFnE=0COa^l~4;Nabu|VusGsOM>lQlh$FaJ+lcJ zL1R0^H>u<6L09~x4;_qs#(g*|NdREgO6nR{zcAb>Ei;XESuIqj?dJWN+xx^^yMtlE=*+iycm!389BtoDDEqPX-g5j z5g$0~5pi0Uaqmc5X($3m?wK?xpwLksr1)YR)Cb^};RD`=VJ+MXDINFf zo%36EB?<_zZ;l&Fl0b={EPl3xe3Cm8k{Z|36I8XsRQGzd-GkRM-~{t^48Vd8yP?zD zB!s~3zxG{lNh}T{V0?A?>JrVt79cmQ_sAARXEK6W5L;emW@`Ea#nfs>(gxku9XS{Y zV`E+8y?qTUcU`OJaASW716Ii?Ta4XvprgvoX{y1~d+P8*;X^wspe6%1!am~aBcpY} zkhm9vj8@ZwT0a%1fWxoq0NZ7Ofd;uW>BBstfcI)V@z{5~quS(cWNZRa^B?HPuq1Ol zMw%f%s!CM`%-56$Csrpp%1nf`YVl~nr~uoF1=um#GN-~%JFGC6JPrBYbw=2ib*6gixDSWIsXe3p)_2F6RHFM7$JnE<*9H zC}ZEo8xndrCim|>>_b+_8Hd}$J}2K=ty8yGwi4CDm8?jK8>1Y`lTO?0Vd4qN5H`e+ zH?@o|zYWeT;}U1ZX`kY-bJn!mN0bJa;19F5V zEG%aVOs9ZAb?~{q{G$wy6IU$LSVl1SOrfAzwfU%>0cPef9qmzu6v|~4o=FZvo0R1n zM7H

    L9U*%RF}AS$KlTL@a(wHTZM4lke>GSP77X&q_KpX@508k&O`=qs@kB_$cn^ z^n9G2h!cVf%shV8^L1#L{?c6YQhE?Xd-HeAa8ww@Nw9H%Be>M140K*h@x<-ZQoW+z zy~TMQ4;kfo2Jjdv)~Re$7zMOK+t6t&8lB*jce!Mcd4^{r0@i1HolyvCkGDIRo zG<9KMhK;9)2IlZ2z8cwmA7>m8447Iv1sZ+bfK2BJ4-s5Gso~slux3=tiq@>Yjif6W zn43&5ZO&3BB$Ap=3Ln<1^iUM<1FD9}n424<$8k9#uVlBc;f*WoJy$VMRY-2w<|0*B z3!XyMv0ZarRQpA}jKRVg5f6*VJ$8{z-qde0uwZeVfyha0a#mq!n8yX-q%gsEDmTra zOT4!BABuc34)&}MgBI++z89Mm?qMTuaD=ACxS;JA-9Ka*9HB@@mLePZ^j;@Vaq1l! zHTbmX%MDYK1j+c~3L4{YyFS?%)r&*aeQ{U5=QCa-AIFG7@1QJXmz?iN>nnQpHagFW zg=L+BTgEwMTb6zdQjm`c+K@{6btKEC)tkn9)yQyp#Al9x!B-$W7kd)h*FN{?M_eOc zH(%!lus&?n80Ry6DMP89wS}?eqFiYvq80UQET`DY(&Raat{0#)ks)LD3oaUE*?JE6 z6Rl}9+9m&j*fAY$9@BPT_h*yvNg&Jkb==r;sdpSl3IIK8=W-m z`^}P-XQQPOwbXe|Dw2A>Pak^rff(?Fu8@AHQT%IQod%sVm2ZXZ`$W&8S$PZa8Y~*c$VBPTNjU(Qg|nG@OIv1P%g1v1#kJ${CRx*|6@;d(I3CDaWq4yFpu#l` zy!Ju5FLDZ3#-s_zWrr|*L#bgMQvE|U&lrgsse|+*8Z?dq!-kTAh9;E4DCGQVz&)@S zy#W)u5~@yCOZW3+H9K7`CY8f(l0c9FweE^Oq9IQ)kbY+I8cB_&=~vej6=~hQ!Vk?p zGp9=A^l_354=9I6Q~*x6oIW$P6AVLe7=<((8)uMgoiEL4Jq*d6I~1OB=Z?2CoP-!A zj#`MHHW7n;_|iu0Gg26##!|cwo+Fo(<)MT@KD19qhPT)1q-M{&?;pOWZrj5{VtjCKtb(|Ynct^Q++uDoF?|X)=M~}GV zGH{id?>-?%U4e6AKzhcA){Z}!28&vwP>Y4nSsWv$zb2H9d=J6p%?akzPKY+rculi+ z?!c0TO#GKdf4e|1K)fy>6d8d5I!S==#g6ZkhvG^sUlUfts8~T=S2!PBDmuy4W`Z#M zMlioP`6!{F(n$a6N~ES@0wL*J3`BKamT%V52Qx^Xgw*NI@He~6*SP|Sl5mX+P*%(L zSpnId-}eHbeuj*fJg@3hm-EW5bgcKGyQFItTjT&Dz;V@V>z$!C+TcJT)-yuRXgQ9M z`(!l;zX68>;cuW5hO|U-$-d$q#ps-Fa#~yj3$CCAG=O;~6`>E15C>p$lbb`r1TgTkmrPQTlPySB+0qW7aA=e>kyVvs0B* zR8{;-yw8;b{Jc(A{b~m%^L2w06%4~O`*E#xW5?`E8Y>sH zbW){8F4hVkP}i7;UeC>>8;Q_<>I05Dl@AESBhmuC*`OKxK0rHlXW|0Es2*`GM)w38 zn`RDFK47TzG-`cWiH22jwxQ0&JO$(fvSFF(#l_gx!Ug*JT3#5O8D z@IP+wKW^|p*5Q9J{^R9Uw?;kw$Gtz_+kW8g|9k4`XE*pCH~1en_#Zd;A2;|P|Cab4 z`rtvl2k#jsjFM3(1Vk^2Xmo9v7jxkvzdM=!W~@dNpyCy~?Kp}2V$kc1RZh^s=x+oj z^<zW}TpVo)G19xDLy9#i5(wS`to8(R|35+`x!5pEU%H^zX{PC+5uSN0~bkbvNs zv%mlriN4BcA09q=6!%^ugu3`3|5G!`!({K#etWF=AmKqI(}9!a0Abg4q76q8N~@H= z%SWm`ZRc<>YY~Uht@os4L`JiCYpaAPnjP0+(ydcNGc45+R)HcEmw*s5bh1QH&H6|S zS^*FR`^-j|@I;+oD-(am2C|5K?5z{iur!KZ?Ak~puP6pg*=Dp_h(d%KP$w*A#PtmD zWq^4K9T@(|klEhQ=`0qgt&QUs!-j4*44V^{H9&mGtjpl`rjuNnv?>1J3|g=cpAm?j`KxX`EQ+7Z^8Nn&`a&coP zIa7r0pdwKKHs=JVAhKkl>eLJR0Cz9PDm^a?&Vj>2vI&ah=-_`MRy6k5QW81>VZe0{ zwHxWVcFW|Q2ZgB1B706Iqfo^nh-n10-Eb213{p<5S}5?n1RmtsjH#MaYg9f8K2^i6 zV(JJ&pkhwXE7ap?Cz5m#1UtGhw|6LNZpVwe(+9{dfm;xsht3DoM^$alD*|VO^SOFZ z^C@sG_gi?PK7RGu|CD&F`!PM!fFjQ4HtnhXoSt?3Pi=}m@vTk#7V9@>h!x+%lbVmc zT!NyIe6yyoAh~E2_I*u7!B%$b30~J!;}Uap&iI|Gz=z4<47V6!yz9^xKV6gYupuTl zp7?uT?cGWUr6&B;9=n(gF>0{a=}`!kNt<<%w~TZyL>)lMz5&s+#*F`TUQW=dhLR`Z z;nX5ehtC=z6(a~;Z}Y_xqqixa30#d;{eY0(7ycl9w=(b$23G^=tAKfUFbM{*yajq- zj&RzXT#tI7o|8SJ@u>ydLW>=-`yc^M5CdrPJD|VU2rtzZgN+lP&%rm!EY!uhpWt)F z9}E97e^M2lfR-aRuYnY=xxaL`2&G!fRIlQE;UDs8c*@twIA;6$sq33F@<5Im+!@TMqq()*eqh|mNn_@f%p ztL@i8tl=Tp`eQ!ofgk@!Q5+c|I|ytnGfyreiLh`oC__zTw5dQl-HT$q zXiNG-FXGX@S9f4|kJE8?=e2JYHYw@+aBxJ`pgN*xR%}sL|AY*Ck-IFLt%k^I2sf>d zO2BNf4AP)B@NftE?o8b{Tl!f2kIAj1(+qm~1Wqn-+gF~Gu**@QRqa~{9C%T+joTx(%H#-AyZj9) zRA!l4Ry>-LJxn8{e(no^o*a^S&Eq^cPs)jVo8{~s=la@5=P#a{s|t@%&s49ZhRD*k zk1exwRx4vWnT<+&jFSr_sk|wHk~kn!N%%;(ZR;oSIV~rEDqbCOHsL%tQ=h1-%xvcP z;qpmMUac2-GRaRtFLIi6i!@K2oxt93bgkBotGzU2wmL@So_}r#i*9I zo4m}LA85{pH@G@iLcr13bp%cOj%98mf4eMpIqtgt2FyNg&2q#`!V+tl#-5$<6&BxHE)bI+uZ(YeMX{Y9;^p zmB8~4)6^csogp>vB0S2XESCdz-60?p_iHy~w9x>b4`VZN7H!+#0{l z7{cR>0Y#uYVf=UmWz88yvs^)EBo|1%^GzIX_Q$rKF?tD`XAS>to~n?j>TaKL!fL*5 zHW63j{j!$8A`lk11Dn7rkk#%a`%Y%!NHl=j(WE6JQCaJ|V8Hb_8#c9|6H)7|lXw}5 zJs6Y@`Os$hBm`>_E%7%EGoj?Yrg;D;-4Mk?nriu$Yq^|7q)1H^ydr6Ht<2v67+e@- z><>T2UTtiB&3LU8YsT!@p_J4KQ7(gUBFg?F?UCzaw-H09SbFI3rZgIS>xn@&m`UC2X$ z;em^(p!8-qL2^1m6A^6^)k$*)DwdcEn1|p7(b-y2Go!91AO<~+IG~O4IE8yd(@9YlqkJ&J4n}dYLiX@?DDq-aF3XWRL=>CY10V0jabGl?^l1rdT|g3=YTp4DVj>?qL-kQ=E(+z}zL zsbY)V$<=P`y1A${GpTZQrp5`XG*@$w(eWCFQ3MgiES#d$bKl_B?rQ&dm1{?zi|o?X zLgJkou=p)R0Z~M7&x0EVnV({+3loehGNl>~yz15f5jKZDeh4ZFh#Bg!p+O3O1x_-s z2hUe1tEPxK%Lqea8+P10~{BhU=;%lubdB_GXu1-Rfoow_)~- zacAs5t2$R*<5RU!iVv)@Up}L$3a-0Ykm0_rISY$!d{LsH1!>*9IWc{d~X)9UH zuN5wHh@k1Bex_Qi_T$7KawkH7>V25gmLI;_afd~np@{GUlac+fF;8yBa%@=GJVo_C2 zr95=c&5#3c+b}yF9X@j-%G9B8MqAg0E~Twzs}*TS$FOE1RF}`Q3Zskk8g%?1s%T!G z_4@!SiR^=Vsy8ba!t;lef;{kQ9m6&FfL&`y-Oy&%XrEq3_o6`m(d%+=OA= z#DCqyfBiP%zy7j)6aRG+{}sl6kwedwBEXvCzaHFw_~&gu{_C>`H~F7$;=gX$Oszo;e^G$8!X&cawRcoI`n-Kon8&4-rB3r)s}@HvzA$%b$U*XHc z+1p|nDRfj$B2T}`rje)n<)mCK;?EGPf0PPZ0_oQ4RLOWn78Ye9i*GI}wnXC#F@@%D< zkxmEeaZK7=NW-Dv7rK#N*EHgLl&Dg1ofN%ul4a>fiu%xY2IEpqy7sg)@{&Q6@kYEi!nhv_qQ6eWfdx^UdfEh6U3SIxeaa2bF1}z$Ufl&S% zJBS9K8)eYgaLA(`4iiSZHEr(eyyZ|Qc@c`7Sqx_6qyd&rf-HD)--bHAkPz?iY%7)( zcOB28NqJU`IB18zvyi<_sRzP96p6}*%}Y#8pH6E%M2{_?KVuj>qc&{;kKi6TYW+$9OY8#Mrd^8Bxvvxv3b5RVYUoCCK>IcCnqo zra>!@vhg0jjJoXeZW2LS{H(5C*J_TG^sHPSYL=0Y*=g}H(~(BHHu>HRbAipy9*o54 z#1YapKk3aBgn$K+UxQ*iSmbBuf~KTKi2YP!>MlCnSKC{Eef`tj2mO0@fA0N<6Hn!* zXLRza;IX7?odT{c@ATLvcTx!HUZhk?oGW^qp48D5;})qD`59%)48yV6ufj%PE4i9- zja8VgvKs<^l1l@y4+x$~9zWF^rmq76b1uzso)tQZYCyWPNqK^teRQ6SlS7vQ z!wbj>LiYdLm z@4u$U51hxv=ncK1muZ?XhXrq-vwXa>qx$tgY!BSSdJEA^D{gtW7s(|1SE0D;X%2wOaB4vpD(i|392czkaQ*uB`1nP#_u^1`-|O_4lS^DQ z%_mq0Qi6^38A4iwh5dSxomJ^SO30@(#30)lIFO8+PQib!^2OzVx`zfMZB1h7Dz;mY zia-!Unxr_oRM&wo2dAPdF$*r$nS7BvNMuCLtE~sG!L-}C-P!TI{vj$1;0yU z99yf?^Ihk+UZeMLo6hTLc%RNgWO;XzO;5&IGTlk0DH%xZ9K)qwJ%y|k;%Q%Zu(yW9 zPA&(<*g`-WI)f=vZzP#rRBZJ{E`E`pRORT6n%n9;Ta4AWyEF&-*WUFI=tY$l)d095 zPNLcmy};0Ws13a&M!?4jf2~t#eE*Ue^C{|3FkrJ3u`7Dd`&GXzAwEK}?#|L=A;AUz zpNHG(d;+~rW!$K6X5kC9YDIP4#^Hb_!6PH&QanFhy%JI915GT@eFL7m)7p(dJB+{* zL`v~`0q`hyhW?2YF1>T(C(O!F0{dWfmJ~;U9%VX?$xs#^)R+QAab28STXmcL$GgrD zbG7@5e|lZF583;dYuLcknMXM@KX#92fC&PwfT1i-9^ovwYQd@LbIq^)c>na-01vv=ox20sUe7QL5D{ z23%bjyK^!|hSg|k=i1`Rk&a(|eBL6J+leV=>ZpOaNYSaGd$-qn|G^p#0IO`(AYE8F z?QhJJ3m%8#-5QSZzO&M?r$QJe#Gz%8_18mg!1bkDk1H0sa=urgp7G`^!)9p2B5(sm z4!_v3x7pOy)lXFFOKy?zz#yWUvCU>DP@2*8$Wgvt?Q(=};A^i&e5=8z&)>(@=1TV$ zn2gPDFV01M{Wf5UrVD)XA?Jhg*TDB88&^$&xS{xa z@pf{A7}!Y8ov%7*JXJCXxRG02Eeil=Uz?kxt=ik<>V*;y@H+KXCz=$U+xDuCxRdHJ zKumu)1VS1Iq13&YQOp;HdIf>y<|gP|0_*R8g#CfFb62+R@4ODbVSi5eU`JIJ$&kLt z3FZi*L+PHg+DTUCo`e5FcUGx)&D>3#-5sT=$YshjNckhxMFi-kO5Z|&aMkVgq8Rn| zh-)}-qC9w$!K!Jh*&J6JNc&To4jIYWHacQ_OJ2AA8DsTt1YekjTp2T^AWyz~eFw^| zpLFot;p3mTe$sJG>X%zdR}FJf2hl{QFm+vd7CA-z&AsEdaD;blXOkw z9-)7is4~UOLC@r#^diTYF8$rnlPexqY+*DfRzDf?T-!rT?Wdvr?ns?y1WCE^;daI2 ztxnVY|GHo9biaJ@IZu${?q4{%=dIqC@R}znceclRsE6A^s)Y11e_ zZ5rdJU;c-vtrv<6b^3EybUP=ZcHO@d!}}=L@Te(PhwXesB)DbY-jeLsPKPSw6tHh@ zg^dVN0!-zzoN%EAbd$kPy0%4kpc+-RM!|tEgARJKiw^CDVcL%NdZ=l!L&7jXC}$#Q zy$R>%(JA-#v}~s-yufi+=Q2jy)G#xiwn;a8Rci36`?_45U}p6-L)C1lYuTkfe_{?J zSG(!RpzHsAwxDY|Vt%1Zk*6_xzuVI7E8dkNinOch#x~a#g_aH?MxZ{;h_uyXGi@1x z6hI=NQLkCl6(KjHeiGS7JpyJ8Oc$HU?bw;Vi7x|RG(A8^XpfA?IY_QqN2j@clmow~ z-i_<*^b@D{;G_^MK-I>Vq18#UiPRr;i@O@zl~vvF-QO4Az2Umdbs6j7*JQhLAKmcX zUytuP>u~Lix6XO^YP{F0?S}o{h`qm420S84F7jW8`Fb1ahX4M0{MTQK>u14k1WETQ zd>5;TDZFdA&)yh7bUCF68kZ9{U`4V~8+-pS|@Ot_9$G~3j_0;X929& z_@Oa~cfb0)kAX0|cOUkmJ_z0IQ z!HG#-D>(!^6N(ShtJ96gkfFM6I1?N~g=fz1v9#90tXmFSb`!icQ2MI*kRTle`5_gbm1tP9? zs$ceSQAZv)Z2|orKDIt#In2W~pEx+TzXvzO?8}{3+19`Iw*Id=9)29W{?pDCRSq?3 z=l9b@98<)GP9K0PrB^1!w*g_M*Qc<+=BlQHsLf%trYT@8bqzHfr&y#xcTh8vu&n@o z*UV%w{s0qJjCXbaKIC-OHPcQ!aJJ}1+Jz`~#8nPoSy9aq?6NI%VVxCIg#3Z1tiE-@ zjIp#U@vd-qQ1olX%vX#2m*!=XS9P;5dx||d?5bDGuhxpTL_20WcQL_dvlfnuu-mNs z@?Nj?_WUf|o}SDn7a)aOE_r!(BaTyjLk_#{aG06c4)^0K(=~tUwis=pMoNjrf;$i? zYj%u-L{RFRVN#72tCJJ8UK%!{WYps-E5->|?e3+M9D)N)`mxES0G0nA&%-r!x;Si; z@|(d9PK$S1H#*Rs@3onzWR@#TDyzNKbV=sQt12JpfbLecL7bi`K&KWx)qcDJP8#F-01(Zj1*BEDwU;bvvKm{$uq;C;6k|GwQ+*Vd%-9RADm8 zphqToVs>tibI5Ey-qO~GfQNdMlCI`s;Fe)+(*+zb`i{3FE+U@rL>(@ z4jQbVRF2_|1tYhaQizKAQ!<5UjQJ$H9O#Lh@;rW}=Mkb2I*k%$i*Cz+p!e?bx~{s| z+|k8$+fd~76_Xc-{6YV{A(=P+QGbdGWq#>XNXR{USL)s;zfS*PXSEqJzED zBUbnzsz--)NBiht{mL)Q$}jwthx$7$H+t9#Oz?m51Vc^E^y1j~X)LM;rk7v)lZ%hT z84hNdrgA>%mM8z{#eKc~vA|wYU$dmR-9rnMtaFZ8pl5E3MCZRd2+q*;t9z4Qf*Cq? zdFP5CFI*QoSuZ-r&boHGU9S+EfxRS-`z1gmEpsK6<+EyqXaq(|;S;r9J?b{ZrDQ`S zcMb@JkLwu>s!6%52raQQvOs<=98w^xm@jwHG_@1tUbnWNk#F>+8rAw1%Y14o#pKpb z4x!L^PT%yCpTckD{GuLId*DFmKo@6-(lA(v;P%cC4~Aji`RJX!(z9|->fm!FQu z;K5T$&1h2!IL#PLe7d9Cin}lq0tq<-<$~(Mwy}vU@EV~mwDg3`|M=t{J<*z7_2e@R znT}YF@Z>&!!(Qm>3EM(Jv%@t%loxlGtNMr z7GtS_jaL-)5@h{3R7GP4WuU3I*Q(+g1OwYi4MEVRGMe3*Zi;>a12w;;sP%W|qt~L} zylf3~qI+&un5Rc8|62_Sh#_!DxyWTYZeu?{Yj~#9aBtbf@9-HM*6M%Mr=X7`oW2xR z;a5-ROSVidi(I{?^v|FjWer}o<@E6Rjw}0m*6x2t@u?det)pzF#~ln z<`saa8X!+ZQO#yBqD)&n6ZIDiTy0V%V&G4Up!!8VD)P4|u_TY5>iSh*G54hY{o=d; zZ=ac(6m^OtC-Qm(GcYdKF0GdmRlMnYHTFoUEU0W*&Pj8PWFUh^h-*c)gy4n-zU*^^ zTI?*5|0SJ)5+GC={Bc>nQ34JAsOnpGnzV@vM24D!k_M^@bcqXsp#t9l__61`o};$y zbW&!^?%aWV#n-6U+QpiE)OhMIFw=C~e@6q*4rGgL8I*=`>9S2aOVf+K*imbhbb0|u zFK3fhh$E-xvt{bDHmKssvJBL-8ncC7`*B$G6y{5vxheeR`dhox!Y%r`L9XNrcbflX zmdk6jX{t4YaoW-21?;QKL3RorN6mw_gt5u5G*yE%V2+Ke64gW>#)9E+BqFxi_YHHsho(ie+NR zilXINejz}X6Pk_C-ZHRrY$(K=Yi~bC#-YImG1W4jK@#4%vC->U*xLeMx`LbMXhF#^ z%GJWqcXZabP_~mbRe8<>IRiXaiBmmZaXuE%ZQ}xvpBvp8i&LkXk_n5@tZDY(Vp$gC zX9Qi-Lj%H5r<9Z3y2WHQuMAsQ^JPt5kE?KD@-3NP237L9Y0la;b@t6#_U)PBomh)} zzKEnB(bn6~4ZlX}On%zNntz644S!Sr{>)R1zw?y*%u7$t=;xom=%i%0q~^j?neP%i zwMQyhI8|fxH0uv*N~O}xl2eVcz)O4prYMJf=u$OCbIrlZ(jRy4$+LJ7xKPn6!0R{<6Y=jlhAOonc|@|P(yE47SNx=(&&vY2%m@G zn&;tL3Q?7_;dPKIvCKn{(B~f>zk8)Be+^E}SiI5G%WuIHj|geHy7h9}+C_7l6^rhd z?A7!l4V#v-8M}VG%%|C0-TQKxa}ZJx;cJL160XGH>Y%?jzQ2d3kSh=bnTv7;8RI}B zetxOda;a%S)kZu+Ctzd6R{^0;C;2D??_9OR^|d>HH!nG_29VT39X}M`&FTB}L#l-$ zzk#dgBbcGZrK$7KBpj<&bJXaal*{vE2mx&9IXeXALep zf_%*KA=0IzoTYfw1?cOywopBQDfp-=L=Sk&4F6< z#yk3K<-1}cq3WQ0dhNZ01|V{f=MsoIR|m;*058Hj2zLWKr$B?--B19tv`xgZs{|_i z;pc>F-u>yWCtCHY_84T~DX)WMMh4jYvWUCe21Q|_z+ z4X5e~2ke&K#Lpi+`ARg-XX7q?+G~?=i6U;PKrE$F{Thux?=|$%a=8?)ph?n$>7OkY) znP%@GvPVx(@*_{ij~zg_A(>losS57^v*d1P4XzQ+zy=D=u>CnUu2r323I@5=R*5bC zaRIJ$=%feA-d@{Vzvo{krWqG+*J=QeEt!el@Dy@s4r`{%|0nADPwl}2`iV{^_#OU@ zUHfZ{ZY)37j8e5`?}|p$Zf3`kDuwV~S6iHUDWTDvJxu&8L3%IO;bJCU~N5m)`jDE;W5LoOG$eEBl9iUT6Df|C&&5de8%z|+R8d` z`Bfz|@Pi@v0rcnKRNR!+8=H{TJR%u%iq0D9gDJ>Fl>1xzy7;HcueR2=!9f3|+9#vc zq{tSr)4K7x28*j_HgwjX>Vt0A;j8-0gAc5r)~mgjy94{T_5Zu^|Gn}5z48CO@&8@t z|EsPES8@Ga@Be%6?q?4qFTnl(=X($D-T43B`2XJc|K9lj-uVCid-?zRF1`FaUU15C zQkf@=TWURmF>25J3YHIY61I=%?6Q8qu9NQ_{n&)F=r`JqE0r02-^AVbE`z!@U5Sl% z%qsg!r9T^h{=&34c%*JG`*gnAZk^cTX11_cRBXv4 z+F!4LHUaHx?Q*oJf7{;xD3W`0h=fE6M)j!#i;Q`eh~IhU^g^7Ms-E$HpUNe{b{MYa z_qafq$B$kQ0Fx3GWu$_?rgd!F!j+bLlkRUo6{iK-V#9>++!pA7Ty=GGeqFs-@xn%9 zrA8BA_qauY^2oz=05n-~k1_&Bs|nSa(vHYV3D|^sdnp_>%&liY{|> z?Y>0s?**BY(QI-T{>o>7Yydx%vra@wZI=tf4V;>1C6t@NU#DQC!yn+UZTL$a>Za<` z(^%bX*^6ik4WjHLH3J4umK&Eo68map4wW!Is|wHyK2|q??pXcRbKLC!6ir=ADq{?K z6H~{p<}it=^Z6UKsFgYmC*!W?8#WlL36YQ(&2`$Z8>;kCHkzxnU)NT7W;~JJ^mRZ| z;LhSz3}s}6rl3>vyqs@bGn83h^I%Z<)6h@eI;J`^1yytk;B)DRiMz8aB{yB$Ldmv! z>`;S7=>jlafY>O6Wxgnv<*1x+@Crc1Qf6h|@dEg_B1dI(*GEh9I8mQqa7y1mPpUdE z@iYAi1K#V=s}lpWkgNZ+;Q;Tvilv-pqr45MAN#Uo)7)a>sq3qN#5>lBG57*!2SdSS zbbPAPi~MwF2#45eSE&c6B&Cm&6}WwA z$V6oI<65Z1J;V_OOh;P98RdbmFml3MLGo5Z=p(FDVDTOXU+d10;|6+MC44%J31!=s zW<=J<{F?Xc5Q^ZTFxFa-9oQi1%MvgzNyfliqZkl6Fr~?3S_@RV42S4cHst=!GmNVV z2}if<%{+bYddH$#ML#*ofnK4hRJ8^C5R%cHl7&zhywHnIz15qpJd1YX%GNea1EdgrUAm8ItVw4AITi3CwhX9YO!nBBYX$cJkG%KsfL~^dDyEP)D{+ z>67kLc8?*4A0`zm?~Lvskt4Gn?T~BnK()B!v_Y8*o@*mC|jQz)o4**T}^yc zLvyP2J1yR!2*>R?yvk*R=afLZj$^0=(HrW=er;XoHA*(zbBI|X2T^S$su$|dSx(H)R*#zB)%wyCw%ZWTMXu9RZ#tH z2%G6j6)ZBv_!3*%B^3Y^R(ueV8nLa)nQ99D2X=%Xs)=4EaIZwhY;SV4Q)Mf&py-*} zoCXq|XY*_Znma^ZZ@F!$NJVJvv%Fjp-NShT%TIhMv*-CKMxGRM?Rmr`0fBg{7)MS%qT7d=M)TE1Lb3V zmX^5UzT@vYI>!M>^>pfTKitg?%}DhL#Cy`7F|xU?RnAqFgMF!a_X^K-y1UKt3qZt! zP^<>M*=-=BXlTMxV2^Jv0O)ox*W0y1!GJ$c4wnOTk;PFW~%CL4U$;jH^ zuq0YheE#GTZoB9fN{VreTRO`qu>qZ-z==pB!Ct4StnQGLzKA%4z8nrH92Vt-<0;5T zldgyibm+!#kumUGjF86#LeJ{#TrY!jNQ_IQhNW9orH;f{pAlAKSKPGCx(0EwFrtjC zi0X95xwa7_9XxnXl!Qr857Uy4r)i0i83|n4ovC8E7G$k?2}t$@df1()$-sEvs+{Jq zYtU9(AjBt0rVD(fic2^0+vd*E!EnT*5oI=nh7Is%lSeXUdVqsxZ8x8>>cSpLw!d_6 z#X76i8h}2rk}jBp5=^&PZy5Zv(?>0+Qzyu)gK;_XO2Ffe>#1tKtXD#d%5=_0%&njv zb@jXEq&krrRDYm6u6&>=7Zb0Gsx5J;C_ENPAZph?rl6}D=iLr^ogI-&H$$oM42KL_v2ZqmbmSDSD72lr5-hkeJ}hViicA%tY>c&}KZbsld@ zsl21Sn%zW#(TE2)>SU>|^V^yYC_QfMK;+Y_jl-+A-7sXKuKcCf0Q+H_F`AJ-_$!O{ z!4DvUb*W?Og8KT#NEU-mapXN$UyPrq8^mgoi}z}3=^0F__!#uZ98IbZQ}e8AdJxh# z&rbd%(uK;oztGhik+@zhA4`EsY&IG0WSU>58Uqy+TpA^D4M4s zdV%^b+9;)%V9OkkAbELM@^zzYv+x`}mDdW2uuSv7exYv=&HvjI-=c|p&4pQ1wRfsR6ArvBt8`Y=p@S7^} z4INeuh;PVnAJjaT zZZ10cPG#^5&B54$1w>a`!(E^^eXXvHt!D3YpD%V z8LJgiMD#P^*?MsDWwbG&mT>EIV;hwPJJ3BqgcaBN39XLc(t%XPN95A2^`J>wWu4<)pcCvkrApUgu_t44|M6Dy5pe3zc52nSxl zrKH=@7zCZ35d-)ub;adxY?9JmG~c$!!5QR%l(MZcA}4=>U`mtuv?ftwbkAt*o$5C5 zUy;spCra~0rLQqEH>J?I>^D_FT!+t0v3lK_T_7XJOfFBIciqjnUR!|^U(|vDQGOZV z1+n?>CwlpG63&`Yp6W_`sej?EB4DW&>E~Ms3q+v!HTo2MlN!`G@^`_v=t$EG7e&Zr<$Ik`k$VhEtKQgk z#@*{bQ@A-VgKuO-IPQNpdG$JcIRLhDY%|2vVVa(D4&zoSfgO)T&e5P%8uM%+G@WA| zJ3tDN{A~fQvUXi6azLcDuWO_#F{cIv6Z`|TFRR&@^l5L4{GuY(5;XK*t-}jCNFP^_V1b~UXCk@OT z1T+{|3Zv|%yR?~$=s(&7Bs4z}iO}q`aEryO zj&Q^{j|&N3TL*wg*Hm7Aj*Dr;k;Nv3sT|yH5!i<*`a+W}>Kk1PUY$Wn@j%?gh7sbN z^dmct1@J1CI;Z8_*YG&!x(`M$z+$9v6;*GhK$qxcH(sc~9l>=Xb6OdVy`y#F0 z6!XDF-%NJS4fu=ao815KLcjX^57<4Td%q?aq$~QetD$QBaw) z01WHnOJh@?L9nWoCJ4Do2Nt{bI-nPOxAE-6gQ%g{P@p@dmdOvE9}RedcWMP(xtk3M z4QRf=X{u}K$b`v^`=LOchx(J64z4|k+VqTFx}4s%=~Hyq2^K3jEIOcPi9@2;QpDD; zq0-^rs9n>+Z+>zKOAaW{5IoRPoEp4qPgjUQtH-3R`TzAg+BJyzL$Tw(IAI}4Gg_>m zAgar>nVCf9#&eCuEtHq1?Wk=1BI1d21bb=9UJN~ON5PcA98 zBps9-bJq2bg}TeC5LxPaTodirjfoFjU9DVWB+gx$T{VOGJO9XvaZBH)Oa~fqJ-}tK zNVk__ykoankL;HR4*t(oxda5Baxs>r@xAD`{;^pOa4$P;MF64Ii*g?S9Ez0tZeF>EA|1j$usXvqj(#$n(7mReYh{kNh*LMTUa*>((G3Z@M@U!MH0W z<9?zy#S7v=2fm@f88OaJurX+RbQn4bzBtoNh)X*GM5(r;Zks5j{Xq--2ScK1$qUq~3_;+^=F@uMlf7Acw=4 z@%A|c1Lk8uD{_E7EC7R6oEjIY;p-j8qPr;aw+#JZg+fuUK|bZ%9AcdiR;hIIaSX-Z z5$yaa`UX`xJlA>v)*5=5Axi(vI%|Hj-AZR8wL=2g8Uy1ZTX$a0!A-Oa$=r6^#G-KZ zpHgJ2+X~N7`-bWinroAJuvB1H#dM=1Xfkp}y6huDb|4B4$aNmomod_lY#7!LVU6NVhnq$;#1a$l3EySVGo6rJAMpFu|?)KaOf#x3FHPPys1vDVzw10D%G$2(=v!`%VwRL2WpE1%Zm{9C_UW72)ph zjW}X-!CyAez@jXdyzQfhO)Z#)PYY0y-f`DQ4;ql@>J%XRRaAr*k=A<=8nq9jJ4KIh z_uA%Un;C%fOkYi)NNc5CY~d{-B% z_pdhLT{xxw!Q?Dg(<*T_e**5PbJDvNtnqZBj~#HqWkXIVEaNV1L|g}TNj@;nuvSX< z9i$MHL2()N^J`xMvijXu)^Qa+bgN)w2R9!XKhjNz)Ib;F75yStrS_fxY46Y{d>4Q0 zMj~;-ggq^!IgQHEfv-Cn*UOjjD%MG5(z9d ztGbi44ARgWlZh~vMAb0n)E9NN)ptt;a#Z<@o1PGsXeP!v#2Hj-?nym}I9|6fS+Ked zkE(j*s6=3kt3Wrk=d{#A#tRTTdj+ff`udboYmBP(jka9xs6OhddT^mxx9L`Epv`KO z)*I`kTWL4j8QkA@?`*b*JU%9sKMj54^@k~Ca2%!wI@ax|C!h?z6wx&{ z(8@?Xu22$Ddt)#YN0AWvcvLL8&4@=P0WV^Z%@?_vbj0AwG0uOa9RbvvEgQvDzNs8g zBsj?X_GA4aISa$*JL}!SZD5HL7}F$HSTIf$Ku(jd^aUafDuF0X-xb_AWonnlNCzOV z>;Rq*2Iysa*7JLzUu!%&bQuDN3=;3pdH4u zTmM!ZSgogdWSCuDh$v+PxAjO-fIDt$<5Wk=(`LAMjTJGwMR4M%RF96D3Ek`~4 zP0`jg$ed0+4FVWpIqB!F=uuxc9oqXBmo)LJCMw4Z~o;u0t)NX4h@vcu=g)#qBra zMN7Mar_Tx?8`sQ?Fiuqv(n?{-7w0*nme!;kC@s)!dL=js)$~q?Iv)Z|06!cN){3^( zvD+QOxgeEl+-;-5HsEcFbu3raRU>gdIAIFI)%h7XH3I^=2H6(e=~=5JZ{)jfq8|Hh zBMvC2`Th9#b@6Z>74ux^^irLBu=SYP!j*j6MQ5o{v9X4NkKi+%kAukoQDbThDZdcK zV(;Bv$-E%7NDPgnaa9tqWmD`|*H2hvVH3q6)iCAKu98j56&bI{#9wK|W+z>S2C`d# zts^_jiuIrs_kWdTqoKJg2Oa`fWh$qWGK;lurw#T?GRaSuKHYW%XG5qioL9)otcR3VgBWc5=J}edfwuH)%DM|9TVqn0=)I5h09A9XnyGESdTF?tGK7b5V z%(7+95I2632FU+h%pB-$@>nLV5@v(YDJyi5u6Cl!63k}W^Ae@pmTk%84s0$=no`c!Y^QYAW^WV|dIe>Mr=D3Koy~zF5QbkCsMgkSP z9IcVTuP80rX6nVlW)W|L^@une#$b19r_R;sUQ4#j`fQSQ6BC=9Fzcf|(;P4jk%d&l zVlt7NjJ7q-lv+=~24qnQpc}R_bXmB{A*-gSZL&Ij;E9BFrI~NtpLLUb z1OycJN;qw3ti`5=nHTZ3jAGv)|Bk@iul25If%xweny^4vBuMCyODZj){{;dPd>08V zgNJqtxLV?C*$QBo5CCW1Ht^ostb@r|U1vvdjWm*>luZO#QIbOPz?o)mAR!Z+Tq|~x z72ty)U9aYl*gOMINGE=6ma`56eHRGYljKt@qx~d9ryqX=OYB1CB}MD2CxL+JRQ57g z`xI1*>Vrq+(zP%Q$zD<7iG5oBMmAv6(*9bT??Y@oe~DXez5qe4)fRLV-Pf}N%WB!Q z1-;j?JxJ=$YuJM5alf_cCd5)}wxK_Y>)MBMJ$|FxuxWk&t@fe6#%(vE2g|s2AI3sO z%ClMz(s(-Cok#-Tv$}ksCJmks&4(Zp5GbrIfRy<9OrtE-c=&}F{E;zXie1S1vfeHB z8?7(9g@tY$K+!*y#T`JP&6weuAR7$bRdZvC0m;?cBJi{q&A_3p8|Js@qikaA?11lSpu{M%k zM&fo}{ju8pWA(a|{4sH0vNZUKradNxd{X80{(Sb2t~X87+NyiCey%lGOAW50;izy( zLHyTyyM$iB3)Jn}=YOo!qCEep!PFS5g<~h@ahEze%m*q2DFOqR zk`!Hw)UjFWY-_?`A4b!0LJ`QLSYu=ZaQm|m8(xgA#v?%2n_wEx9fo#FK(^vs;oElXu|ddB>ad?9#MJN;i}1n)AkwSCp}b{btZ-O}mSNXp)_Q^~y7x zT{gh>e|SFyrcgU)&6-Y`q%(S>d(5=J^Vsdg!ca89G&l;GjJmthoY2gH64l7{_wryd4Mhk4CPll4Ob_hIB5_Xdnz zX)Oj8nZg>9U%0b}$I?LYlCJ3@QY^um>PINDn<2D9?6&(y?>6WarHlCn?7~lrcZI&M zp-yrN4~Xp{&KgBYa2jd76BOAmFN3V!ip#*vQDvMR2eV0Oo{ue37I_eQ39 zdiKoil$SI(TEHZzOWE@UlGO~QigZf(I8hZTLwIHX!juf<37D9*?*&{g2I}C>XCU;w z&1*B#e;=Nrm5ijw2u@Dd(<1M?4XSlARX1eP@jL6MwDexr=jyf7tEw36t8$077~r3D zdt}4)+QSQs45eigZqP0NkxXr*bE5O8>$1c|wSCm-m{#CrZs8hI5u?ACtY*bOS2>!D zETvQi;YDXIMsf!l)`Y9reoXBLPFKM+rg&GCalYi5pro8i4S#Yu;0$H5P%sR67U_h3 zPAdcpV;XBr@5hDuf+@ryeM!}O?87tSe5iO;_XKPCA*>Bg zg}F|2zwfOKioVGXz}}j9I6}gtP~ro26yVX6;QKer7sbewapQl7S2T)X!#is-+#Czh z6m-GkO~v>%!;HAe*#-e_3Ghu|8>6qrgpfb&HU?>ZT%4Zf5|1ZcYise^@r*4tN1K}a zfMVB*dOOZvAXZUJnSQw3EH=yDVS&eJFGi-;N z-}ELPSP8B0(7@!33IW?3rkV9 zkd4rVlN&-$cHPn>2k78&uKu;vGx1E*EAfi>3hI9o4`l}TVlA?`u>ITwXYKsr#%W@HH^&TU(vl3ld@}A{Ur=1JXo$QY*T&MbxmU~ z9Ymrz*6{jo^5rki=+E+Hl*=3DJkr-7-46#yXP#Md}S^#*l^v4UD7 zkObiY=q<1na>eKc@-=?c2D`32`A76r)lFBgwqN&}#CKIe)3(={Nl*R}16qVO1&G9HLDD8QrwhuxN+X6U^E{_isxvjY#MBm6RF{|;~f z!-W=dN4!C}lBkksV6<9B$E@Z+b)%)Iw)0L5FdL2fo)RH4gD6606D6Nl!ZCoHZ*>Gf zo=FabM7-2!Ar+I7O=bhuwv4@Bie(kefTz7AG*LGjy;_^v;^fk)TG`!fHScYJ1Fs$D zbRiVGDD8s{9X>~0Kqvl9%pO;34Wq{2BbU8o?ArPa4;ao3d(fVlLy3q5h<}#_vh@-u7 zMM4vu$;8c?M&CvJ6=IXcUxyz@7a)E)<2oW*&*n+Io^bUmgsi(Wg$y@7jt8z25@d>Tk?sxm+ z?~Bc~8_>re-Bwbqb~AzBr5erzx~K{!760T(v9TCsg8^L$bX=`AsBxq#7n+z9ZQ?Sz zN|nH%W8_a8dWe%fr0_p4{%?_wawW{GTk>jIPSw3{gnm5Qrol3CIpSbL)~1`jYs@?F zqE?lti;~Ip0q}Drv)!S|6NX=^`q+$s>BCL!cojRjR3f&%iorb+9HMhbYd+RjV&QfO znt#<4X0TnJZv7?6XX;Z3rZZRU$;8~e049sSmariBdYJsDTHw_8E}}BfCRHbg5BEK| z)uY)%n`{)J&D9KEma9bqAXMD8wjhE4uWuUMkm;&#{Rp%HO;!(M@qj3Eyr?*a4_KGf zr3niEtlW4Av$R;(N}DhB&2mz?EwY{l)4Z$xtT>@t*pj#>#e8>uC|AabOmPSFBg2-l zG=GR2%$E6EehKHCz$0Il=%!=6*i5fDNOx(vOz8%MK%s8m!=W0VNB|_=sho9)_%R)N zJHvP{*&yA>zHEDs+|RAy*7U8u|@5&D159PUZ9nCwyl$u=AcL(RE?MUZz+AD*;V_* zYys1F+%4d)yQjDv(F8=H037~_Mk0_jBld=)5LT6R*k0Ci=H5BR!d1eP4w#npr`LLwB~N4oAH#Sk;uuW=IjijYk)oj~&8XEOa=??&sbEbIAdl_CCx}y2##gu1WfcZQLUX8IEV-v(TT1z$F2P`b5{!$RjK<()5X`gU5X(8qSiG%lo87sLXoRF6S z5iDm)wY!A$v3PU|diTIC?d;i17*=XB=erI?oRk-wSgM4di8Pjrl2VwmIE8qHD50QB z$e7Lm!#+R|+B%t(qc@6m%rDiv%|4Si1=zi6ebr5(Tny#_j#vS^sk(RWz;9JAig!SP zWcuoMo>kGJsTr>)VH-Vx+AX;f*~b*TR2Mh~C!D%&oUMvUol{&qe5vNGsVt?D7Z{j~ zH^Y^hpha4s?SL)r?6G@)TpEfpxT_{)ROw*UIzub+K(|NdX@ zKDfK>Am)CBVUK)13hMaEqlus=5?|Bo1~8xvlzdXtQ+x5QFfRKrc>{;MnwU?lBl)qG zaVQfnMw0PShk_1RjDVjTZnG(~po#SR#_0MYoNlLa`?a0w_1nz~9jz9IyI(u~?WX?u zjIL~A;@4irOh&-!b+$c4Lr*=yz>b0C>sLl?Drt ztI>cmz-k|LaA0B;YNazU+Cbu+)nL$x(Gj*A`ItdiBAtwU9P4p#MS;TlG39bWtwao! zD-eF&Gu^J-ZsHw_-u!%pRjS3WQm}ti(K)qLOE!{418Z~l<+{#see3RD#L=?ZW%mxv zs4Mfc$8WGwG&T#YqED`w^oYDupZ4SYVbe=DOZK7lv6UWoFXMEl1NvJjgu0Wmh zg?GkB&S{I^{#gt5!~Ew*UZ^XwpS_t)ZD<_2wXP~#lAFazo*P*>k?oJ2yD;^v{1q{A&clfoiEw?I9~(zM~ic;`*U*XEsLdhfb`+ddc@m2OKW&+ zo6*a|GoEKDPJ?*+t|DM*us31yObe|ne560oAQ@0c9Z>~~zuhR+W z2vz?@v$9f}rAng~YUe*xD$WY8m-vlyfU~QO5mXuTvv%S#Ch)^2x#=e zbiK^?&K=dJx=jd@61+{iA9I8F-DP5tg^-i1bX+bN1M;ArzUEnm4dJCt^DCGoyPsbQ zs3IP+K9Pn$_RYCa(Pl6yqZLEZq7Aa&>tcTDL~X(UU^GNbzatiChW4v*L3P!9qU7mU zE-wV`XL%uT#@B1EnGQi1#h3Au=dAz)Pn3C~Cd0qYx!v60+O__|;_U6tlj3BNEiRMC z`CG83cAl#G$v;H>cK@&U?%loj;I9w1|9tQMXZP>^bfZA;92vaxx>UU738BbrP$!!=F-?8HagPU3JrqlD7SvKWcS1_2SLL0G zf5l|SlX4lbPAiQ69yq5zu{QnK?)PyT2a9eFyaykr3eCwi-utS{oEtxR9C%06Wc(Lw;J{VxC#U3?_{Mdno=aK-W+mF6tdW_lH=W_qH{Vg@ zgqbVKX=qidF)Cf#MMTo9da78#fH`gD!`#{XhN7Zn+xrIimQux~%f31=_E zFTLcGT`KoFf?>%`HL=Q?tIG>XKJ;kQ3rsWDtPzAnp$%jqpL4Dig_?MZJucptt^8YU z1Uf8styS0)E3{03Mv9{=`q(+eR4-Ze6XYv(c>%_hS{Y5(z4ZP@C=O@I``I8WJ3eP`2q?5UtA?=0g3B`(S&=vTbcVw>iMlCMO`>H_+^ zrQ&Nj7{=29_%?Od-$Q3Mm`P+%#Ty&~HJ#*EDMNKxUY#cB;OwbtDkqW1g^60S0kVEZ z)6E1hmk^)_?{TS%ZLqr=ThXIVa#1=CJKudTgE9NKeW#;)|GMHs=C)7#gZxvRyFp1vC@UG@UX+FxikfVtaG)3 zoO?m$?baO|UU>nR&#}B&v$0ySx7w3!gJo;sM;J{%W~NqLz-v~Nx=IQS4j%`t6;3Kt z)p_4Fo>iw8n=Y{yvJqbJ*~_oL*H5mxBB}~j8Xs{UcyCwn3Vi^Dd#vrYmNJPH_f*e8 zrIGZi5<{Ekg!icDBdt-zZ={6}_yHIRx;1+FW5qbNN}dBTQ?u|JXsIJJrP`@eQrn2@ zvYd<+&355hhZ0L4GdS-)T8-Z1OOWnN_Sc4xcpZ$*wIy}XB05^ue8|zMnMBHV&YDa+ z2#u0#TCQd+8Utf0z@394tMw=FOpze~N9*`(ZmH5a6;Cn~6p|O1@eAXl)yTJS(Qp#B zjPC;c0tyHE2@Qe(QBS!B!Es-sL_8*B2MXUs{0M;&0sS2gVPc0v2t8Kxqm|(5O+H&q zc}J-)?7Z1E7`hIvX8M3*6Pk_jpK@cRpU?LB+oAKZnzuEv%?2Gt2ntINnDc+y&hWj!wsSfuGruJw zIB2O-=NcD2TmNQPhZ;<8F%>ue)EvA9~Fu_aIu1tHI#9+B$3E=9=QirrA5lze5V9(Pfv211pWNFhq}o1$1%a z8aSG&znHEdn}cbihPmlHRRU$gId3UFD+VANCWqV)2q|AIGeC+rq%9+t3By74hWykj zMB7oM-?woiIa!6!jA~hF24L9Bk`j6_q!YFaXA%P7!j1vNB*4vusBWm1{5hG<5bu^_ z)+FDV8NWFLLq$0 z@%V!Cg_C(%Cs`5CQIl#pH%XYO!-frygm?d3<&Oi*d)zX^9GpMD;&np*Y6W`WZ0V@Xs3zOR@!FP)hKLK#hWzQ^#GIw6&r}=`| zbgo4SQ50#r$`vtZA~BOi6X&}iib6#A5I)M-Hx(t&Icwx<_pi;~FVR%t#xYo-_90@X zpDQs*Mn3eD4ls*OU*c7&huM-JY2PcteH#z5<%Thu?$XNs#beaZOX_!WJ9)lZ&R2># zeg2&~$G#x0rrrbl{rp%lvoD%m5DF#SLF8?@bdx6%7n*`|6$|_g3S3d)7hO@})#`CO% zt#Q_(`|6_hn6Ay8_v_8&`}gG}A7vmpRpm4XCNa&%pyYHr2J=XG=4V}`sb0*j{`v&@ z2&-(vww+?gtD)!>ST$kEUIV8ttL2qgHFn?^=hPo?MZ+0wv!Jrn)zuKEQrl*RBeeb9bRXi8P5)KES}@e9)z z&%v#q4a&NI{e*2k=r^8I{N}O zcX)k6mHr8&p&pqGg^F55baO85%tSJin&kgzmsY&yxrkQUGbkmw-ZMaixUp)9mR zMIrL|+k@og^RJJ;-#a=;4qqlOj-LPh@bSUp^=J-`P<>M$Nl8szg`?2ynOlbN6(Lv!>2Ev93H5LhtKw(eE0b9**D1}Rq)w! zMb(FjoK>yI&l6~o>pDDm3AH^vINJYK{kr$)@X6uv4{DvhK0JP=YE8aYweBS^_KuDZ z_rH6xca*&N?&!tymj|i?k5#?T4xfE}q?$Q+dhqNxRn4kr$-&>%FUiYq_ntg~wm$x7 z?>jYsBh}JTvj6I{p9i9)4gvF zu+(!^&C$mn!FSZb+3}J3wXX(xbZp9gfB5pCpX?nS zzEqu6qdR)88h|-fMV@0Vs^GH&ss`peah64W0>6Lv@<8t=R!vICa6sRHDpA>2bA6Uye-(t-ZDF5+CN^YM_P+aelSl*F<#~oJpcXYrZTY2}` z#Ax0>%ED)%TakI?`=yu{(wOc(wD>{xIrUWCpT7otWAj{%6wDsueVrlA{r(WIDDL=< z%krsWnR*PBc>#)#!VJViIm;4yS3c*rLBhUcmq zW0(@TUi;;wTrGlCgJ83uCiS_RwPKkEpC3%ie-y#@FDMQVU+!ZbQQ&U=`l(tUsp$*q z6w$5rTPNt%|CEE|B47J&LN~@pq1fAquY;flJw%sE)Bq7bA{e25@Pe|zxTU_E5~ISFk@Rq5eoc2Y~b(_Sih$qbvwdN_CYThp*L& zd#|3A2eakk@N-Ss|;Kxt~u>$mOsq1jfU5gWhkdj^6*6j0UB2xKzA2tO%E zyF!QvmxP^>tw5fDT1}uM8j6i$6#(T+CpKdXESCUT!;Tm+jQMp5Em;q*Gg$aJlZ#V{ z9#-RidYiK8Y^~^9(nf$qKA&WxyxTFw!Q=a@A6NIb zw@=KYp7;(b7T@5nemY=3edbh;uTc#a&${W5tHUL_l6-~E(om7ccqN597snJCSRH%O z&C1!9tZ6;fx)}}Dr{~q!Ox(P+%^JbuoiVw9;ex;OjLfDyDPjpJFx82l2=jf1duTV3 zTZh4h7yB4010Z*rtTfSap6G3Nma|3sZIQWPuEXJAfXej2K%&~VAbc~BzUfbp&eaZf z*M9GPBeD_bA1$r8Vn-dRH1Rc-22GCg3D{ronO47^WedEIp;JZyjcral&SU`(3b?ao z?wgXk@DEn2lTYVMx_?=8aH<00SZ1a99D}!M)QC%0=p@L#D>1MnZV?0ZIgUi6&+da) z7&sgJ1H9&plQIwk@YX3f&p1vQ^3auwt)K@dd&5?0Ah~y#xYMW8r zjDyJG#kkCggJ9w4Ay}*t~Mmd&F)XmqzAVT?up`Oonz?;YP{b? zh@2n!=1gM{4R&3V7&dI~4DUI4A9ngE<6tyM15>G<%;FO zV7l7EhRYz>!@^!6&G^>u-prdz!w`)Wv1`6*Vv4j%$*rG$zGa)Y(xGXl=Uxr3ysUWF z`}bH>9LjHSNnw39T2RjfaD}Z({H1wWqw$!(r7cQ>_)YFn>e?o28k$}*n!4YT~y&*?3H`BPR`$I0Mo zTN`MA5+WydtS6p6hx@jYCvYx;2M&{MnXd?%P(v8<}gvGVkhg!zpDih|ewpltH z$1k{a)H7T;%0`3pShIAzXlBh+Bf&b_C6*TN>)D|pQu%LZjVYngZ*OzLDr~wlU7v)F z*RH_gf}RqLYMmFYblMv%U-KL`USB(hO`Vh%RL2wJdgwTZDu1hljGg-}QZg>YMx@;6 zF0=7c(!`kCfRQ0p>!Wi%k`{}6v^1gI>do(WmB(sJxWilIXZgEd@@!g7#W~IIbZTK&@ z;y?YYdy-**>)8xfLl33IHELXM&qZ-_6Oh(op5&NiP-o|>z#9~6zE+b@;5d0*9pS!>bN{#c6=q5$r^@#_YHqk)5f-Y2G`WTy3`OXeoR_`X+wcxmk!@HP|2KZ)9-4 z3AV)7q5;0wYD1r+JRy3y8K}%D3}UZovm8lp9g&|%W-8U}mV!h& zZ}EJ*o@BZsAxWarAx+ylV%z*YWuo=moe*;txaEKfRr}dYvTH)6W6z7n4xKDCDWPOJQQ{X1ZGvn zx+(@n#p$ZzELNr9Umo#YrbO+LnwTm9MM`sIwfPnKy4Ybg7`_ z&U2ajrMI7tzyF=?Jp&c*Zv$R$!S}ZXzs*XcxafP^fx->ZlX81KH%?`tH=RoiKq-TJ z5tk(sKI%@D zr>xKyfr?>MK$>n}SSuinaEl{Ug|8$OZDVA$0QmZ#vAVcfBR0O!gX32QmR0WwveURE z^JUk`C|%~uftyNKWE*|0te$2QQMOl67U8zJ8{3SkgIH#xg3_`e!_#4v#SYc?l6_SVE^z^>pwXvT;|HU=odg>)EP8{3Y2R$UwIZMUfn}NSWyYyz zP}`by+l`WiE)+MSpxzv>(iAw-DcWW{uy~MOX+GzR`Q(i1(Q*9^q0`0m>Euvyj^)<@1*glGn zj406vJ)Z_l4y$qJ18W_FC=J)-Jfy*?d^BX#3xSOj^Z~w#)lqwgt?_U}e%lxWq!vj7 zvCm3zV)qVAYFqHg+Ky<<_;l%&#~eW*Zc#kE1eGoNbS!Y*C;>d@AfiF5oEwp-(;`YN z=h38O9hNWM##PdW(huY-!Vm;ViXQah&}z=DDFQq6=>l?A1T^|S?5fcS=Zt3^#~f69 zOgS?rG1avrTIpzd0K*BQHo@0B5Cku_v6c!=oMol_P>Tz*ibpMXe+96Fwq4kJHHN#a z)jM3>>Q}2pmJ9nvJM8q)jAhibu+`=;gPDA5rupIeOXB0T^OpVN>cnL&yj9>}Z}i+% z;1O#+i`W@WH3baD~Ra^Qr)oh_-}>o;0;f2rVFkV>c#FQklOONzQjpD zGMIK0{HmO@alQ@7|GbI)tn0N#Y~(1Td25sA0j|n5p4wY)I}KC}-RtzJLAjaJ6}GMYMvBfB(BoEx^;RWWT}6U&$~2`~ zDvV}HgynD3lUXupS4*?%P<}@4hr~spGkL_Q#DZAln2XX*r>%+fR^I~6tccqz(Q}-Z z@i|6o84olD4_gkC+IOe{Ic;0tvg5XNN^Eq-KEqmd!5c%+B&G*+%r*kX3K=|LkV?cN zFof{Y`}DdL&~N*{>-t~U^}nv`e_hxAYOeov7SHCFt^T#5{@2#sFYn*owCjJ}`SR{{ z{jcl#U)S}&uIqnY*Z=x$)&CN;zLGM|OSs$>>Io8?`a!x&W21->b*K)Xt-s z^@Sjilk^+v1aG!zNI{OkfPOuVi%Fi465$*1NPbu(r+}e_V5xk$j0@Rn zmI1o~RxN(-WTylCH&EYy15lj7VsM+LH%~|ru)2r+EZBh);xr>4tNNDs4z*sv*Yi9+ zNnU?r;06_5A!r&-qpso^5sh84GiR0Ou z`W8X?AkD-n9%dr?DNe~BqvbG|exOMH8n?-hP$kg7wIuV0N{hhmEHqpTmq)_NurnTy zJ2G-#{*nL9>7AK3}zU~)V7 zqA)23mzPX&X-23hLWKq4hp11YzJeFE8i|AhqdA-0pKIT~@V2Mb8PaCZ+V+Cag00|& zB*o8yG`^T6y1v?1cFPMvq>)f#2$C|#z)qv-bcARWB#nO#I~`KTqC4`^)xsi=oKDdZ5F1MwSLPWJ zTc>Ki$3iEyMRh$zIbq@uE=(dxc#IEIBO{SUams$D_iTrWd3hWDhhx`qAjur$Tq>0{ zkrbk!R!2_LOI5iNKqhPiJS*ul?h?*DG?z#NgfW2wD$-^Hue}F~OwMB=CV3%7(Xn@Nmxr)hUZp&?;2wXj?=n)>>aU7KqK=e^I`nNVHEvqrn zZs(CsDw1i_-X(xIZA;hawb!$PJoG*NnFbB=kZ)>cSWU;rMc7FTN9>xe&iY70b10{k z#)v{b@VK!BJ(JxkRwjGsI5i4QkhaW&KuyDQ8a&P8bCM}%%b>)IXNn~+#DVBN1O#JQ z=Ma!^>x|0FbkziZPKCF*+nImmf3ruEE{gyZo+Pm>A)@SX-bFa)A~Xsm8x6NT=j`AQ zKhwu-IE<(h9|;-3D9CGH3=9c2M=38CSsAIajw@l@KpP@SASA+rD4wc1dzCC2VA5y( z+;KRNhg@LycQ-wBf;7U%<5q9=_P0={;niHCJf7#CH4>KfuhsQKiQsQG1x#<1u6RXpHJ&HPSBLd*}0+Ou;6*_ej%8iaImp&Uxz=`aD=+g|_*Xzmd5OMwks0 zZw78BHhgbrph4%1S<2OW_4e@0SmM|eG%%MLIpq~7NOWZn{h-rK8XbEB$=x=| zP8(Qq<&aW=DljD;z<{SC6+IJ~GGYyz_4O+M)bSHh21Q9=a%pi<-Gv`fRLn>fOY~E~ zjo@+gGS;JL%CjVWiL7m!p;L?**qc|FlI`hgbJem%f2cr#3EU-IWoS!cV$s({&$F+df z*mHjJ?rI%09B<^-JtCABp37FTn3WR0+{oF*E<*XUaGuSRGKRxBDx{B#CMa;Iq4FH^ zipxJlvxO9vMJ&6lrdCl&r^k*-<}!PBh+y6fopF3ICPzqaxGpMD=&4EOKSp^2=TvH*fWeZK)-U(sM}i@|#Pa#}rRX(f}O|K+{QHc|!v`ILoZ*cn=2;UhGF8ddZ28n(^a2 z^MC3bNK%5-1W18{TrX;Fo)NT_Z8HMMx<-nkFhtQK9t;fi6h^hu*+o%+5%7pYnZOwm zH1tm6c+Te4sZdFy!ou_!S9x7OjJt~QUg;)nY0Jgq} z2je?ickYf2r4jj_p2O)ROcZ!mr;5g`{)Z`)u{8loDrCY+wx;8_yujEGJ>k!UZ4|+U z^75r3o>8F((6x;M6Nl0uctVF+G;_410W;&kHz2U2SNd zw$?E%fYM6WtcG9ZcEpBg)C!gexKxT50V{l?l(wd@<1@ zS@Z?9lcJIpr=Sez&>P1GSP8vh{s}4$r0@_;$_3F6wN_Egl6)*aW4bzroRGar4}X!c zXNKBhQNbP~)io?u+4%$ksO;Nf8OGJDeaW-Y)nV_+{^;mnd;jpeCkKxYfpxyAM$n=O z2W~WBUvEh9g99_1P-~EPzW(Fy|JC!&+kbfRX6wuTojY&8q1MxQ1_I{vHl<3i+W$j+ zbIfli^b&9F$voXYI@&$hr-bo%jh!d6xZC-g(E7Pk4qwL0qTB2BOm#~dUyMfG$*gG9 zBHRd$Dt>HoV`BXgii)R{h>#D2;NlG6VUu$tTzT~FPRON*4jY-lO(tN}qmtC!NxnTt zl@?kC1Xt4gEX7b9%o`O628FYGPZz+MoGDs6$8Z-F_h7I)+!2brX;T}qt3`|+OmNNw zc+8k*GHDQ{wngE!XG$K2XAGkN%q^PChY+6EEPW@cO3NZ$6abjq^yZycp2KtuU}8Kz z*7|G#uC!+Ge-|9*@QTYGNbyHSVp(CuKf z28LkcKI=5Lq!!TfkbHwm7Td^2q~iiA6@BJyU8>?4LOhBzFBllqsN}nr2~r#phGbe|syis?-h|sCj&zy^2S8@vVm!#}f_ZknRAXl{diCLc13B)}#QME^Y(?Au>P9 zDx*nXY`drS(s*x)REB#}eZ1Og8@zdacTL!mON%gFaiG!R5h);Tv$faGtKny*(ND*E zg*rl7qoT~8JIp1<=NrtGHeN_Qj@7rO==)Q=tji|W)G?Y0vC|hi8AvK@O9=dqXnSf*gDccYbUlQDM%166z+a?AuW zE1W23-XAR*>-S#Bkw<7C$F8KuzNTdEd4`c`$0Y5cjtDs6=o}~>1FxN(}cLmzcKYg!_;^pkuSrfXSZdUao8TUO305=y$b=f~>_peCsy&0c%(A z3qbT@E_5rx>>LJ37>6ob4Jo|F<3Hk=H6H89vBu-C|Cmg_8Cy$&7eRYXC{b(3rIp+l zY-zU_F~p9HOAzv#<2;UDk}5;9{tH;;29p#eRBxD&YR|~hlTpSukx-kjXuzFrfwZ5; z)8u%zyoHiHsS7YN9Iq^4u-Cy#dF0V`n%NgVWvl=w&pMM7NG{=8>eRC~@TT27+3EkWXwJ1K~J5+V>q?So&{6hW9vE(~E09?iZanqUZ z6URk93%cO~SqcUrJ0nIxOadukVS5Pfxf&z#m?H@zk54h};%v#DhqRu;5@pryYnnin z8if7iFA@w-(hs|&^aH^ca#6jjc3uW3DR!1?&NPY8UYoK1enpvn@LRL=oRH1ll5VO2 zz{2S%`Sp}%Li5e44I&QuO)(^#|HVy$(APzIDGl3wPM0QOg0p;Gw2+) zX?sEND|FYA>PY)5Z;IUKH;cdBEMAbSs{DWxUHCu43WNlyN7xdz0(p9$VMcWLUwG(& z6xtatJaVIKr$Z%ueZ&}aI$PuE&2_8`;_uunZWhuvS4AO6`9#cG(R!$sx97RRNI^vG z50PKk-X45;Q9_H7)P+V)x49hy!*?$-B772)?I@i&S9T@MIQ}W}`&W`tDvGnoC#{IS zHO({R6walFWSlgRJtL0K^z8W0aZQird%b6StD6JmF8V}nMi(7d;I+cyQ;Q4|KlKpI{t6p5?7n_ll zMkHF4**To16Vl`_QiK`B&J@!xnS`Ce)8izaR_O5E>ieolFm{!cY|G=6Q|t0^k8SsK z{K9v9oT{3Jst9Q<`s>67!{gQv7c@7EKjI=FUC8T%PFo%iCT1pNOF%{-Nuz?2sJ_o3 z9?LbRCkrti2JN`C%!h@RAt{U#nN-H%eM}K7%DJHnLsXc(VR|l`&o`f2?=HDlr{kiC z?bS0fg32s?P1~^JF2lx~w;SSHmFdc2{78#c1hhkribq``T~3p!o?%przsCA1aZ$$a zlU(BjuZD)-(QTmNj*zthXZ}kGU{Yin)#A^?&e&Sl+v1|j2`P-$a#CaI=`tQyE~4QT zfJ0Y6*nGTJZ);)mLqPp$b5p6r@xI1AkH_4#buhi(8xGZn(@BN|OApb6SI#}EQGPWH zM0c=R7i)GDVN-5FfYz)S&tx~P}u5OY?Rb;)n20?FW`SmS^rh66 zafnFI-Afea%PiRMBARfZnx-=|tn_2*SG>{e|6|jN&aPDNw%Ln8um{btnxkD9$reqw zQ_7HnO${8Vs%WR;ej(ANZ+SpWV|1{}qM1=!5dcSF098X+I?Y3J2T<;XyAPl)U%1fA zg~EOe6V_b#ehOE|`Er0T#M3d&%`zs@GDZ%ML^~|zI4$tfTOAz8)PXTWcW5B6xRNmE zM1^t>)HJMgr4c?7!aL5;Ca%q`e8sPvHFimymRIxA;?-@o@8Jp}oQP<@dp5oq2D9k= zcnY$|AecDn5~8(|!jKd!DwbArmmw7l1J$kiqxwl9H>sF`9RiE3Tn`!x)Egq4VwzEV z^0ESA;ZHP^C$HT_Ot(c0!nC`=8gv+ZQ|1vRuqw}hU7wyoufXAueMnDB)^t;-PUz*- zOrBkdB4%pv|2>6$!V0dXYGhrqXin(5MbeN2T~3be-0Z)t1f&y$9w!GA(KwMF=Eoua z-O2fMt$Jb{l>}df(ESLy@9OGnzXeuLja1(=F?~x1V}%cs74n<}K#41>KbAL!0!(w7 zj&hP3`vH<(4*Z?7W!zIa#K&E^xXx*+#kNS*xr}wSPC-{?t}G)nOm+u*p0t}FHJp}b zQe|FM4wp256!p#r&LK)SAh)b$Muli;G9*c!QX3*?fb+hrZrx0RV<*D7NTwB5lx$MV z0;6KYh%Bl^T}lb5Ck6{eNw^UW(4E-cPl`Ob)SVqV)AJa^Uw5m~`||u4ZuV?KnZ}rP zxr!TXpb&|pf7FXdKV}a-Jb=f-{RM%DBS+&W{N8e{4+aGMDB6r zjBfPt?NXhOx=m90!z1e;?-;86d`bPYGgp^LG)%Te#7d2wG%%~;*tXP5hEI+J70!}k z%R3>TUg7p3n~!~-`>GlN1p%KC&ni~j`M;w=N)dL{*JL-`GQwc%=rG2C9zt!kf|~%e z9BH}_@r}f!5J(W+?~$(hBEe^zid;O56Il#NXr?s+&?H{PJCB!gcGkWd+b&yf(3L(V zxHZIux&jNMu?hqtTZp(aXzrkrkS?ne5Op+~Z@Lavgd2rK5V=-d*&W@xcl1ptjNdkw z>)BDz+Dq~y=vu+fX1Kn+0sTSKD!{$%Mm(}M6>u!M@o;gP8L8WH5#`t-^Pi z4~Q?!rGDmW;XvF#qXvfyWasLfpXfn9Qe9yHVD*xgfM?KUt<2iNTfyP{4F~Zx^R zlBwwS?aGBrb64OX9>t0fi`cpvXNvk#Rn=4t6b3)Wbg-Z{j#Z0Xh*o3h+z0CNYS=lF z@yj&3kWxTKp>hAgTx#b8iTaV)t6+BXik3L zOp%=`gjP?o$7}BR_r)ELD)&I&9^oxQzSE}^fvQ|zP0##sSZkk?cj9=un#ub4s@e5b zGFc-jhAvv2jvHKJNS;!R(ZdYa*9wV|Z zw7AJ#bA!JVZUAFN)AKB)Bpri6fHC#B77q>YSxv)Dlyb6|IV^>+iPtlk)IrPMg48BG zb(Q&FbVTTkYJ7k>?=I!_f#sf@$%9K3{&8@0yNW8}XS; zp;lVNZCVkf6SXp~$ElmGw=mMIzu#sGYaZc7XX=X7Q_drnWcT zPdNq3qEO0c9JA5Q{e-HiaF$ZVJ44e(qU&I*Zgq#5bD5$HwjQ2>iap8^3}-SN3f)iU zd4{~i&dwx#N+d(308xxJ5Vg3HGPIS_Qju#NJ-RNp9hZ~-ph9lF#pl2+SGHA|dXKZ| zG7JtWv5!OO0jI;s7qeKYOwdFn&le6F;GM?lFfU2qSD-dlo5ax?QNC}tHz~ktk=||n z{r!4mJ8hf3KW?qLMF>DX>izOalhBb!i2~nq{TkgSp&zU4jmxproSDoFGp(!?(u0On zUdDMOlQ|*dLu*u2PR=Z2#ch8OeO&{oYpQKfT_qd(sH8z(BU`rdG;!^yzQH^`7mT6sju!y(+%c# zR4Ltc@9yiKX_zTh?t3!>LUkJQeU9qI1$=*e6&I!-sUFu^%x6j2?F4$ZDRc-Mx_K!u z)DORYzWKshwevc<6K>$rd#u8G*T_Jk_NmA)U`Ke$QQOg}^tDjc>75J=ow}1sb&DO`3|;beOD9vF@@rO^YJECs`PFD_eH8zk5}=!lPO>ij;J{ z;)@7?26+<2Yl;z-GMqL}bqNPi2V_8U7!rxst;)6@&;8Z;fyqCxP02oQ!9x;>PLh&q z_F=)Dnk>3sZORlM`)(uU+8x> z#2Y-6X^^!FW6teDXp$a0u577Q!X7bhBRz?hUC{U4zKF;#rO^Q8B+{~G zDM-OEX~UeL=h9}K9R>=X$6O+fRK{IQJsb(^bEU2jsu8h9BdjqAh@D|BUPW)cmN}Z8 zPCQGFly0TIt|4)~EFVqS`xZTc{~0Kg_^_z|}>Hw^I>RGdXq(ifPhyJP2$E=HndQ^`=>Z@W{-zU6^L zN{w1OlguhE4c4+?tO!1_9L!W`rv>-Mj^rX6GU74KMzXWUa;F|3bKzT{9BV1TuhLgn z<_;{}E(al@cnyfP^1KRWMOzibD!Z;-0#=csQX26Sk7Kam5UhETua!KOz0<91t@Nyp|!+@a?CssZ$bo3SRjt=ca& zd2Q8u=td)2yElz^?T)lpn9f!sBPWk-MI%-p^QxRTNtFJged_C)D~COVB2}v*qg^Ge zqA?=^9TnwqIzr`^AVvzyY09E^$lnwJS1HJZ_#uu|!DER=$485UuC?6S;&eN+V(&f)rrNl5C$ z;Dh-hpJ#<#)X$gj%S@MLO>2XSgumH*`)2EHoATg4ryIe~j`+XfRt%S2wy71qp;yhb zavJF~>e&f-ne)Wc#t2@qH??xn9+l-D_2l(Eqk0!sP?J1qZ5?M-5rqz$>9kVB3c^); zYur|Cp11*=ft)xS5iC+g=6$lO6uOGJDkaUe zaP0K2Vm`j~7jCd`TKSR}D{C;BCsU|uYKsNwxd_vWw{s3Fp}SRqj^5Z_Y$3&>hKM^W z2(-!sQZpgJkeEo(#d;2zcbEnF& zpv!Q#Fy&l7;BmrlkB(x??5G>;_%*vJSbuDisb9npEd>~m@Fp}0?I97LtN)K=Y1 z7+O=zz(?`&o7y3@xshV3b$0QFsbWXgfF8ZMUhdtijL*5aeZ{e;W437Eo1)vR(@EC= zD5|WtZN64q@rul}#$^!>Q^ZS6c3G_Gx+u@|5QTW=>4MVP%5*s99MtW?RYR>YX3+p) zZR~DK#}((IU*R9c>)efKw5swpT2wC?an`hkO~zR?rPXtW8^PDw%Wq`v-gfN6>biCx zn^*S^*YbL^sbA^e4mwuxZ#{V^v6@P$B#e`{`g+ep?QeVU$tsu9fA6#=b@Hj5avAQk zgO0~I%xONf5e*Zc%vvHbxAE?ymnY{}A+g<@ehdXL@t+N|p-u-fYXF|F{wQY)h}*ook#HsEuf{|4Y; z2vYWyvazgut<|@+0jx8DZ)|f1Xb!!0c(`_W_*FYRTwC(5){_6uruKKSb#MH_?DiH1 zx4W@k<4hE5{f!yzi^a)F@|rB3eNoqK=#10Cn18Lix0IFHJWiX8|25`*@!31r`&(L# zWky3cs0uh=Fn+_d@b-;vUw<1s7e8N&o16e@LQ&E7zi8}SY>%4Wr8~e?misXot&aRP zN~Se?P%u8(-Ju=++Bi`xj9%Lz?oxgfYgSEbS&GVE++bC0suoT)2f`i4ll$&nJ!#%G zjPXioRi91!2v=!YL}k1>ubG6$YWx{)1dOcUaWb9G;^0AMB`wD?ex#FPYsnp1 z*pF-BIjMD(S5yA{z00b)Tn*) zfwzQKzE|c|v%I)Wj;v9MR*XXP4WkVLOfM?VRF5q@#6DbR0Fe^HSb~!}dKQHv#ku

    Itw#ZD;5XdZq_R-x-FkwkCJ+DpSeYhuGJ0ZQR6Osm@q_UQNd77y0H6nW$ zOMUrWkKf9*d(^di)U|umFVsEi-94X7i>;yey0pm_o4%8?)i2W5>KEf>bv0g7zX}hi zI!#A4u6J&~YGK zul2*N`L; zc<(59luY6jZkS#8L8s_WHecpcS-Csu1$Q>LzPNp7^Uh{)5Y6Z1U$Mp0I6qH{Lf9?P zba1=`K`=s}_&(>_7G9R8SjUo`59e`SpsD2;v!GK3w@*Krz){DWKkJPK+=hepo_+mjYILpMz8Kq0aQpwKYKpdrBK3H}??%;t+@xR;;xF*aT}q4&|;Ib)Op zP%xFxIoy7RT_lyqvxHC7e990%=U5h*&_n}YoMq?iYpNzgHBRyr24$Pm6rI&+%sA{m9_8#m$2sXA4;rB*A_;K&( z;ge@a0kk;S-aq;&c=BDaz5i42r@j3L{b2XsJU!SwJpA;NCkMgaEUoc?dtZzukMZck~mi(|3DE`_OCf z9rU^#Jl#Gx+S_^dX!{^|`t0E8lfzvA-~sfzzqkM00SvSIcz6FOgkj-Xu=@l22o4`^ zKYD~?efr7vGnl{ujC2s}JbC)l!QS@|kAjC!9zEEFhu`i3Y}?;H+U2oeUOSJr_a66y z2iuRgzu%>=oqh zyZvDMVDAush1nfEfdLSw@W~VE1wP#0e1=YLEUme)Mm(NB@o={qNPIfBw(u5&R<`{l|a$@9@!o{HOn3d-Ol>qyJHR z^l$mmzf+I?<)8mEeDp6`U;pyY{{=t#FRMrYFO7)*s7L?)|DZ?z{{K{u{=@%;PyWOI zqrv{q4Ez7Bf$-lj2>-42=)dAe|1~~(3&_MwwF;p{Tz18;5Od#ld%fUq##1U{htI1h zB3|YnKKPEO+7xt?Lr6&eLLt>@evvkcQ8*4voU?4n&pbZcMZ@)&cV7u>O^ zSc@f9o6kaq81E1Cnq2b`0p_-d+7h9y$ z%=y|toiSr0HQCE#KDuz7nCDqxV*KI^j$hK~%c-`qQwsD+5FDHYpW#q1yqST?QGve? z;atK*PPOL7<2;UDy035=pACa8uk{nNUA?ZeeTok2iKd!^7w0f44DMe{)ywbAZmebD zs1LC>M9yJ-fy*4IThO?Zl33EDgYkiZeD35$FdT{zyxQ01S-UgmUcCk*RE;@Up*RSA z{($`H2<0}A0bku2|d z4wF}6l^nkx_($d4qcVd1J%DwOSDL4f(m_K`8p| zk5CoUuxQ%Csphq7BVeV}{1pE1GwBY}tO~0YX+o3I-$x4);Gv-5Mcm2bKx{vXQsyU2 zAEZVyFMaj>y&J)35TTzeR_qqwaP7HSTvF_}T~cLzqLZtk77pml+QPMqBbqg#f=3Oh z*w?hHM)6F!rdkJ&G)?eiK-v?;s#d=rB&R9YZfkG~q}xib4Tvs7t~_i~Ab~|}V^Gj? z#kZ*}nmi^_o&9;{cSBoZ{@%krh?acH4Gmm}m(Rj^+m?@lCqc4^0JKFCxi*MRW>rC8_4L8x1)3- zYr0$xhB~S?L)`Oto(oloFVyhsN`rzD)*yJZ$s*TV^!I#4zomrt7Gb9+@b6nxF7S`+ zycFT(zR_pWRI-@3N{e-QismzDkhi_NVszx--5{OaD9U);ZUz1jcn z?f+#|yevMylKubXmtWTJfBWyPFYa#M{ax_I_5Q#1|GHlPYyYq7|2`)Fmxk9%JAgI& zf8E=H?QZ*j-P`)&+W+g?|LfZS>)QY8+W+gf<^LsIz9<4C$<*&D>|zu|ss>4RR+jUs z0Uu22cS2Q{O7(k|ot^?QtKY@4P=A+sG>MO+$xG#cCeJ;5n4O$RN3`A7^DK>tK)>ZT z_{EIETg3pVI(-Cx#(8%{v16l==DPGK%jQ~^;{f}|xFp;+aGJ_of0Uyrg3W-+a8Bwm zgD+`+AM%&c*&!cy574u?zu^Ic(0_de#e!sN;LdVyv~1!SK9cbti^7YYf^GwY4|5?-sn ztu};@zNzZYx z7;)-ai7?;H$w=4KASs|14Ema2#d1m&Gn7s`X3Mjv7@b5(LyMx!<|9)3bFeg{+VJ?% z{gs#)^x$zy#azAm8i>F)gOlOm2Xs1QD?^8yl0_9xFSDo|9$MIO*m04EDHTrR5p6-B zkFMA9h@8EHsV2xOC_u}nwP zReQPTMI)BN6j+oN(?E5ilG^lXm^YiDXJgJJ@l|KkL60iV>u7{TL*pg~5g!p&tV1J2Z<zH5Ht z!rth^q4nc_=U@#HCbJ;dV@RHWL(kz?6RPN2kB-JljAXvEIG&F%cg)Nw52(F+r|sZS zx)dft^+%drbkz_1pTFX+UX+twld~JoS+Z3Ex4YR3ZeX7E?4k&m<#C>{Ktq64r;r?G zJQ-xPP1rE&rldJ8C-7mUsRIXh{1`p1=oPOKV$5gl^?Sittj>p1IgBwZ>GNCVz#{~Q2`6Y{}!1sg8pvQEVts^oea}8EF!8EO_xg`V(38(Qa zT6TNuIf*Df>N)(IKoktQ9!-Wc=z2yvBCn5Ud3iytJs6#zKV*oA>BzU2}|AWL~0D< zqQ}q7J0CxjLTvq3P=f-g539|i-4%x>1LCXWP~G@?CgjGY4CZdXHSaFYea3EXTx9IK zjop~2R<(;cs;pX67A9$_6ke5d%WA-$&jMQavzPIb+~qu< zYZ>D4knljJwb1fX+Sy`RY_I&~@Z=J4d23i47YOqPqNi79((--lea* zu->R5^WJs6y%G~>DAgj^w!}208hWL;rAM(PRDJ5>kWo(01zhy0y{CFLI~2b&_oatR z<1YLjRm~?0%n6Qdcs~*}q<8kw+Ou?)yo`eZ?839bn1z(_&wWIcsVaEl*GXxQ4IGxTGC4I*MCmcbNmPbnA}q{G9PlAYl#N9=jxE{e45$i4 z9svkLP094}KuAOdF~D-Z3@jZ0kp`v^olN3*YUVvwz_FGaOBobN9v#mxqgF!2`SSQ2 ztyjeK2u1>hj01-3&Vb=EVP?_bRT8O1z?`Plt!#wSSTPQ44ud5}%w>~R-&P)DcUm1| zZFhT+HyzL6)hDO-QfJeCbUBmq zqlh3AaP-U|%{7kNZ8Vtz|4A@md4L3vk)c&|;!dO8o_nx}rE&HmS~7{NeFtad%c5T~ z0%pHHNrQ5`R}6(f8o$po|EiAtn!`|Ao)K2G8(~G7?#ZI06ty_Yke7>x9J*^}tv~aJ z5fUg}C{cgWbw=>rC7DL*bg!2tNK7hs325r689Ow&mn3ZU)Fo;xe^4o+h~?qh9LI{4 zPZzmh;MJv$O_TD)Wdr9~AyCy(6nG24sOz*ROA*B33#br*=ZBww$V>P^}F0 z!0XM6v8EKREJ4no)fjUeg5*YVPUC?Q@z4}sM8+s8=?l$_n!e`D>RAOE%3(mf@@QD{ z$9+|1FC3$b3aUX}43}o;db9ca{H-z<3h*m)7IxFC2{gmpnsTguV9aUVp#`28OGZx) zC@pN+x4dsmZebkcKJmz3dki@(NwF?#As>ib?f!OWByCkxRR|@*F$FQruxx3{wM;3+ zNgDsYsUV043FQLrJ+@3h=ft{HLcllc;!`>*HwBrLnHBG5PTPxaL@PYhG2@a@NiY(Cn+$h6}1gsnY-~~ z>|Pao5UVoknl#HhLw(jTraOiX0c+ZuRH#IRgFpwu#0n~ExSLDg;|zc+1Av7pf!`Lu z?wrMwm$LM@L|K)0z^7O6fqSnRT;iaZyu!K1^{ksI<*qVp8Jgz-iCFqoN}rp))$rZ( z+j_>BIWWYs+j*8s7O8Exv|1+HuddF!q;f3jlT+}pSQa3~PXR*1@-O@YLmIx?qU@bg z?bv>xosQ~H7+Up!`hRzzYSA?dh30VQ6o#6@X^>NGVmc=C_!O8jmLiWd2OAd7MSU)z z%}^@!g4Mx3!jRRy3@I0`oGJMRleGdbg5vPn^a-lJGQ4|XS91Agr94l4wqbS|byL64LJR1aqJU$tWD>%MZe}3aF zmZdF(TpLCa+Ue+5<97WBXL?1wSKI(gy;U9^ghV8S@^BS!ygPYD#N8PDGo(0$Bn8| zR-Y*~sg=hn3rdVTi0~>4cWOQoaqCmLULv$g>&Le=z%-pkRH;0+ot?M`!35l+dW^t~ z$EcMYk41+cebf5a{CeN6-nWKXz16nWg@Y?P`*g7=PRZ?n+NW?AbmWLu8#u!n*ko^$ zw<1%MML3?WzqJk37{<|{yg?VM!89tP!MG9|#=%*30UH}rB%xOY6%y61J6x7~8mD|M zdxgq~D&LM-Ikb&j_;GijVWh?apR3pILv6@k({_}OE3I~-*UPghv#jlI`dMK3R!-wt z8FdZ!BJSB#9yxyVbWN!Ik~S;XqfP0Tv}qfRs1xl*`wDH88S`)&Ga#_m&?(`LkLL3k z#j5G$%*i$_=j=OC)xbP8rGy5UoWmA%hBU~Og9p*O4Qs{G@mO&&(lMK+#Wq*b%j{u+ z_NqMW$t;UX&&Ev`=f|*9vlICVOs2d*e+J}IOASZWw_+jJ>0Er$qH`jRb-Jbx8aiHs zw^R`%jv_7LtX2VKwk8I13OhQjKj)cVhYGEq1zm}RTfzO!aI=Sx82DSk-TRyP$TT@o z4_~*4b~(yQ*eUK(R_fDPTofGs^4B=ee336B1u*_=y_6lQ=~(Z18be+S>z$nSP!a(S zjXZ;WHCC_)5u7$eb(ZdR$i*MY*AQRz^!PkW)+o>&W-%jklI}aDsT)Kr9_>)>NS1+j zRJfv)w;X{vDRwO>_K}Fm<9_Td>u%STTlF&AbmbPk%=TQdHP_pg%B^$|II2!`hkQ}j zF|K*R5zu`@&xy_@Rc&_7IGCg;`c@qVQN(jrP64bft=vZ_ z!X4GeD)NR%?KTGFM6=T@2O>KUisU?*MY-?|&_qCx92R6!OIMgn#Y}Kg1IKS|Tg0L6 zqU=Q^Y2uR(KsM4FBAc90UrI*A<_x<%3c4)aauBNDfvegAI@>i#-^XuP@>-7o*i!g2 zB4pJT?&6oaB*G2=RpAKvUq@`c&Ok-dS`EZDf(Cxi>JDuRc+Jk()=SzA@RB{Ot(S^k zp+V(rZ8aiy`GFN;`_>Wr$afrP?S$@#1`0RV*#WQf|6S*Qy3YS}{oijQ{}bAoWUw(Q2OKbn%yZ`0pb^fR8{7={UpRV&iUFU!LP3C{fif|sG21TZG%Bmzv-@)$H zl{9my7{M@5q+q)Aq9R7zdZXh>_&6?#=rl%sEY;E$msoOS;Iibz6+{=6Y0s+_{!VL2 zK8ko#pV4ib8Bfj?P|joFG;xd$eBv&yX+Pomo6Ki%Bb+~1uxyutLAV+qF&ntPKTBcT zDE$YplyP5O>EUYqEfwR5r+ZJ(;ZN6%Y!d=*Q*3}hB-Tb`{lRgPq6;(du2^U-qAC5- z)D37f$1cz+5nu}XxIm=^mDeEL3a$z)9T;++U<{6Cg}}kq3O;hctvrYY;25$q9^;Sk znB$5J1qrP|hTh?w{J5j3d~l_lsG_5c29T&gdmOTKD!`J%ClRam$Asl2EYjYSaizMD zi1FyCaE&Y-l|m!3=cJg=q9vNn(_k^5Wf4&;ym=s`v+7$d@=0l2R6v!ka2bzJ<{^&2 zM)u@{o}l(iQ@Td7PK!hxHWH9QQwq>h=E_VjLZfS0ig^a#7e}Hd=0=$4Sf)lHdW&?u(I~V4 zZXN_r?vH9z+`5D}+@QS{5NtM$tcSXBT@H~njjekN@?pNnM8uZx$mZqJKO){o^;M9N z`pEo2z}ZtCa%kDlvl(w#$*2mw2l3%vkj5;673JcXw9XlA)GQ_!TWS_8QZ%{fpYO3x z4ps`voFsQd+%mQm7K9!+q{@%c6FNFSo<;*-_AkYR{E@dVal_{K(dS5{K~Vh-|ed@yz|GHn+Th}ijL!f8QWRWI^SJ4}l=dlkv3qr)F>En9FLSb?{KZs+jn zlf6f~2cu4J1sqjNET*Zyv;q<1Qa6gnFUf+X_kM%UkTJd+Ytj+I4fICNpp$4}5;eyd zl=|6_{$>6U%CUrWawMTpr(XW zwuT(Xu(MMmF87A?pN!z!zbxW{E$zghc^mS6%P9uNs7ZJOTW*S*(%Aw%xM#Qt#o0#A zHe_=s42uuekxOHYGQdM0Q7Q(aazfQ;0v!EA1S_;c|KgW^UPny7>#{T}t_Jq3zdEnB zqjf&u2|Ofb=#4exPr7;`pKJZ^wf^^7|9h?fb@jiq=(M;R1#q+e_se_t?|xy|f7!fu z_gepZt^d8&|6c2Vul2vbE&VTDBEmRboEI|d{xgtDzr*te-;b#7>ZnSw-Z@+rWqghv zziB+9b{*l((hVNeyW|l%I+KRRFuICSWPg z3NJi_9RnWKBYt4^D4VZW$+TJpT9Dxz>g)HpTbxv`TQp0=Z1}rw^`{&G)x6TR6po77 z2>CmGQlOVJdl-&Z5yMgsb{_;i;mo>1XJ}zDBh@!>`Mt8J?g;E9cSc(J|&L8RDN^Yfd5c z3Q+VyXe5HxZJ6+z2fN>GKYMgEf^VPgLSMJH(0%z%aO;*Dp;>|B>ts`(f{bUF6?ML7 zpMG*9NWIR8B419WNLP@9Jq-pl$kfJ@oD=n_` z#&pemCNJZqMi$(eBnVey2d!mN0_s>>z&0sHZst<^6>$w`LLkv**a>c8_l}lUPpw}8 zt8ns1LL{qPH7wyOhz$zs=;0;UAx5&$K1kyWz$k9I8Z6Sk-l!FGZQ{RFsdmvS;bA)3 zrlKZ&$+l@CqfxI?8H&+|+*c@o(8o*TmE%=;(-=B#XLbV&`mCN!;@fTo(3&jvX2IAS z-YmYsHSU_z)e_s*4uPsf&k!EA=JaiHxIqgRXES)8O1h!wdn3>EbhS+4*)-_#JhXfc zc(_&kyk}y>I8b5fJ&4y9Ecgd#L1bifVw|DS3Eq-UPiJ;sXnu(M)>C6Z8{}`)zmev) z`jn2k`fvYX82n?_$g~|+LiQ?-5$1dXHw!Io650rfqtp-^q4SUS;jB(((uhkQ?Fxup z#kM7`Ffq@Mc{DGA#Tk?opB)2C*wT_ z{(O~8Wqz{@OsKFFTH>Fw1*OVFjIeeZ(fXOcI zX6~EDc=;2Mp0ETj;@skt%#g6`aP1{$2hHIEcPHHM<9slvayb>2Yrr%vCU9Mjq0MXD z8%ujHQ%V%Z31FG0g*cD@0(cDT`}+MFeIajd?vHry>z=0u0Ov(gxakzswzebWp-mmJ z(S>X_S)eRr(@VT7*`dezo{Ww*^HKqk9N?e8_ZA+<9wP z6}~wIdYq2w0+B}-VyiL0;)uY(kFmr=o<~cN&XM_IJaF*E-P`yaBP&mJ!-wIBQdW7< zF`V;N1bdevG)bLF8&G(G{ACg6TDn1Aa`Y#$b{(MmOxA;v+Y+;pD(J0%5ko*!t9c{% zPG(feVe4fTSrqJ|Wbh%Ty$#9jHe?@hewy_q6Tq~D$VjC32l^rv!A7x|BR-0api71A zc%<*2?a9MKc6KPtY3xlRg63}ndKXEFt~(?q!=$&L?vcI;gO>3*Dc;gFTPnjH+4_o@ z{Y6Lv#Bc}EqRilimSC9v@}1Ae-@oVc(K+MRIUw!B^%Cc!dyF~fWhGQsGE0S!KW9lg zLXLa_7$=t6BC(WYE-EF5NTy(&jGQirz3$FQaYDld#&F)8U0aPX1FfDXi}Mkx27wdK z-y_)jNttJe$bwkKYRD;|+9QQ1!9!O+wH7(VM_ySYjupdnsbPG5g#Md3A8&1a=$m059I;>;u<_>K5n@R|2~4qBjI(TV8m_0nhK)f|jhc`Cl+k*IgI zpHUfWOb?B!zPQ2_oGlk=;{kf_`T%V>K-WG(i!wSnc?a&aDA+Hx5`TArG_qyvKP%Pl z2x(wbq3*vwM0p9j|4Ko8%6+bYP>kFH#xqR+4ZD1LB~U(u-VU+1V3)mF`8u`&S_MN3 zc#jvSqcc(mTnWJ6E>44o)Lk=()v)W}bab3Ym@(#xar-Uzx+ZcZFl$Z#&dh`i5?4J3 z+41_*kYBDhlW6unrop|gJqP}*#RTFgpDjlyd}jF-5q%o$VyD5O>~sa#76>hXF5~EY zgyUTawvV7U0%rxBYSb1GvMT0Ez!O>>deBWmIFZ$%S}3-iotz|-1XYc_Rfh|8w-zTH z&Ei+_Y;@;}Ib!e#yAAHN<%|-H7O(>!N@`7!iyO=k zrJJkVhdS)R13AJPv#7wb=3`rQ1reLiQ!Bj*-Q_~4R4VQX_+mko~QqXG#=`mX} zMlxTd2qn&^3~?Ign8_LayM*(2UnFi7VdTOOdOYT(D}a57d5MA+GW9cjE|-t<>Wv$( zpkG|8>8~x_HHrlLeqVd7*Xzh#&Het`H?gg6A|7s*e=p@BIf*7fkV{qYlPcd*U12?` zt2jW$oWq&2nQ|!w0DC}$zvhFMlK36`ZRH|$w}P*~rjB~SZ8SH$FAqvTwo&>Z&ep^paWWacjBw-gvlHwj;aVA)L7>|7Ml<&dCIBckJCr}ibxf%!^s#7;r z11DkT?%lUOg!$y&(?v3CWg(J@LFfbMenyd8GDaKEH?d=!;zb~N!7S#K-Pj3d;tq_Y zGPh*{+AJN>Xd`r97&kTGYIBWEl=il<)go=zPT1x~i#aCMZ`G73tyNRDP_=40Ptu}- z!ooa|MAnS{NS&7=hX&UUL`Ni$eJS2+f-yJt0x@xm#KlZQCb)ulzQuDy*f~(w!%_BCs8FlG>O`BtY&AI<0xI9UBO2mnpeS)E7(xVO{}3YuM=HRDi~y7yT(cYtvV;c4Ev&h zxWic5puE{{2YBkAll75KpM7AFj6wYf>{=jV7sp>A8pJEw@Eqznuk*fkS?@NxjiHl4 z-rC96TwLwr54^-W*tHA&QFc+YZ`nnBe3oS|*GIMZ@PnaQ0{Y8B?iVX)`BhTJmmy>P z?t`J0hikrbi8ku8^-Dnh{bti!mQ3OiRrp`s)Z?DxH_-D8IW|QfRst)F1^mSVCR)HK-6SW%2+R$ zBZ!iy4?2^C!qSn1($Mx!&#UKGz3-@7*l`4kSRfqw!Q(oGiuA6>pyEq?D2~Q;KE>^G zMW3$?_B>Bs;Ys6YTtD>XL`02^>s6-owMImGKb1%Ilw%G>{#M-EOwcHipCxmV7iHya zR*)88iIkk9XgXbQvE+wB8F;C0C$pF|N6nx57z&%x{?H5lCjQ*I(_3xp7+spZtjSX_ zK9JVN!yAZq!VH7TTgZHe*mz$Igwku{AdKyH%wxTe)Xs1BnU`s-|7k6#zx@5*4E0Cm z2rXB_;Rb7dCpkg=XSHI*9~$?)w)585^p}$)>|JjQ3)Q?n?%r=LHLUT4yLH!;6W08$ zJ%qnv$-tT4FOMy(BO$Ewk;4#H%LGCWXmQJsqg>H7gFAbV_YDQFec`BHTrJc1HHd{a zXSh7f`p1`nTmQZp_7AQc;jm(jel)-YTaz*+n7ML-7{j#tddYKvqj$V6!Oce)=qGQ)sMDQ zK9ZQxc7v>YxUBnO4Vb^AebN3P5obpWIjvmI0qUy|(zvJhD5CKIwtOa@UhN){L$#AJ zKC~%Qhz47lm~gL+nDDXI+9NDT1iO-g{^shLpIX?JC*Vi1Pj79lI>&w~YiMps?@9Kd zSMnFJH^p{bl`GGzw%`U>Lf1Q7S+UT;=@bk^FwbVmM3hNQaB}A{p->p$&8R{V6oxoD z!T39@Jd5u^rNCvDb5%aB-Aylm{!-85zhv#*0=~dzFV?>$y#9WZ* z;4D}}#>In?j&Lcy(99y?F&Em7W{Szl<|>r}<}s5+*pLNaaklaJ`)7NP9*lMlcDIjq z#~RZ@xfW%FSU`-me1SbiB{_rvgA<%rIg?q^Llx3$fcRL4>NLY#KHNJUKfx?ZPf>=^ zrL$UTbhW?hyP#R&4LA;U=8E`rb2mId>!;7LgzQ^;iTU4InIpVaR@7z$a5qFVB)=I1 zLV`2~v++6VBd}RU{)H!SJh#W67WmwVItA5b(08wyAyL^PkuZb{7l|KN#-WZQOiq$% zC92Jwk+5_zi70k-xq+6a@=BqJ3%4Elglo3Z=L4rd^V~Z+lRl^gYpoCpLWeP~5Ys$^ zR*!1u?v4mlfOW~SfH+?pm=l$KASYi=e?i_usuv`gqROd|2h0T z{QQqkqt_4PXd375XAFPc@6D>__nrGz{qL=NU)=p&@cO#`_j~{E&Yj@AOwQxs*8RvQqobCG%vUR=rkzkmOJ&Hn%L{{1h$ zwD$iO_qOi;F4(-@|L^_38^P^cw}VNBRqhADqCC0%6+Xe!hh%D$!5{A(1&_E`eb9v; zbZqXZ((v6$FSrA1cKgoeoz37Nn$OF>Vv8!%B_+*?^Z0m)Rv3^@rhPcAW6H}oIg9es zxG(KfT-ZLyj!`vEt_7cdf>r2c3df+3MeZs8Pf=u(giLv6T--@A1KFaB(!ho+EWgp~ zfBFd~nT+B7DJ)*{9Vt(;1-iHvWuA~5LSIy}M=0d$S#qB65YQD~PY?riA6gWoK%OuA z!8u^_1pkd`W|V`pIP0UTNvMnaK|zU05v2eWOyzT|0T<6^*ahb66xU@5U!SInvJWD) z6lkJ>FV0x(`ScSt89>tsh!ilWNUI6gwT#9j+lXUzoMh=VA?pKK9&yd71~Scu7a7eZ zLZqW*m{*G{UKMANtp0{ri!nYMrlw6PM+mU;Dro>PdJu=Sr%Ja;qtN``Ves_e$q#!E zb{_;A+lTObqfhndu~t2_IN07l`U#8HZ}0yU{Aq9hK|k32H%||C4-Y^61nby8e)?!{ z7as2I?>u_;U~m8X;9K}`{|Qj_9*{Hidh~>f)r-FNb`P<)$GZnR58>zbw|kHFj(&o5 z`fl%NA9@YGgI>3Tr`rcddppk_Z65?rpB+4Xa<~fsJb-@p_x8U#fMIqY@9rOkFf2R^ zc7K2$!QsR0M~`r>UEIFuQ{%FaY8dK6ygDz=!+0+zsM8FqQ?H;O}RLyBahPcDElv zZ-@A`-Z~WgtB|6G>MO+$xHR*ue0P> zpG}gTmE|0t(0oEUi$$4Wk#c@0qKTLCC0f9@#WUF^P8a722Z!@GdI^9W;%!p3!0U@@ zvXfyZT*TbYEGv++?xkeN*cQf4gbB56Lx~T}WAX_8jPtHhYm?Jmy?dLE&muF zA7+!6aoOpM7k`T5`SvV%6+Z-qFpG2bf&$)a--`aIk=yA(JmI+*uLv|Ysk;rjyOb^w zCa?Jr944n}G-D-IbP~foF_#|_qq&HW3;McJ`FreNz|QjNC;@!l>XQ}97{+B9bkIEkiPq=Q=vi49v2*_-;0Fp zRHTwb4qeJr$a7J|DkkNmP-QdelG8}qfo(zP3ntuog(I}2BM?+{1oM2y=v6V)_G!0c zyzBIX&ODE&7|I>9XNyqh1-xxL+S-24;^qPTLuYK94{Dc&N|g?`wl@2C3=QwYjYVIT z8-}4C&MIh$C^*I9rFjNh2$8_b;-U=TJbSqM#BSms5 zH>6Q#&Gu)G=GLENCoTL6bLwo;$R?73q`__^AT#SBiku54Q|G5g@_DoG+dqQ83e zOzjrBIr!Z!F3^TA{2=DpyxX}z$Z^y6Oe;r~>$PM@Qq%;ux`6|z~iz;uo~C(a0nyc|VzG!aV%UUf1Og~MxF z7jZgWqd7=wuUa)nhl6yogtjNMEGm)EPdauZh3XM@i1&9QFQB>CBj=rdDCLXPVQm*@ z$t6+-t;(=106c6@lig2A&o&>7>jm&d&9xY)jOzlo^R@3-+!T$5e z^9oKvHO5b3n8NkL!W>~S7h?~6X(Yr~P+ABxT zl1_|G_Z6=v9u+k!Q%`ON$!%@+>RTPd#9#Vf3%Ydm8Q~GL1F}>$K)`eRY)G+ywT&7l zK@&k&5nSjcFh>E(h#nT*-gDnM{i41@F{wYr%T>@<=4A84Z0H*<7%MsiR>lXERM~`_ zTWv%yx-_d^8<;vbi=Wd+K$zlOta=Q(=UDt17&%Jl6I5{`XYUPuPHz_IG}<-i1NYz# znYFtFL$6_Yovr(JDlNFf8C&qTS{_q_(w0ZKd5@DEsK&zm#vG=T%{v3dTpsRj9~^zV zyM5HRT1~Y^QsAnZywzc#`PqY;r*#pRCfsG>xyH1VNHp(W-(3h+A3s||{9)3SAJ&RI zs^{DGI=MGM`PDbTBL?otAc@VAFCD_u`_j}lUVUHJesH;KPqDx{dA;hIvEqWk`w?+C zVn7oraYDM|E{J@yI33>E?6sHq*^9+1`6KpWGoR1b68*Wu_7{L=`Tt>Z3Re&YO{|Q0 z38)6LE&-hnwsAou?rPeb;1;HW)Ystchu%fTuD+6;R!e+g1X6g)SoQ23p$+FSFQvyg zAekLRYN3}6Yu-y7RT>$V#KpEkE$K9-1%PRwc;1&mkb~fOS<==x?sR&=?Qf|5pS$X; z^N_ocd&f?P_&=(*q4?LGm;$-dO7EeN#t~RirN`z#M*gT%sG@(b?zfM#d9Zi*bo*%M zq3(w|iE+E4%T*XWz<4i;P8W)33jaX?veeR#qKR~JhAztoyW0vce58mtiwxZD z?NbmBtiItA%pZHGsXp0pqI zOh53XhQ!`kqwSqP)pfa(r6&mnBlCX4`zj5K{2r{?F;0Lvla>?BC)u8M?5c~dLazR9%j6)&cXv!KVZ6KRFoNpcJ$qMc-+iHPPve3y#Ju#z z*3;j8>D@s5?yI_;0Pp^w(P&_ex3%e^I`wkPCJFt^I}L%7EP>IHOKJ?qKFnv_P&9Nb zePsW|fAm}34Psa4^KyxcKaa|Z2*m-;Oy}1mkBYO{(WcAB*kyEnJdIeu9taa*)%_`2 zXp@OJ4QIk+Tif4AwSbeMAFBJCPw`F~7JRJy>=^8d--6Uzi8CoAUguPax zDFsdOiNG;a{5NeH5fL^d>v3Q5&>`Zh^1_fmd41I{UQO{+IB8HnRxs9%3cErzmUgAn zBu|bXh-%X>=m~uAGdj!AQ-TUi(e*H!;U8d1_G9lR@nojjZA(*XSuThE?Iy#$%1~}G< zhK3gH+*NJ0hh}4O%E4tcFPPD|UxebN^QGi^;uHDAXy+`1@fN2(qS`tBk*oLS;DUac zUnM6?GEUMXqg|u*5&JPV*{at3kgmagXtf6BhdPIJgg#BhMz3vcTdncT4@9kvjf@L! zdr<-eZs)*Txp>Kinck){W^{N@PqodgOIg89w2@caLMQck22wU3e7KRHJPjU#*qUhq zBW<+{w1~r+$FH1&NCZ(a$Fa0(>SIX|w#HSk)(a!mhx&^9)W31sQ$Z?dJ_6{45JE8a z1Lbbj7oJwc8ZBn{V}w}&$OlRZke#W#7jr_KxGY4{3DMy?v87ryW9+jEEG^316XMAO zqZ=9eaG*AQF{gwzQ9*Y zB?5;W7(L=QI`zZqe%Jphj*?~{x`o=Zpbm(Z7AJdP%r&UGw{%)wzf0E%_ zv=q)k4oBNszpmwRo?XCU4b3}Mm{F&;`4q!B8ojL5n7RjuGkF`8y5`cZ4Q@mn7{ zr2G%xpo!SmWQMUTWECyWvKeCk&KH}$hMYML!yhJjLQ0rIE{A>qdYbuqdj;R#HJ`ur zsMPInUwtHy;*Yb^I=Teukt@LS4ia@d<-(0c=Y_cVxfUiRtB6E8$Zx73VqH?v8Z?iL z-|&b&GnCe)0T9=r8#YmsB*>EfW`q$65Tq+W?wRrSaygGFn*eSeGOhXitcAuXj9-^1SJ?fCzGiXCU41hQ?s?oY zpb5Nwe*50w1$uNJcYc1oxyk>3a)STgsd10d{A@;+eygj)*K7J5{+GU+#@!BuigtPp z9&IahWG#Gpq~BYM=B|qzgN$SrBApZt%C);BCdkt0ZJ^mEclio))8j189j+oDVXyVj z4rzW7r>Ak*#jUROCY<}!+o|c?`WO9O(dk*I@?RSGxUC3d{ufGjtYuli-o|OOgI0nXm4klBeFk%g?v-5ROWN4Ma zthPytQi5e`B{x{g5E7-n&y}*T3aa8bshM!DRq%y=UtK|H2hwI-Sv|5jZYZzYsD5yg z`Mp<{(a;kb=Vyw3KI<~OOOV8=i zqbI)kRG|&*ja%u?R0zk5;B#`H2{-Hf^$cr^6D75OL1uCZZyI3&S)fYKN|7fPG1if{eDs1P{a$XCW=r&_fQbo z-UIyI3+psDwy1@%#Oy*%xa{?9q!>#U&#Xnm3&Vq}TQ(iNq_)*iES0gq65l_fi^XID zC_uNNrMMS8P#gIs=1`|p@H92r5bdyS-vk}>8`yT^3sAkSj$F&E_ng*6qu1tm0Zn$2 zJDeAm_c#5mYm4360RkgqRdg#57tLX9xOB0Y`aB`H;nZ?`U=#2(e%%);YOI!?!m^_s zuUn^9_JoGf*C9^|BxW|5_`ny6HL z)9iZfA@RqVa8hjvo>I{JqKE7-26V)PXP!>QbP5m|s(>x{t9PkM)m$k7Z3KM%O`_cmm%1D)2{fe=SF1L+CiREFE1M0 zP=sT1Q$}G5(Hswg$8m%?B?|cs$Qk8DOhq9oZ#By6WI1V3a(9l2H56x+4C)H_uFXaZ z6vZVo+~ceDs{9HCl!osY?4S{|^-<+-ZDcKAcOSkxl=j^%^4z|+ zxp@!&cZ>es+M@rxL;ri1{`a0o>!lg5J!|tcLr+c93M^PFt^m)GHJ9Wo23Hg5KS2gN z!+40&oMStze%m=}TpO@s#K-M_0sCLw*f~mKk;)rCh%%S~tIp}hWk#$I(yt@D5<<7v z6)p-x8Sdusa&U7LpwNi=KdJ;G9QJ=ad|aGjiGlEF_uu&Lt{M!EW|CBF9@aQpIoP** z``ZUUeX!wn4-TFj4B9C>NO@*z%gl>_1fvlO*bOciJCB|mVs0=0o4x(->t5~lt_pZN zACDv2bfx87kLv6@-}UIc8`z@eE?4m}-7KYONkIahJ=IP<;<-}$gOF=|Ih|3HB1tjD z+a&H{(mKz?>+sGJF1DNooQY4mdkd2ZMuDJ9EQPIW3b)SXwPNh^=bOqquyF(b&Uw*1 z{U0knNUO@xW;csI`r~;g&w)NygMt=9Q5#T2&8PN2+UG-8LvfvIio2v(B+oKdr(hu? zusF=!2ra7^qv?Iexovu_OhedzNA&GCcrm4r@~bFw^D1J(X(-2Bc-=G2Qm%C=+gw;? z+zWl*bJ)=V2G5^!7Hq$WZ8{CKq2SA}qgXruq6Q~b!T~>4Zm?JG@p8_!?C1iHDt=l` zW|SQB1KXEu<^erM$FQ^H6#eSwd6MNxxonGSYej!!Sf9YSr}0SoG*l6V(iuUzUy~1m z_z|7FlpfrKVG_@c?{9Xf}I z`fRBF#1+PZV2-IvIE$dFDS-uZ^h^mW_iAHd*K-7r@i}c>0fa+IlP3u~i@^UjxtY+v z{Z+m#i=v%JK*35^bL;rs0fazyD3X0_+$=WOg%inC3`+WGLlb1PM)BHp4WJmW5k3%< z&Q4g#)KJ#6S(z$!$hS6lrS4XJ8+d8&Cs7AKmD?$-8T7f3oY3j}Z$w0wG?c znGB*>cg9wHR%?Zs?WO)p(V_n+Xeg@-QChjv+okMAf+q)WqmJ^)7XVJy(t5XkoGy?d}|no*q0odb0E6k+&0$j-JYjz3BT75>~!sZTC51l5}s` z1s!lAxE$vv3(av*?Dm77RtI2Lm{JvtW$`sl$HwM5&Yd-_Pk5kB0^JHkngFlXPR~>z zOzWcuyN5dmdryxV!qvY|UUBvT5sp4V{W`{1h)O|I2M>o&cenpkmqcJcE0dEXHe%5^ z$AT4_U5FIh>x85;lCdvBL#0Sow)1F$wyIe?Jylrsq$nsGlM7H5Xbjac39Uu^J!3H{ z8&(N*tF=HrXn@k}TliuMDWtMVV!)v2a_7+=?5mNJUtuq0OAu}#edLFX$Yvzh&j zko^oB^hzuAHJ;0hol=U@(G7%@P_ILh$rtOj4g8s@Fd_YA1!Zfu_0@3{SMRW{Jj*GT zpf*Ga_VX(ewy9~}<>u;XZ?%)V_&`2t680`HtJQ{qT@7m24gb0f*2Ja8_yV7Wm%(zs z-HKo3Vq7*IL8~kR&NdeLd!)gegjtzDpe7kW=K@-O{&^?(Ool?kbf|(dJn4M?uU-xB zX_0DFqM-`1W~6b+k(x{aH7Nr6f%N+yZhf(4zJS)T^uECVc2VT_4ewSx7kHZlA*y;t zT}-wcUG1@Rcq6zQ;<5EZ0jt=I#+7*ZsEBsjbW29oj!fx$k&^)V9qzi|Xt=S*42WI@^8DdwGNtun@+Kk8Xy?Hn ztl+(r%&m>Za87^{e|kZhR+e5iTG8fO^f1~42*-A~*6NB|tq9tInm=qn)%|30SzJ|C z?irOIw+w8pc_`HP#!yq%X?i$mdH7tjB2aMXT9e?jDFLUjwoS7!8cdMcspzEw(di^W zGlJ(KSjT#r)QM9v4a)~<8p#Y2kx(^0F0N?iID82oe#NJYbe0#+V(5N~XL$l=5iZ*2g*jBYl+-!Nr+EJ1<$s3=F99+E|!W~g|Th30nRgD<$q z_WD%%w3?`N?;HhpF7WUG{>L5#^w#z$5Zs==SU9$X07ujgAXW(6A@6doj(SF*NIuS4 z7YZ2Et@&-f)=)6+!T@@If!#A|d;frz&w)Y5?~@tGRQ(!*$BS9c^tG zgV!;$R~ThzMBxl;cCH{l+TncM)JO=0^j?EaA9=unQvQDI3MJ(lL#9u?lJrf8x&Sd0 z`CiT=OLgh5V)LtZb<(dJC3lo`w5a-KyXe)jLKl`>+NB!PL<{roxd@aXaoR`s>`NZ!W%3Uldp&bi2OV#ktC@WnP-!dH(nIqxPe}zKTD* zNaA5KyPq8M8~m^A@5aW~Q~ev?Z*D$*^8HuQhp#@vzd6c@(EMEw@?YfN)>bq|F1fS$ zbmQ^Ur$7GX@el2dufO{8?|;cZ9cpiVv;CyK`AEEY#7PIHH+QuDpFVvWUjJKLkDqRC zIP3q(#^cSeqKz->|K9&SjMl$f$4v+h=-Uwmb;38eX^|w3&Ur6;C(%BLofAA0!2@k+ zyV>++mR?>JQFE{c!u;lw^{ow%>5t;+wD<>>c!jQe?23+p9UN-UZ=%atJfVEN7qf)U z0wCedE|V6e(3sp{E^H8{qU^j7d5b|l89-B5v_NSw&n}8@?w^fl!1!5!DvpZ3;CH$QDfGR zk)r`(fWorQbCNu!H*{c3FYs?dBb(08;RtlqLL(Gmf`*A^;3c6HIt4>{#EwO1n>9tV zB^s{oUyFu|@&6I2g+LQEe0>GN9F+a$Yc&{*P!8uAXp{|Uh8duZ+WbvqD;c;K zlMxyo(6LE(sARBr@}e6ZA3i^M(>dx!z2oTB(cv$>z3yK0pmPk*4_eWi-pPx@*C!E_ zIO-gn{2CoTk2(jxMt|=efOy*dPc)N1{^sk$qp0`t)qW3U*51MH{_8!orFjMw4-SE< zdqB>lmDfXB|W-hS@{FWaB@P7VNS^cf-=SPRo0OAy?91;|9^@U&% z-;p&fPz0Y}A9s!3>~%Z)0PPrSo2A==pM3LmIwn;clGZn0(@A6igea^vBk>iZK@W@h zbVQanRH`k%kpYZ+Imb>8Ztvc)ARe<+M|Z=oZHzmak>8WSsq$ z$}(MiP+!oYNA+8{pX|}OiVNtKqDpDbc=$eICSN|wir2|G#vzr}-teRPnhr0MLVctsMKXD=KXvdyez_RMm#QPjH+hka z1rDF%7d@ULfql>-_?~{prvK04Nmqov){CLpkgqW!3%kIRkt3>Y`ah${wohJfb|vEr z)?;EmPYZIBqpdRiN7ArT*;9?CoS`*skA0M|V;C7j%hVY%Llu{jSu#Y3X4-_2d=l z#4u3jb;do-$p$$2?>S|nDhKzcWx%0UU=heGz-RM=7s%?!h|Eq98x-E>ssa)kWz_?O zgiyl>o}VXVju?*Deiipf`Gkmx44o?&E^vfL6|+Zq+=EIQygN< z@z7*DqcS-Pu{ySE#2{MRXW4|K!S{_CXVg2lfbp4h|8jMs*`IVQ&I9y>6YbCwR7uBk zK*E?}$OE1f0A+V+W=O;)So&MJ0a4upZ!u$BOWWHn2d2GGO)p}XLe(mKMDNpBPP9nv z+P+9IUhIb1Xeu zZvAtew!AV_84Z?$VpNoPoHi*0R1&Hv>1gN($hI<8*>YeSi;VXhBS(1-+qY$eW67+yHDb%=d{sl?yx&=$1FM%$BL;^^}K-7$1#Pd zTsPny5lR{{tHUl?ppA)SCKqs2!*F8T5$1&{qo$6^q$R5bR@a8 z%-4b8{?dEZKkEJr2jkoZJWwiXChg0%N&tF!DfP4K@ibktVfPMx>0vnASNomg7YaP?#0+kVx9>({`7|Nn zJD-kN*0eg>J?cI0b@y~PNtR-YqHAfCn6R_*2CQMccHdHA=U zT@O*urw8h>&XE3O17;~NFn|S$lMXoYJ%awD`a}cFuV5bWS{bjN_#ytxJ za&DMI#)DJuO?MwK4~uB`sM|g0cMqKExWtnQQo>L;*^Xc$lL$7cBvBq#yrPyAmwAy| zixC8!aXKHvdBWt)zA!AxMOaR3L@?Dn!_jUw;~WG-QWrlsfOCH)sMbG;(+S*!4d)wF zq+Q~kN9v0Wgz`OWd2{XREBk6DFX9|MRXrEbfjK__Av`ZIw1?`u!HSVZt9Dqc&>v-k z7^V0+SXQ+nuH}e!cz8gE>|`P~F7ZIZ``&Y4?f3IhR^*e*fc-Pd9!veO5MZ4`MR}VspcQvAOl*A|P8q zAZAClp4dHkvh{fD#~(K~Oeo)nplq2?zW?#D1!Z&N@sCe_c&fpCs&ME2j?Ef{9j>2X zN%9$-s88-kdGZc@GuK(LfO2IhtjwVNk$gU}V|D;O8UXN9*)3@f#!uzFe=ASW=@4V~ zh$jmwM_XPNaC@3fn;LkFNZ9VKfe0f7tZ>*ZP2z2$kE}jr1rHTG3DRAP9{m1_nR?5A z1seDvgoR~b5(*UD5C+f@UJzW_cyXh$>&%jAs1hn`ke-^3gB!DLx!*|>L;Ov#wvwUY zool&gfC_=G2EKBYii_eNw=- zfqGjhVb9NC+V~HaXur*WLLdzp;9s_ABU~hA_M=MiQrFzs#H=7N5&Di@4WwJSnNmS2 zsfE2V`u562V*suS&iGIy^i3}?%M*J}m;wIHpiF$_91pJikge*fG-yN4n)re;ngx~= z60KfRHA1PD!+I;=oVwaYPMJtnqtlx<{-;S$+~9@yPG-|?T2r)EH}S$lMkYvdWV*vD zDt^9XHB3ZeD9$b4TLf?_hp6w}sW&@Tmv;QFS!1oPESQ6Dh#N#GT90F&EN>Gw6)>nz zFe`sHQ>hy+A(3zj1l0iFMC(z!70bDCDjjx>jZ8#rqgUZX2_-XUHR*=#603hK3?dlG zEgLCnBS7(7taJQn+wPO>PM23q2Z9RDvjP<}&1sgCNl~uYyi4J9`62rAj+-m>A@&#byYE4m<;yu3Cz3r>JkGcyIja#BOga$aZ4#mp^HcCRC8i(U>XE(IjWb8WQqG3DPOyybX<`?Z!PjQp z^Egj2q3n&$osMP(WVt4m$Tf$Bg0Tju#hN2?fnwX3^ z6IPt$**L*<5|r@lzL3o4`c(;Q zgB@iE)wFD;jOs%7vF1YXwGI|E->S-h8PHgG@Pir#vkC9c#cD!U7fwx%qQYyfL|bCE z=U9aqZI!E9HoS%m6_!0srf$ovgbFOXG^w=QVnQu#6%ai&1*l0i5)ItXf_d7Es zo6vbawA?DU8C6WF>YSCYGmsz(csg4H1iSN-bq97h*hgFrp?tp~JJ zb6W#?4XrO}4DhJg2gxp-BnEjJY*NbrRFo#5%@tfQsP-Uz&7$gD&>k)i%d9Eh+Prwo zdEzF%$P?zs!6W0CPrfFHF6Yds&M=1uooEKphL^NL*+%(HIGMqpcA`dhae*ay5h#6} z44l&sX2xSo7+OT3>+{bh6mg#gSoag%{fNVBNcPhq3j*TaPdm}plMSyud1+LG2-W>k zNEE41RxN^SR43?O#=h+QH-|=?yCt7c7y$wG9KfQ;LippY89e=T%~tIhnGY5xoU!MJ zbr^h8S39F8rfIQ~wT`F7O`o=SwbifLc#+$aj98+$qq-CG5o0SKWm#50V!VAv23t}Q zA=|ZP?@{$Zsua9f#$0wp~5ABKc6%UyUbFI=C1S%)ifCG=_QaOA&Xo z%WRe=i?P4UMQ_48wu197kA7#IcRK}$^Yfd&Kvytkn_RAR>lT$^UpgeAvx8o|hJCPQ z-IyC&6;?E+3z015pxh;tC%}R#TqzXTAv-$>!*)5qmh!6*F((twBqSpa@R`H(#8948 zR(5N~iJRWqOmI!K$}W%|OY}&$6)liPPfxe~4A~~u7GOU}m6x+@J|#7WsbFRr6;=UXqe;s;=@X z#?aseNNPS;uo#1GvCIlyuJ7I+?ksr{&v@%tmIZlyr|mNqzg5PbW*?~OGrfV4t6so) zYFN72nZlS!bGGSLsSIE%%4^A(jwBZHd6%Oh5gW;pn~B8TX6|k#lgzaJ%8};8)Y(FCr#K6vQeaM^N4emIsK5s*>~3izX_jA} zRE^BKa9Eu{8Ve|d3_h?aV|rg=%3z8NAg@yB`q!5yS0JHUejRma%)OAgHxdiq&D{Bn zT$8yWInm~}85IU%7QtRJLj{)06b&L0mGDy%0%ThW`;H@akr~1f!=clIh&p1p&*4U9 zMHY}Z#Ao+Q1drQtoJD%S{0wc&2HQBO4lx59EXP7l}xWM^!2jFJ63o6 zm{4zHgY@FsX|$mvS9PCHVp2d)2YqO2Xe}}NkQ>Qc@9z1O?GdVQBK#*7V@1XTH}Rt4 z@#rYeTB)F2;)MUMjiLAHl;Z~|f(VXj^Rz8nK@=KJ%w;%4$Ce-#Rg23aQFNdRjnePr zcGQL02XYYzPbgzRmQ91!j007~E zjpv}JSFjL~Hf{o1qm!^Ah;FaorHliGa53@#yyEDBPDCHo#3BkH#a1(9BJ3@^YWr(z z*|Amf-7GrM)@NUIJiCG8D30w`3y$%O%gwbn50IiXc~#gi*=DG_+tJTS5pqgkevGl0 z;2L zszCXNa$Km*M%-`MYu+4)a+`&f1r3TM26(Xr61{lWxK7Tem_CTzakn0qv4=@yb~7{_QuMV3hxPW8Nq8~s2Lv7n8<_cgv>^!f+49)u_o2*;QC$|xWl%3O(C|Z;R+qQ1o zwr$(CZQHhO+qP}nwv9P4PxCrov3IPhtbFP za|e+iUuVC>HSDzLKwz{(ln(xDuO9J4!Up?O@|agC@KQZ_9egqb>|48W$KLxrew2^W zv$f&=bujU*7+kLzWJr)8Y$LWcOY)1q+2Lt}9?PznIT~j6(df=Ic!)KL)wFt994T)= zS5C)a_Hy~pHK%2&7oaV1d0Jj2Dz)BrR%`IJ>`QCV*1Se*ocHe$T2p#64fF?GeV+S2 z%5LSx%ShKBZ`-EU9SCE~>#7~KjBNa6nK-g!)K0!zc?_qUH!}p1_1{5(UV8*Ti42Cd zRl5llX{*l>H+oV!3i%?!Wm)TJJ}KIx4g2I{XQwQ*LuJZZ1KLw_xEk3~v>UxKCTZXk z@Xg&UGHhEROsLCc>GL<@8rBlOK-ZK|$tL4yw(h43&xD$zn2MSqe5JAheO{vIGRj#e zTDt(RluC@Mk$(pH=P!YM#5YJvH>kU<%mg2h90Vn~g$q$LQ#trtuW{C!^g zZ;@du1$!9z;g}@!?u{!ZL}C(L$T)adalK)Q8uAZIDj~T^C%%A4H1&QG4vNp!TuSD) zUQseVuM+i+iBrzUCBHcZAHRSLU1F4jnes!2G@V+hzkN)F7V7`drnnfgeb*rwi0qC# zMsoc7BvR1nfD&oim@CjOpKiz-jLrB)(qWQ8@WTy1Og($e%ce+4mL*-5N$q+gf9uqQTo9r<2T+WZ12T~Xmcl9k`CqEC;!>B zTI4d^L2wT4kR(L1D5|L1IWRs8uMz*NCvS%tp#lufzx$p?Rz0tRdxZ6tCw~^7%>azc z9!3GyD~TxtID-ELEAnV>XlSsA{x|0I1%7BrO;tO;n0YtW==Nm6AS zWAdO0RTpkBV&%SsaX+SQ8)GAlY*K8}@FmuW6bIPP6Iz#MaRAbe|2YEVzHyy1MSp0X z2)B#KO0R_j3786oCf2XOOiu(%psKtdi}B{eJ(}8nw&4GF{p=ARGslF>r>n^jOFbW| ziRA=4TD&y^X3K1WS~c^~oSd!3 zt$B^c26IThAop)Fj(2})>xHbWJ%<^WwL9IHeU(i84kDug-+TedIQscUv$SMNR8w98~AK@C|7T%gY{$D_sAm#+N;-_K`z7g zxV9et2zZjBNN`X|vcO&hk-(&)szyE^cokLbXcrO=dNJN$lb8)>acvVuH2DRTv(B4a zS3^aQv3_Wa6V50XxALnkdKDThP%e_9mz+5fMwJ_7r&AMQ$SrUM zEw>(|>BWd$&u=Q4h6=s?5TIMi95}6NI{=An$xnh%*R^)o zkmE;LfsKH(`1v2eSb<9J9i7(EGD>dBTdP;`{J-6mdt9~eUs}=HL%%xEB@nd7K>!V%Qe+(ES?J%vX zM1TB40vz_ngEeYxxB-eMbDlzJdqjR_5RS-xy8bg#?xYV7wT zBmFoBtn}*Ua55p26ebqN(CtUqhn{8ljH9r8%@~CT-m!VdDfp|>2_dllu#KCp^HfdQ zEH|1fnP{G=9&;@caN@R-go_0b&EEeOz6tE&jvzx3lSQY^z;a<6r;Q^qhVquUma}s# zxc!w&GAMDKXOT}N==etzh{oLWM26xRc=AkX0SQQJWaIm*7dGeFQ7vw3L4snxgf1t%@Lr3Ah4=h6=sAws>yRo?7J?*N1Wl}=4XNpDC{qDf9S`nvY{1K{3)gB zf)AoeShoohY>I{{aYV9u75|`t;iC(3NL-`tlL3e#^d_Xk)}UKJ`oWhc1y=XA9vm6F z$SUi{o+xh|I?CQyfyQGNRL##Afz+5)6VKF^L^vM(MPK_Y-VH(d{)LoJb4@YZDimYD zOl!frP)1wx-XQ{dEff7QDL|pC?iNt42PASd?*YT=&$G>*9M6;LQ`1{*FUo64oH*bQ zX;IB7Nu_U=sj`XgVhBd0xM z??b7d9lQFhB?a#N6h4XCf+4|=vW!n-a}s$ajlAgPE6S-l3y=Q}bg5tAHgF^6ORhkP z(9kE@e1uJ6o6nJ?!?NJ&DNicUq;5EFnytkz!)HN53CLD(ZvNe0oVl3{v$M2rm~ocb z{6M6!l%-N;p!uX=sxe<0){TRIHI}2sAtQoi2+3rBXq)LM3jsWEVd$MS^c_pa;P;^V zU4Hp?BzzroGH=rWOabg(XETx4&EaG7`W|FRHO?#JBooSZG+9si zw-y?tWyv2k#?ps*F-_7~XhmUVpSiPg%7zLuT2TIepb9fF2!dMW7t6J%hLcC4XD!tK zIeBzlBqrO8*{y;Y5yKM>YE%?GoUG{7drtkK-l-*~LQ`<~(G3CKD^hjm`#M-eb`@i1 zr0y}z57?H)p=Xs`J%kl_Pgseyscw=Y>dp{!*awiIY*lH9d?OItkLG^DFnHdIdHP4abFk-LVjeWuU!igfLpsMGfgGk?ZesM;q9!(HxPG%1*fBJB? z3^shrdTovtnL?V&Yt=G{;%ouXVfm;S5_UQ38CHm$5T1ac_YYC>hcdH~zs<&> zT{LFa_I5spTPn0xDd$kk5*_)0P@(I=9;i*N<1s*=?O5zi7qHxFAryAFpKY@5&u8im zZl5(Ba&bIbCQCfe3}S>$V}#XQWQ3UIFLjBR0v7en;>@4s=0F>M^p`iqCKnr3rzKCm z2(UWOp(mWlC_4kaj%k}KW!rl8@k#ELqDK}EwA7o{$dVs7Z`dFA;o=<5?c;p^SlH8b z@mozyDk2K@`0aS>-nEZGbcOSz<09MX@wI!q&p+jtNG90YdJ@j!TgV)R4RmT4B{KP& zlRdvYmV~o$iy}X1>oEMU=hIr&Z>;IUy)>g<^0d9j9Ra8_sUv7hJrmOtyzg1I^XKS) zqeZh>_p5lYvZ1Zkxtwg)I^&Z_Wv|+zSa}%ZqX%!o$3=`8^a&N9ObxD7-;&lW#CS%h zJMO=()y22-K0Ev%;)YL@lK0~&l&>=)xh z)Oi(iRg)%49dL2R_U=d|IKqK}DDiuBG)5A|TKG^s7_aKW5{BYlg`M$WWhfD-3tcYs zSU-Qly~{eVFS54bHT1?+!e!xKIMUiRDkWCZ)nBL~3}=6)O)OBu1DB$>0G)}mejjpy#6*i9FPQ!3U1R~DRS|`pFku=(pE1E57&Af=N3g@b}+*JKuSqIKCNMG_^-*K#8<50jXqK;!C_(~|Cb_R-)D3!1g*7%bCA`SgR`9ZRvpf65nR2@_ z{NwYMGRI2hxFz1@G$N)nB$@neMuMqUDw~XGy3j~UoWOw>EKWZun>Nbm?iiz3=nUYb z3c+n*J>;Hf))T-UhO#9rdn6-k4pYXpQngCqO1Q z*o@hDowwQ3(NR(8SZ#c}WhOxu_Tbpr^;`V43)JibsroSEz)Y_WUTPf&A~r&g9lkC3 zgNaK=*r^Mov`7Q#AWLJ6LsJqbOas3=9qj#^M~ju0#>UPue0Of>8}qmp*k?4dB?e)4 z(0m##;6gB_gAkm_h?X=kM+yrsl`utItaGl}hf_7#!a8QpvfX|}#Fk~oX2@2ou-g9!P(mQ(%zRmw&)?gJLOd3gx@*nQsmPKioO%T3IB^1MuH}& zXS-}fiA7$LEpbYA;e`4 zNv(XYL60>|UGx$9K3s%4@O;2LhFo97VNRMM8BQjWMgvdA#03u}pgCB%Q*ibuB4O7S zQXyp89W*v~B^oF5Q?$y(_LIq()ekk6~^Dw^hGSHyI=U@ z6scQ?o_{$v~Ff8DY2zu6m#}(_2&DHocg13{mqCIZUDJ`#sXoBvJ?!y?6 zEefer!}=er+}L4IPO&=P*<%z!bhAb(6kL#yrccaKAQ1$mxr@2SlrHlPoZ(2$8pmUJ zBQX5;nN5(9N(X~jaBfi4eUQf&);?nUvFd{3I704VCd7$XuJ;VB53q0He<1(bCbSRL z+)D*aVjUA!)>vMqoVaxcuobMxtQi=EYwA(V{!$`6^xV=+l>nRHlJXO<2;~FkwYDgN z;#~yzkU~@joGE0WS{ERR1b(8ju4bq5RP_mSGjQ4>al}+=bw$Q%X}6O!sg@6bN*PC$ z1Sr7j-N#9dFSwv+euZkkn*0lqrOvsdLQg>#*1QtlJ!AB}0{|%-?woXqy#E#Yub|Y1 zE4hPZyU3I>LOZ6YK~S>69>)9Rmnm>YfQx+cLQ?XKBg|6pONXa@$q)PX87Q8t52vN2 z!@|9(!=7Ekh=E0EQNi4UMo^mi;O;|7z3Onfx7p7WHq_K(vW2EQRBJ|$V#gd!{M!ZD z1=d4WD~P~X1*KLI_7$Ncb+-|#9}#a`7C~!H?9Nwq;Z73T5xDTbehtQIBt)ODAIarF zxG*SuY_aQ4()NRk4C>asv=(^-|U+R+|i^YBpvC5(9jS(P6=*redkAYJKdaK~nO!NHttY+};Bt5t%zo4MwN{|U@7 z5d38s{4dz~B-ze17_cW8!;$MUA{$kf+oG5?o{2Q1(vE%R)X}SGHryM+CWW5BCAwuL zmrC+CEj--TYfGuP+TA&3iE6#6L8^*EM3UKbxr=i?@Ymu344HP0N|IuA*fKD-ENQ@; zHyI=2WKb05=%HiAl3O>`H43{>lk6&m0K7O_%DvsfKDhoExP|c>+jI$ytRu%9zu^G5 zin;JsnjCekWFL23!9dhUAR^sEtei|wc|^CaCexHuI?2NoO?}jQp~jpY!8d1IqYUyv zd@Vr-C^WdaPbkhxlcfB8{Gzyie$}y%2$}ZN2Zv0AtD#GdiXN0d@;5^KxWq_1x|uKf}kf($_^-!K@UqM5MwAa4HgSGB~a6D02;e!(eu zqsd9=rpA6bxAxWRkP+X75>}EPLVy_q{uVV?HjDS?FcWqyQ$1|lF=!Ce8c0+uv1-l8 z6pCSKrkRM5a1k(yQ_!}A$+8scHflf4_m z;P9G(#S+X*P*$l;f#XM5b&iKx;jgnVE!1PB>FgL*j^3jvZG~=l(r3Gv9qnK%)0SLO4 z0|tJt2XLhocZJ9Bo7r&u=hImZL(6Svw@AWLY0C!veWrvrnyxw*%Xo>?susaip*Xe8 z4Mfl=@8254q6p0-Lh(H9viif->2?snLxgKH)z-4|0M z<|^0h#*OX}h8i)K1EchXn^L@E`-h7t8>&QySFKCrx9U;QO8{{cW0HtbT0zdQI!VaO zUTPi>6a%iJ#(s}0Dk$#M@*&v0$ZvEzfe=n3uX3#pP?ZPkj3*pYs!Lg!t`ie;Y3uLj zu3De0{1*C>9hMvp?6Saf#m09br2hI+7jydnVg1EW;rYUu?8$_ht;S_tQ%EBHNdWZp zsv^t1o|8h2mDLzBzXMARpN4d35h=(>+aA=W;XnqWxzB>)9ajm-)B6q-h7&ZmWllHs z2}Md7T(I(-gpd}8W~7D#13B+Tfgl-hYXeTiNLXDccS`;d;OwFML1a~^0JdA_Gh|6R zI}VhHt+li;u^r#HlY>1^^R__)?_nC9#{zLup$eAK-2UAz5z>3ANqNT$S_0u6i&6qz zx9rl_l4jj9^6q;t=r}hf_PNbYX2OWe@lXiQiSQBdxFJ`J~!GswkD`@f!CiVJ4Fx#U8iK>gY$4ld`^p)%;G}`RX-85<3 zHn$#Q+0!m9#_z6&mStpIwA}`HHe^gPEZj#ON=w=1gsHF6@@MgmIa2^0(jlMftgvbCP z>*9a_KWVsS?WV#GnfcoyV`&(F+GX@$HtfP=UU{fl{-%I`Pf&9_U|b^+tfAifkouLX zJ%@T&xQ7Z*XlUy0~Oyaov8?q7v+85H9U>Ne~iSgfG`nEYKnuW={)TK-Rkt>xwZ%mp-fk zCI>yS_W*h%U(JH*>>tk_s>g(9&!*6&)|t}!7YVH5(=l2_{IEyT%NtPaA;UusoQQjQ zwBn>TodIE_IzNgV#j4U+HI;PI-`Cmoj8a)r!P2(Cs+P{+l>8F@n;!6vZxLJ(LNu+? zE5CQtfcl*vKEzdI0NvA*aE^U@zkToO<~wj#y=xrApQrj@OhS)U7AU1^&8{L6Z zSU`?~44YPz`rm<|nyRhVGU^ry(NCwDWrFFWY(><#p&d}0eb!=vR>=B@mN4>?zuNs2 z*8<{0|1Ct3xC#-gWKE%G6|RVe{EA(cU~|JsU58b+E#C89UJM+^KN!rsFb`xZOIA*j z8)r1MacbG#-gTVQn6h8d_4NJXT%HZ`^lc)lu~#jIa>@n^Xhk?d@$TlFZS7RRsXDd% zTO8glW{T6RZf7I^(|aZ!WxbuqDdi?2W7UkiABB3W!i zS|&jhufA~S9VJ=|b?%QDeE|P>4CB%*rc@s}(=MJj?_q&T=F#wo2^EwFNn1a3;mT94 z+YXU>W&wI{6sP)+g5bmL0rxk%`7X9G@H4_(wakxn^Ms8e!Ji1VbbD&OI@17iVu}@a z!rBOCw#cQIZkgH3^;POD-|f-r?`5GkCFa8KTRF(>LKV>5ahvj4W$=s`9;3s!guEWD z(hdVbx?T2ts@hstYIzPGFv`6)9Ti*V)M(h^(w}O7W0G$~Wm^aAafCgR_acRm6I{3$ zxl4i7BV$ocq&~)MqF5oF-gJVzgbEevQAN9fU?>JB#_B<&N}bP8zZ?^nRF)RtrDl3S zP>ofaC9oFn`bPQSy?}ov@ol3kSgYtNpC2P*=DV~JC7i@Zoh^5Ej}m}t_J=ms587K~ z8=0lCR6QH!KgQy;2bfuZ<6Ki(PPeft8Q+@ zNBo+YI4qmt-!k*`L^txIKV&$FTqu|zMQ=shg5}g3Oj0k}Ps%~sN_#FCyA?zTOZ3R{ zE1d7fJRMhcU66%}*>U0Mrj<~p*f3{1I~WP^*%GUnwlC{=tf6ks|X0HM3xa4#DK~Zt;MLQMblXa zL!7My9Bg1%;f^p3?i=c39Eu%%P<@nzyQOaR;dnK!lO2!fw42@m^os)EIAOG~ zci4SN*8PMouMW|tD=}sfC1c)bt_Fkf$_#ISr`Wb!UsI6$aWmP zZo*_k{g#__`0j=0r31LC;r60rZ=*0j@MP$<3j`XQ)KyA*9pr+VJ-n@`mEIr4{c- zSv-XC+Au+f)qLtlxv3dzH0r}VGL-k$@oMZXM)5p~C@d+l^_o|5aIIa{PL+-oNW!Nf z0HuE__2YkB=3RVendE6E%mfSQj2uUlXiLIuQc5xXp!&^wxca)JL_=a|^<%V`A-^1C z*5a#lQ9b8qjD-Ksa&EjQnYJ0)jzn{;Q49jZ7gYen3j3|3X2~BI1Xj3{>(Ovyq1&RR z?&CdKB)C*w@5z4yhM!?KtWz3Hfv1txGgA_(^e&~4Zw&hPj&04qKa$O|K2?4h0CgD? zPGiy+E^|qTm_>m+1kW~_8(y{@ z)ebAuoU|jaY2F3e~f4rQ?oJ!4f z(Rt#vmp70gqfFDQ2{Xdv%fh~?(!<@hC+P_&VX#H_IaA`-a9Op@k=lVb3x~2zuaII+ zBvHnB{O*7U4rb^E^hU?T#S|#C$iCdodh*mT{K%u4rk@p7&O@jNlfvbY7~e0fs}_V# z;v(zNe1?tqKr_sgADl)c*%>lEyBiUhF^W~DF{P$PY`Nq8HiHvM1ow&X#_(u_Jd5Xp z-}a_L#Z)Jziki0DaML9qYxYFGnK$FakIjRqaFU8sYVc3kaK%6%K+tS+vGZK!f%C*H zRrd?IB66#i){ZAxXg_NbR>iF}A4UtgzF@PD1-ty$ zXL3=D(?hBfJbNOlDOYY(BCNEoHA^AUY|btXnC%kGYr*?@ zQTaX)K^kf}_1#?G_cQThV{Og7+x<;|h69;ahzvTt^Njx^{A+D3WQfGz z`WG1D^7(uo>EZs(@4kOl(f$3VeJ8c)E@i#Uye7S#5> z8a#QK{qX%7JUyr_jHbQ#-TmQ;UhUNsk-&*}Z!L7UtN$VH4ipOH4=eIJ^zp^YBXr1Ru?_o4Qrv*j|952SP67`kKo=lnp} zjbV@$GZ%?R*f`~2mWc--0grT8ghwK|x!MmDeUTh~q2r4T#mj;X48<6){)EIu8|b62 z1V(IT<;3!N-RGiXVRLf3&as^eckG@n&hJuobzT4QoMR6?1*txlx;-A=zes?P#Bzd@ z^@)bf70nLRE$n%Ld)1VG<<-S@j*abk`?#aL==N^jxg40>>AU^C=-%z0ont6-vx8LL z0&)N^Ck;Vpq11cs7zMvJdNqFm;d0G+e)arYILXcZKe%*GQPS@1)z7TL^X1Dz)zA^G zvp)Pj?lW92o&eKM+D=dsD>L+6;Vs=g0#4ug^_`K{p7)LiEHHauYHZ=okXj$^i?6Q( zQV;v~-qqmL|Bsg@>lp&Zp13_2m_X!i)z23rtGvzHb!bC%iS-9H|v=y+EHM|(~UmN zFsVwXf@cE63pk|W3>Fo`$aU-JZ-Sd=c1D3D+4ChfDSXAp;)^W1D0<^#mL_WP#cQoB z+*9*NV~9k&|7mX*`Wbc_+H|f7V8#nyx$Md@|4(bi zo4#|dp=II|5ZCkpe}F5ICF?JpUWhpCZmS8Th=5c^a9;?DF4fHFf=#fapV$t~lFvtr zWG7Ps!jN>VgAD=cR7kL_a6u+Gl(q@5nNV7JxRvNgy)gkHLTM=aX?Wl_mzfpv~gr9rEpciQw*7G?Do+(SgN@9Uwv9f?j%%!0)#qd50dL<2`V3ry@fX&os3QsVe1HO!j4oG@JorDH)9Oqv zXq|ss{NkVdfr0&b0wJZ_XLJE@XJ^ebPYkaKs&T@2Y`irhb>zhpMR8enY_fbU2Xm(v zWF4(|KHG`Mwy!d66?nv0ZN{7kj$4n2G;x|p_FLqp8e>D6MdF;eRw~)@iON{@31mYE zQp^*wtmD$h>3eK1P)!ycs5)mp6b}xAc{!FDtj6G}Z=n1asvKAkI&kz#0J(SSsV8^) z;qDmW*h}-r3+t{GWvG-^s7_M(LzC=%*Jl@eNaXDYzW;TwA1u9L+1ybzXCMw9aP9GN zfCf9m9qavKrv`px5%ELG>eq`VKC}aB36>TfL}>$x zJdXIdJKvlxK?_|{b;P)&KWo+6R}#}IMWZZ&fG;t@7J{^Zg!@8DT6~{A4LK~DbFnH-(ljfH_H!qniho!durktOMA=(&v`z6fJ00Fx2k&5MH!bpkT=SJ6PpqT4Rs#2$z0c&Z~aHm>%(bOk)J(l z%r!lc!c5qj5};JhOYMtEJoVMnz)O|#2jwU3&|k_NEp6j z7Zx*)I1LI;N=+vWy5+7s&_nFeHe@RjU~aej*pSm>o;~YJ%0^L<*}%r)2v~EDHVTGL zdiFGBdbGv;nF@>hQ0Johfp)~A2^+p5jR|ImYE>`L`XPR_fwmDG7#1yVPP(Cp4qx{bNDq+5M7sW4Q1B)`Lr@4Ir3TrhwZ;Cn__;@+KElPPEmtWOH$}+r3 zR^g$+Z|U4XYMsbnugi<4@B0?@0Rfr&Y^50DH9~cSxQDAeKkM?qhCGjhuh zPeBfkfA~E*-!5kK>KRRjSPG8OvFk5T96wR$@)TG#;`mCw!#L`k>8BK0%jz+?9Y4$- z(Q9K@AnspiyBn(uP{;o==`EI-ipte$H z3nux{)s(X#mv$;7f~8e>5n26Ce$VqLnq@|c59lihSv4*)IMDAq$W0yKblJ^`ge@}M z7Im-Re>OEcBkUU~hHyjreA?ah<5zd$SbKEnpm!jbi#zL}la~I`C#;X{szi^ry{cFq ziqNJ%G}i@=A)SLV;ei6Un7W+02cbMN+YrH{ z*$gw^V$bQp7a%mmq!@}uPZLLIw#st2YLF0_$&w5wg~tZZp=$p`FSoQCArO21hg7QO zUzIRI$zDh(C+@P|Ptl7J6-*JD4-swx>gp}Z?aIJJ7#-M&Y2mPR-ICiWfG(N}z!+R%p9Re^F`D~*bf9+CwxN9be<(P0z*|pR z6H`7m*%U_g*U&US9jNl55AyDg_QdS5CpR3K`CxtzE0eArouj=z7MgBs)pyBmTkl!R zr)L_7y%EW7=CPW~T}DBBw>LPU>Wy~i#7O6y4M>ouJx1kCtt7(&f#5Cfu0`{-wLJ?| zb>pSghl!~yxMSZbJqnUMBt*Ssa(0E`2Qhc`s4AR#n=#_qRfbyG@%~RT^ zStVAB%!yX4o<@i#@fY$E*VHV5*rQ&!&B*!_0a{c~05Qf;&yebsjbaW9AD8#(4-uL> zV%mH1%Y4zkxh78)j?vL#6q`U7XcHf8ei0$j?)5&gRUG1F;s&cBY8LLFp|o)Xmn%Xq zJvt}p>7u-mxIUi5LD;O<@;K>1ts<8F`td!8rG3qz<*>6~O;bgKE= zk)WVQzy!_hJBf->+}wACF(c4d2G5GaL(gx1GyA1Y&py>d##`0460fUe*w}@)H62*j z{+V?u1~@m{*}qvRlrYH>`4o}boG?XSkMiqu(v1`RA{oc%sy+#!RBuhDSlnfvmBzu- ziycsgYdvZI{p`V!3Mss<5u#%JxB~R&Pf-q$Rhn!1OC|t3D5=KrD$0DG=wt$MPE{_7 zRZ8}4LukOgPUW|sK;(ZpBJRwfA*wh8d3Jbdj>B~Cf=TogY^@+bqm8mhE`yT%8ARaN zA;LP~!9^eOOfO(VWkgd2jyq$GJzcC)8JR%oW%TlayAX+Pk&7tE_LvIs6FQ}cPBG{u z9N(@>4mbpio5Pa)$MWqSvT}L_2xVQQLAeNItRF zOuaX&mYnW$vDSKCg21&M+DYI=nRu|S04tN@!3IElbQb~CZR8@DE+$M$R7%n`P7C0( z+f>PEK*oeRNxTcqQjKM=VLR(c^5n(szH|UjL2A@;)NgmU&dkyh400990e0S*Viz`4%l{b>S`E3+53KE_5y9o{g7k>-2p^j{9ZIID4RD#yX zQQJ1;XI%r28B=~Su9h%uE0xwJ_F~AvLVt=4S6_4-*GxYY{vKWRh<5k^6?GfS=48jr z_#j^bR(uL!31J?^6=JY=p~~y8Kd>$7G&;=Gz5BYJYf2I;Z_beF*oTn-QMmoU?}$w+ zP95g=*%J1ZiBl5_Ik{3KL6y%ffDBX^#u z$3i(Gqn`w>6+C;+GB;RqP8y}CE(NpD6fIWAQ-NxZ|7p?}_Say|@f$90E8eLAiBVb2%n}1xI}DKV24=WF zaq_YS>*urI2tBXuWjhxBc}K0il~kmtE06}b(?IuJ3o~Ke)U#r`ovVv->aA};?w~HZ zWTjRw%WnZ`h2@jO(l2Mz>rRctuWM3svutd@CqeR%Q4#wjBOS-+7AibTxuQk>twG9` zTOpW+fge=}c18-)WI}WhANJyLz-mAs2_%$Shn38}b811So;1Ryl#Urwz<<3K;d^5u z+|X9QQ!1HANYt93%M^u*IM!FI+v4EMtSI|^(Gk!<*n%9b*4Q)-D)#W}n%)fZtlMFf zg+A&qB+AJY1cKra=tV1i^c4jK6EM4@~W>xFvs2NUjlM2+S|}=n^s8GDW{G0<9+|{BeY)3%tJ{Mk5@dX{mxyAR$*~ep?F)7^D*y-TDl|G zK_ge5f*{L~{74oUTF8`t`ncJ;`~SkrE<)%pZsHQ(Cdz^2eUpO9FZwYZ4LwSz$G9<( z40Qpm(~pBRI8zv%9sy;d9yDjB97O$t9|?aZF-PIZ9OR@YVFW~3cNJ}I{-CZ zCTCpHA$F)zH^L+PFPY)0u9O_`^RU)`nf?Eh6~8Q2k<}n z5xX`Fa#SF}qeg>}0n;hoYDNpEzqD3GY87%_j5Knx*9F}jNoa0ABPO}Ukbw2@=EYcA z+Y^SFS=bTd_^FBY+URRQxx)-QYK7LDV^2MR!32$|l<<46nb$27gG|p&S65?hl^&cu zKH673GxroqUu8w7RFd-vQ9!o zcxshKAVQ9PDu)BJ18;7n-?vKK-SQiV;q;OS`KK;AP>bC zd;e^a3-U0)Yw>f$X*z=PXc}y7vxBvJd1;cyfTQF~$(-j@@RY=M!|`l~P|QsdJ3xEk z_JY^&2s&`KlR;?;6HD#(?%?sJp&l!;>*>uJE=3WIZ(fSikyayp>P_wia)bk}6an;d zRbw>^X(K6;qzUEswsZT7)r9C7y;q5v=C{a)KpbV=7bfec_F=M)J)9T8a!8jGh(zkx zjrnSKsiZ?q2P@-YL~Yxo3HK9O|2i2E3_siPJW9&`g{6DvDH;62!K|w}PHt@s$2XSf z(kq7G_trxbfHIKxQB^!Pd}*^0it;c7CuSZ}o!K}TAsSS9j+@wAA#DTybU#z1np)wQ zUGc&-u3g+SQrv!PrsTJZ+{Z&{d>brhb<0H+e{S-XFuED^s`z}2-yF9=gCO{wH+fUr zh?Bo}c<)5At_oHR`_Deg<9Om#22;-eV~uRLH9v!*n{PF4WEIoJ+H&2u3gu<3-i#7M zP|RdV`Nlhj`P;pZ=XwyzO2o8_kR)-E3N5-dv|g5}!~ru}&j}u_Uh0c{RdPK*QI^!s zW>?cmS3%8mnvh?<8Pr;?)th|>vFs^0wkK&VG9am$2-pLkBtk#|arACIH9xGI?G+_L zM;dq0V(IQS`_njI&Wiwa9D9-U+=llsS?eZK<7!dBH^_^mCaS1sE`U@)DkJB_s4{bD z-IUzhE`v=-%}_TUQ=J-{!3(;vH?ZzDJ_y5DLXAXV|CE`1F)1UI*0>tp4z(Wpsg_MbAnR`)_>~JbN%i5>Q zp3kVFrP$p#RBZBABiEP>c!iHZUGgZhyG9F0;zyjLWw5{)VHc(wo`_L4uW<|z!K4OU zaxou5o6n2UeDu~OV>>?Pd_V%j`fLoDoV7gjiU}9P>xe@&;BN1S`|I$^`A|%9Vmr9J zb@?_a-2dlw(jtUjTx_uo2L3vHWPO{ujV6I0N3~5tq$;glq%ie~gvJS7i)1g2N*Qy7 zo6BRpWiD7}rEH6!ngu+Z{2aULo2_-|@=f)`FnV(N21(8wUxKeea(p*TJ;dX>YJCMA z^?qq`&XzqS%%VYZlSELGLa#f*wssNC-o1gVrOeMVpajSlVc}e~#6wP`O+psT-C~@E zY! zD7$#iFeuOFD-g!!zg~AKuh3K@mb9$qr_u@AAP~pZpWjC9eDa{r$ z=0)XF)42<;oWWl&MNU7E-Sj2aU%eP|*PT8}_#dXuDLB+%+t#t|WJN2sZQHhO+jg>I z+qP}nwr%HT?^E~QQ#D_@{_eM~`n%?s;~T5+_ncS3U4N)fBk7Jh1E#2dZrr&pb&Vgi z41#@9NF&TfZ)({`b0pJYDqQf46XZF{V)}clsq?C7YWyGnJj1iPE1>W-JGk_tPf3EN zxe@V$4Zkf>{H({W$9}(4eBTBr0Qfr7{;<62uI)reSCzc8cJFL@eI9<)yCPkc1R4P`m?Gnv6>Lluvo<{5mxrYXHkn!eHVNLBhnGd1KuU`D z@znN{<`3nvH;j@qcZB#9_|)t?dQyoYkKIAv^g~FhgwckOrKC6mwW-Iaq0@-(GitzR zQP8OAjBT=iCCJnZ973i+_iR{&MQfn}D>~67Sb3_Gv9R=1!I%GvkTv6ZY5GX9x7iT9 zo zd}hDAsv;w8VHYBIf(p4O%gBSF6F^AyP6?^_SjpcLU@XL?1W7O5yP%Xo`&CFS==_SI z5h!xyW&AiM0jw8~ZO3wZSs^mA>g=5;c$w2zA2LTy);@xU2NI&D!+}LOqytqJ#$@qF z1^)|eHe&}R8XAr>Sp`}`9b}rbqe>^|EP1)9Q zrS+I)4>t^1IhYA zLgDUsNrx`89N|X{j__dCAANbnYwJesyYl@M8e|VMvJt5*IYdQFHtC$0K@8uJ^R@-7 zWXu-XnYyr>K2?)3rNt^^vdzBSfg;R=nsZ2I6RX~RFl8i|A{E7g(pkt}!i<6lL)_Cf z7J$r5q}n2)g_|#;4{0@0$AVwEJmMzP>UhKJr&-yGW?YTj83Tm-rq;U&(=bzQY z5ko@ang5VvxieamUY&w8FZL~^1H{K+hRywZp!$R9x2;7y`#yOEbnO)Q1~VWZZ9{|r zh}7gww3rweR8^0Z3-A|UKdB@nWLa=ptPa3xfRL9$qa%bt)110;;)-6Sm`g~hVP}&T?)7vv%JprmEKVm9VqSM%c!#QF$ zCO6_%yG&6iE{BHrY>t{tOb$Jf=?pEANRAyhP^xl#@W_?GTy>^#7VUbG4o3yrvail8 zAko{H&^lJD>wG$*U(@(+GYbyMmcpuo%BDH9To9%erPhR2!7vOcnw?p*8M7cW^$Kfr z*+G+!#apkO^8OSj(G9D)`xOSI?BN88U6{0+VDhIcDgHcb&xg!nQsohoU2xdDH}TE; za&WKJ5BsRe8t+uMYn}}5s;pDEZi72hHt-2pW`k8dPGDuL_cO0XT71izOz?q3W*X@o z0i%MYN#l>^u5KQzr$R4H>5hB-NqN2>Eu7ZD@ga7|pvW(EQ^3@fM^N);r=h=m&DSF4v672|2a^iA!wU zvY*(jS8(Z6K4Jb1(j54Yy6Yl~R-waTe=rA!)?gXh#9fXnHtR(P3Y{nt22jIr_H;ad zynyL}LV%TKWbJu3Pp_2nsJp5I`;*PtPxhvh{D>TS>F#ayEAnxZrOvQZ9O{Epz<2}y zyi=qnMPyTMmtWv>F{{)yg=4Pc{Pg_uB|r5ss@)`V|HXStofjd4k6*vjzm6nLOzr z*F*98h9@wHj;ul}@*BaeOI?t12zgh=0le%s-1Xjw+`a48z)k2DGKq@8%ZR|K3#&rx zndW9|5MSW+Igfv}a#;Mfc^fw^82%%&dt*9`hc4(&6q?xio#Gw&(Cx8y_)$20E^@7k)Ywxz+(5P9LjMyt-Zh)UXWhMcCOd-ZdkTw^B1O;9HA0LdAX z&GZg(1XR9L2c#(bi@+z4iEjv3mqM(^uAeQQNif?-hq&%p!Uj5~Tq5Y!wYBkPl81YXyuCj?mMP1@u}^nk{1PL%^Ev@b(nMaN)$w?4jlWK3Jr zBmWHKWgT1xE$WasTQ79x4+^|zweF@uxH~0G$p<0mg*6jD)HiZjsKNg-c`bx?#>>i2 zvA~`ArFE2VyaH3LEsM;th};&%$$}YnE)ur%NUyqz%ATb7mt|BOoH02qYrb*TIKXk+ z;EQeex*e0JkELBlXNh}1^iSX(-zT+Hlqxr8)C&9D_NRbyNh-ti!bNEG`lkHRTJ{E0 z(QT*hFkMS=*u;*6*6KU$wPBDKVq%bsxJs6mlR;-ri@l;=9=e~fb#6c|Nwby(f&0^e zAWWq-U}090n!OUKEQY@69`q2b$Nnba^jq-30z|r)Si_Ma+7{2phyPl(z*ElZ1e)FQ zg4A6YD$1*N=&tMo)izXI|2lFa!O!cf;p@phx1!iebgF-+l0H8>6X?!U!0i8Z=rm&#&7#P*|zh7$N@i z@6yV~irYobo`49SdLU1E^O=pj`Vh>V$=yWv597910`J#ww#|+k9NLtZ5PH`y*vw$M zLS8g3D61jNf;sM`ZC)k;k&v#}SF2M^7Kr;bhoap?#pBO7+NV39^@R)9c{6Vth@SNG z^6&v(N{&^9Kku=V;WvhF_Y*S@JU=9IYfgKioN2Q=XD2Eiqi~gQLUqOi$=0_Me1Z-0 zZ4LVw7YH#q3ACxU$G$v$qTP(p-ng<=yO>Rpuyklp4-kK0g(V@#r=QTHU|g%{5GipN57Hp8Uwy zRi^-%Z%^D<8+SU^y}fWR#L4l4R;K)XW7iAAR=PUnyN`ufe)e$tB_x_uLi z48T6^7HTlPR`Xl=c52qYiTb-Dk+)|H-F>j(%#}R+>4b>iF!c^@Sp^$cTA{7KFiV6~ zG>`!^wz;u-jqT@vh&QVVurbuAUiX6+RMP)Pg6ZOV`a~yrFJ6G49849-o?o$ejV~gE z-tdZK+j2``V)p6>%{~W_k(*dsLwfsCMeWk8#Ap?u*LiE3FfAi1D31;UQ;5Qsi*q%M z+{qjtPb6W+6l&CmAo?GwXmkkOKHxZ;I~-dIAk2RZ3laFx+`;{i{fKk9!uX(oeEAAj zI8RuORz+XWl`ri$8=zHV`$6YUy05mw0pa+mBOLuYe`ePQWM9S zZh+@qX9&C0VjluFFrXj38}58Eh(Fc!e~cxQ#wH5S<}d2hvF?@|)x% z50HDc0|I!Fx@{QrOC_P8pB86e2j!779R=}wIKtXqh*T=3Im)*@p?zANtazYf7j<7?E2&YEGL-42ujYl=p#5X;kgu=as)OK7wGwuJQfAaB#vt~pGW4y4qc z9NB`z?{Ud8I+voqRE|08LWs=o7imi%Mk`O}Vn4|)zZR9-jGrw9cW;?^V9@=6gcin@ z1Y8$bgjhHc+N36NtJGxvPaAtgL2JZcUOND`0?7!?QIQ z9}!{YkU*(wq{O6Qp>Dn;g9O@>;s8A}OK@7I>WUuXK;>4qBcIeh6RIbmga!DflHMlW zzEUu!Jw3cVDZTrB#XP;E!m!FE5mRCK?1mLOu8}(AJJ`~s#PH#3lTL4j0klBk3a<%DbzI<98fZGfa^hAM;h5y_Ve-EU*!v8Mp zK0|@1|JAGed>|k!-Qi_(`P@H-|M}SqE!pw?-~0Y^$TsaKIA+KkZ4?|?X3rt6Ytlr# zMr_!fPGL~z#_i?StY*jCx%DGon043WJ=NaJF$O9TvvS`_fl>(shv~y^R>|7wcFM

    jUS9!*k;#T$0}VQyK*5{9qRiraxakhEudqr~Pi}v*kb1 z%@ZsYvor&+Or?MOvBHqpau9u;=RbyEp52;+m9GZc>yF~0&S~0 z{VPN=nRCH6@~2-_Rpi<_nTvr4EBUAx8+9j11O342evpI$jm)UQ8bTmpo^J$>o?s0$ zfxKmi2lOaS9YG$Gr3B7p_*OR-l1@<3*SDrGsO$xdz?tsz*~)#8@f9zF3bv!q##2WeKKo)HCeH0?u^B_lcxdX&=rb_N^WRwnq5#%M0OeX1{)&{4*`(to)(w41aIbf2sK8v8Fn;MgL&AW5fMW*fA6(tM>Zf!79RyqPW_PK&pjU1= z9M<;TnOock?O>5C+hI0^er91=xUI7SVau7Dwq#WaeBxp%@Vx zodu>z6 z1|2}^$-Dsp?Vi_NxjqRfN&Lpz3Hq19)B=0_Iro^m^x#I$iF`o1kh%HvQ$vSWAYZ^1 z;wuT$XA~_;fWe+{nY-!*dXjoyK{84yLh1S1hp?n%s*ZWUF%-^a;@0B=Bs z^~EG+8pvKP%_DXAlSi3URR4H4GWe$0xL4p$LrqM(=ipNHvl^~vU8|4rX-6z9zL7pl zZxaI2r(0HSjZJ)Wd?hVxha5Vsu?)4SlV|WX&Odr2`SSz^JWFUr+p7~*SA9cfMtpQ= z_w-LXEwjp2!m>f`VE8@0*=23AabONq1IXiaQTXkQFG%K;0G$@gKQmr`fmxVb{jb!; zg8SU(&t=z#>&9>sorll0#upxf=TV%Kxkx;obW^^UycPQ#w~w}@jScTgB#5}2fDjNB zpN4{BPS4l%3Ku;9d78{dqWZ}q0bS}^gQ>}kk8KZB{M92quoH*nU2F@W_$GAYM3R^8 zU30llL36sj?B0p>mhsd{+5M``t&e&*^L3s{5Z0%a0p?=Wi($lf>Ix-I7pLoWsc0jI z)_2HazDhEqb3vA4jtoX+CnaGV)G>P{f+v#Baj^`tifV*Np#n~R3^H@m2M3QC-L4*X z6cgaLL3Y%M{Q0@CMe+NE$OLJ;bf2@Pl!(l zw$5Awols+8KG0iYY4Qbv}mCZX=8v_Cu9nSQy#tyY6r9 zVfPqmK;CoCw-cUQt@dkZY8^xD=m;OsP;G-yej~{oUFe%SbVz=bKgLM2+_{Yi%>r{V zs(eD#rIOLm#d6v$s9Ra)5*Z!AaLaHMFI{a(4^|? zB>KCY9?TG+9{XN27^M#+`1vP;4wL(oY+)VTPO$SE8;_*en8f4~bbEv~b}4Vd9HJ7t zA>H>1R?@z!OTgn+X&#T^XqEDmuNdsfpef6W|EwkS^GyO8qdmHQs^ma8M!QbU8NyQ( z8SK(#R17TQs;vO+62lR;>yw&1bc$CmqEThuVxd~SRXi(ZaS=$Cm>Fb5@fW=$F~=x!%!&P3k7{v&U^NmOM7{OT z2p>D>aQ__oYO*1DU?*oX;Z*Les{{Nng1IPa$#xV~%SD|OQ!CJ%SP7uaM`0sf_|(p* zl$h_@{u8NTyu@Lqns@$2>po=ak~*&rhd0GwGIcH?uxLBL!(If~y%aP$)q9flAL=0^ zv>&@OmM3STqT=7tC`f1Z25X)%x0|jWaEt${PT0Bw)dj9yt6Okm!5*2j+EK*!5;WM8 z0ugvMhut?z)3SoJbqv(EWu6ovT@hU~VKGH9&Uawm04V3I3hB74F_&+!LLnF3-mSe#=0g1^vcU#wgPa(SAC!)` zO=Ouee8fc-e`#oL$Burq$Pz0SNi{2e{Ry3&KF2hX#b0@u#o^kAbGL$Lv;|3Mh=h~} zce?&#qow?@D*L#(0cI)E9V(3Eia;*qykE6?2uBOliEF|@yUrm1NeD^$!Aqy4vWm2g z0bF$f^IFJE*qbzYBEW*mKbS`=JG)6FV``!r<{hnMc<&i%gd$ZocxlPfr->EtS<`UQ z4sE)?9Gg%vegJO5l7z0)ARD_OpiJz$d9W8foIJCqm#8d-ZC@?wPYqlx*Yh z`%t?JEDUrs>W=oxjF}7YNslGNJY&I;a#0a3!&c<2sM`!0+FZCXioV*u!iJdO8Ps*v zv=^@ZFxX`cu9T){Udtsct9s51HAdCXUv7yzP)~8+2^ySoCwTX3ch$nNvq% zZexVKm6SLffsT1uexvWe@#Q zwH1vUweQ=yR>Ky8=do&ZM5{RCrs}nFk5}aczRApn_7&EaeSkdFRJx&6{BoIdg%b6o zKLuS{xy6!9g2Q=(<=Z)n73!pjcY^0uwH))72Nq?M6ssO8>)72`S_5|asg1sYwGD=F z(3Rjq)k}8WXr^$@7qYT3an;aL$Ff9o@wBh*_WMy9Ha)DW!ul6-o4mgsv0yp!9x6jc zH4sm&^0J8(>#*LpV~cpI<5$ZDf&Q}URb1ATb(~0alUI|5el(M{2eNR}xqC&)_HSU9 zYH!ZLd-mXz2K~C^R-D6R9+hU68eh}I>I_Dxzf8(3p?hTfG?b<|ZaZ+~-o+w4^5R7Y zah%$ue{*M+&6|zW`}tXgckgu6LuX0iLxxDPY)KvRuAaUW=c|TN>r;1M?u`0MgK#=^ zf}CDSQya=ZzO5W&%Z=tGPp_mza5NsFI4(NXxcD$Nz9OcumglCT^!~(&9%Tu0jgb+R z@}+j%=JL#h6N^77?d?-)zqm+T^K8XiJ!x7k-_P8YvV&ksU8_;>6wi(_a2n{~?4K)m zm{sXc+dy2i3NKq_fBkmn=!L39>#npDYrFS(LRYmD*Ngnz$b~x!ypHSU%?)ZV8(js& zqnUlX3+wKuEo(ry3LC$|yuEl#9V`zX&lu0DrYqYUbxItyuV)O70RR0d65z4{DTaHp0?6v`AAL)$k|!zwFBY}wge#Q^w1m4^ zjfkWKYu0~~883*&d_jM3O`~nk`V94{owj*j9F)8}=g7ZzT>f3gnUEN-(-zs(ox{$d zfvIL>CE?fptx32wwr5oHv5rL^uy6cvr6rU4ME=6^ z+rO%$#Q91$kSI|1*`gxzPc0$28)!06HG)^hs=`V)>Z$@EEwkmJW(_Z2Xs&MIY3fdE z;DNuj9fMt|8)!KWWj(C6tr@yX&6XzRvG1*e$)Cm!##O>3EBw8uA5^ieG*K)`i^S?s zc5=ALE`kYCqfiYh1gJ{0Ef&b-n@lHR2NaVdV<)3T(PF{G4TWUp^F$(LD1=m^cieJo ziJz@iN5$nh{q$F46Vog|KmSwDJ-$buKT0 z6W)I4|6UW!loa_W=u}L8tHs2A+9_4}4dw4f#jAjyA4h}|Dl+nU^A`a+WdTg!Tz|Am zZO2cbat@1^`&PbW(^M-{A|fvuE=|(Fky2OHd$il|H)o!`kn&L{8>^i8$77kH=_=+9eZ`^mFPKd$>F{hW;^?~^8c7sisuJQ^~m$O*SeEY9_j_^%bb6M(1C ze)0WpsOGoed<04DTS~B|TK!6-9D}HBBK_?1*Oyt#3m-H7?_=?R=m*6vL>M<#)V@tG zESL2P#_^8)Yh2m)_0rdAw4SS;HLMfLNU1=Pm^kZd(!x#p9#UZ|K2jM2;;uFKqZJ(% ztW>2IafgbeU(+{TrTs*);&6K87XM(W<_Ii)h`EhYC*5c;+p_icYr|ZLAhb+DmHD7^RX%R z28Q@l`OgA`WG~qVp}>e2k`o4nEk32q0dUAb8~CBQz@Kv(LlR(`v6zC=J*$>;EnRwY z>&oeuQE`BRNdaqSTn3>bj$)$;`kxSeCw)=iI*0fU)Bv^HJ3iJjF!5A@=sA87Qi#rQ zibyw4;W)|Ha+~3NSwl*4qq3@%ok{&UnsAtn=sujzV2s;}mPwd%2U|IE@}PDX6{Xjr zUWgx54V`k~{iN>^8uD`5Ocw{^>AiLL!NdV>01!<@7TxLdzz@pgbdb6uNr5bKaW=Vr za`UGRy^EvyA?oHk!+oLi0jqFi2<@r%@E=G2l&-w@tFZrPJbo`ZBO*xL#E?i9-)&)j z-XD}9vs8tOK3cld;c6f5>zocPTjrob!jShz+j-rGG>;4d6OF|XZ3d}*sKx@?Oza?n zI+$`?iS*B^`zxHQ4^MubS!Bfy{f4a6TEU=e|fGP=SWtMoICwGEdK zbQcP>EpyXgEy52#XYq7>BGVRs)Y^Z^A#8HV)n0i{2vCN1D8c-0r5t^I(s;cvgyg^+ z*(kk`4Xxt@xdZeSV(?~;!D)CkU#OnHvCTB8&Rvr@_ep+gY){SI;#8CDfe-unhh(7O zlVa@1xgKOU%zckT(R%#}KbF0qPA}MSrSPkND02h*0wjSqSe!sx-rKqN+6+tY=&y$e zh&N1iD*s|X+~hc}A|3c(OH5+hO|#13Sj5JP33>IGL=5W5jX_5-*{#As9BwR-iX6vv z&EP8y{s~X6!;(oD3-F*s`uW32{uCETO^083NDuiMe#Z4 zPM%$=*xeIzIM#3Esits=+9heV~+#jjd%{`N>=s)vI^{8l#hXO>O9|fE>*CEH&A9$`jO? zpaYpC-_HN~L~M@|#!z;x(^Bw&Ayp1b@r0m>aIC2q&d5zWT*7*~;J3SOlyXOK_8>~@ zg~c%UuA$hLV3&|^Xlfi8$DV>)lcV5$)~<>UVx69LcV215GOmvTX*0oR^HIN=9AGps z?1G~Aa$<$-m;8g{lOnag$u7lni|Bvi)X-&p5Ud%?sW@ESVlw=L$mW$m;5P0 zSzW-#;*$d7Hu?DSj|z}oyhCXsa!Q%_ulEY#haJp`jW#M#0&Z@4RtGjEttX!joa z%L|9$wRY5i9Ad?_^1pTHY`$J`*+xV#OD&S($>Y;FCv97w2M{$sVIsN2;hc*Jay-> zt(d8Z$@@vrQZ#wT0$-TbUZ{kx#jkxX%DAL%1g^SS6mint%Jg1wYE=vPLo6X!LAMk2 zI)_pq0oN}|01>Ve+)118R#>CDZFl6nCfOjYU}U`tn&tfgD88Omj!eYVxEO4L?71oX zI58444+&;F%|W)aN8bzDthZN`QoW-Z9&=qWA*Nebd`jJGNw&1a<=sf2}E zd};tib^Me`F#<)Z5^Y-~SThz1=k1f7Tppj%2)NvM>G;Xx*~Kcy^d`rv!QY-JnE2&} zdQzb0nEe7Fo3$R1^(Y<&ivmPSeXEK*Kr}Vkz=5U$SjISk3H3sfMg*EImkfFbg-dcd zLm!ijiI07FY!t*QZXdnQ`q<9q@pf4H^Zc|hut3;RlR)%0{JcIyQ$??}x%T*c(Z$E? zXC5!BBYUl%CB`&wV>_sGk@NHp^lll|q8 zfXIc?!pSXC!?VtI`ryJGH$f{D4Puvacmc6n2FzIo{ zt}O6Cd;cH$8Rn>znSm9pczb~DFM%^v)!&!hKzW2ms^p|L5MhVdDRWY+fU7I2hTb$r z-aD0c^oX`dW1ET7q||P3*)!xtJ931%Cu>ggmm&}Qjt<`L2tUTcI=~{>u7(XbGRD~i z1^f?lyrnI(&=dmZ9jW+;O9#L{DPpN!tnaDi6+El-_aC>*a52eQDbRbf*;bI`zi3cP zODrvH7}+fTNSkP>e8zg@muSbY4In(-p8ic9Tucv_doH7VYDY-4gfeJbQH9-RF(Xr= zA0q6vrpqk}Qf&V_LK`Lj!iURXRIh$i@Gy!=?p6b4T0lxTN=@C7+hQUR&jro=4`G$T zOl`8^>?wUwG)*(3mVF}hjOlF0Wdnl7(W!i|I(G&Bj7-1l*o#M6v~aca$_IfL@*Jxv zMq**fJbjUkoEGiP3%G$Gi}r=2EP;iS{><|#O`Bu@b_&Ylor*EQXP|-qmOmFjVWeV> z3D7}mBNndU!HA>)KWqP$z7Ss_=d#*-ib$8_Dm zO#3Xs3=dQm)LPb~;M0ggJ5vx~u>r>K|96(c5N%=YFd=YY{7E>}hD0^hnP;x2F>r~$%&x#|F z9LN(jE3t>pbxh4AJ4IZDT2{CXUf)B8jbw@yp(%D|NWV?g$+KtKyw5^oZRuL0nUk{l zj>N@&futBDF4=3bGjwI6|A}+O{`2#Yy0h|nZ#Jt2EkE0MuD>SK6vd{=`5v|rt5Z~~ zf>iCnO0PpkE`el&;thUvH91+Uoevbe;uWvDOohT_Qzt5!CxH58^?ej1IY^e#nDfvo zc74MmI|T*0AjpgZ`h@&ef9UkH9k<2*x4SK~9C(f>$f_zm0!g47GhSwQg&CZ55Zmmv z44FNcq#jZ$KLW1N#ihtuk7pASW>GUPf?}|u_cjY{PJHqqf+weMZ%#RgQKTfY@`f}7 ze>TaJ&<8|iR1ObCTxHw+u|ILI>6E@uTxx;bBh0-6c0bG1P0~{JR8pD=piy-0CsW@b zpCga7-ax#Jb$E|Z4zxFuTJg`d0*SF>&hG5ku{S91un6+C(or<-&%m;`29p@Hh~+G@ z0@~VWOGB&OJBSbH0E?btnT9}WXWB+s2#BOCXbmxX6@+#nPNa%j3+5SGe(D*^o9!EL4*;#ZE) zVEewZm4#H18<*`3m|E;MqfJ@H7P*cVzT}hCzmMkT9CAd;q^V283V+0Xj#u@b)mZfA zMuwY2Gr_>GiDadXr3>*1gOL0|BIYTOz&XI-)_76zCj-+{6ZNztfH`20&Q<2hyfQcOWE@+wp9|ie_PJ(o7nM{VM;QCSS$QZp+Q(%6TFp?~nK&sWa4@cr8LiUC zAx|*hn~)AeWxzziPzm#V0e}zwne2YbxG8L+!)W!D0~YjB8IYENx$=qTEQc@ytWK!0 zVbe`GN+e+vpGh7()v{JU>K2{w__9bfO>@w?S3+qM{TR$2vXt zgc66|k8?oXGwElMRpKa4t|!flTOf#1#B+#Xr*ywp^3;w=nqeRNe$BaUvNvUIouqTQ z(ttUvv^s5*(3fQ<$=8_h!~+Luw+cxqlJAQx6dcXzb2$~T&I!>9dN>dEVZo+^B8$Z# zwg;dV(fF`t;hi7k=t3}VX$(3BC}zEO!M9+d&nMRVRP{BWroESEhmCQCSI{~7v$s8# zCMGT6djP6%hgNd675Ht*Zq5sDMGGK>x^Ha4JaF37I@utxYl(2*@_P1OyC8NUXbVgt zcgO25uH{GP+QI%Q8?oQpuGnk8oZ}C=R1QgW;Dne7P>mz@cj4|l+6lzlO*4D)#wDW! zvRuBDDa@fq&X{)=k3e1@RRI}?_y@9Wg(_1L5LK%*RzMXq)cte7`-S(%b;{S5j{9@K z1oNonDJQ9R6y6J-te6x=@O#g(G8k2iF-xPYNu0Jav(iH9@=|C>!TA9IUY=Lt3vB7B3%Jy4!N7UZcYNBjDADnn1(KXEVw?wrM%3{s?eFG~{(faWnTj$1bO&w^(oPPr}$C>tn_{S1y7xx&8pbfPfie<@$~x z%~~vx0TM?5KG-vb+lCMpF78T2d^A{2(KVt{bTC;Yi8gvd@!9NY?8%TA7;4kl1sf;a z5shh7v*t8b%39Tc7X*=`g!1RC4v3SWdD4v!?ZXLIEn|f74Ef*29(O(J8(k5FN^C6> zwgMhu(VbyAe&M^(u~|UyL{TwnNtZj@&&tI`j65CxO^j)(pc8I3*Y>NJx^Je4=TGup zzm#7)+GY{H6B@p3r_c~&8b+F^pe^>Dvf z85Pxdu4UYbB%(VZp$MY5RU;7g-Z#Ve$!3OJDdj{rN)!Kq@&U?=mh}OuLJ6!8&<F&ont?Ykn@_!P0vS+m#CQra3-=^{LC)Rm)h2m4%_{T z1l;f{>t)5W|8FR?g2(eU%wSmqaSAG0HQT4QQfVel;_J##@XZHqR^Cb>oh@p{Ea@e; znw>qAqK&|XHP1G1G}5^22_*T>KM@5>2K0Wvm{dNUb8!*&C5BDZ)BoAxqzCaqQL-NxG8 zD$O0vKy9B=)S)VUHxldcnVGC18HSs*M`o(E9+MGs6*cKYAP|~(X9-sri}KRR$9917 z1!WOQY2nu-*agJ+^qKENs69RFS?a2#9`fFvi>Uh-?gLiMJn^Q<%_0Ev=eyQ?Hf3mR{Czf#l}g@J;JCT z8hyJ`%2kRd+oXC|1P*55(t1>ey-zPOOuGqy9z`DB>Mw+M;dP`W!M{~=Xo=#8u5~&T z8@~V8zL)?Klr%=gH7BWEQc{?!D9 zr@0oWwy29xl|KqKH7+FUPAus%-2b%X9zovk!0QkQV_s=<`1;dI!MuTZ3OO?^pd);lCXhSJ@hiCr6Q9DdwP4RpqlG!kx9H#_ z^L6`!GGuvogYMJYH1L774}+FZJysRmcOVuGKZ_VDF28q{D^aD917Xib>)NzP#3!T!w^}6 zSHgGH3yq-;_ZBKOP^+&FULY^<>LV#d8(zx)P5m*sl)#-TepA$&G!^p8ZoYLBb(@5-JN9DOLMC3V$Mh%GF z=D5961p)LH_Em0%DB*7o+=b4f?C3Y!j?R`V9#zoF>HLan6TbEAH2-y7nNB7+Oam-T zKw}f-190GL+%DBCJ)@UjF7HcO7D;qjoCa(~CSGEZrcnf~}|I6vK2~zW{IHL|@|2&6xJ{*D=81(yo zF=_kqT|0aF5L$Zoeua)avg0m^HIXta`2H>p2{3&e5e0?d%H`#8`J8vu{Q6P(d0Bh> z@m=?Rd{X)8S^6pX&S^r(ss6TI{<*ony5f19`6&R8eQAFGsrvS<_}MxCX?g$IN&e=| z+8b~9F-^bNDUZwYk^6ZFQX8^#%cKmUP(F*crHk*<;Ex!+ivQ?+>%0F@Wu2cPwl75% zVh=ec%u6=?yENK72A}32!Y@)aFXsKB2h*Tu@=oF7rGXhF{X|aD%1}d#baRS12!`%8 zQA<_Ps12h=)wk6%7pubhXWo2EA@npF7=aL`3B1}#A)i*H4F6W9+1eq%M;1n zRdWHAAT<~2#x4Bt2o^hPaGbYsIwWsg;OY?YSRzz zihCZB^|s{f3o5i2<}Y8?W8m_JL+M=9{+bxuwsy#U>V;1gku_IF6ccX0DL9c*5#yQ{ zs!Qj^RB+)bW{fDri6)vbSl-Vl$;gH7##`{@zY%_4o zEc=cmM}I|ml;@XuRMW1(HEl&8WiRhvPBI|IU^-Vd$ZIG$Uqz_A=|Y2PRpgX8-hUBB zcEq|@`f{<@_Rxxk@U`L#TEHVH))1DJJ8onOt6a>M&pTF$YfG5z&O8B-trOw!wAOiw ziCgR`HtO0`_wFY3PL^NPNF0@H(Il_H{bs75pN3~9;u;|uTH{87rVc3v;XGm5)+`u;t>-=m5d3oF9Db# z{#zj6M(hU?M_erFjVp|eAx0P$G9wK+SK5o6krCI1Pq`i-q$9sw#UO2HIc!q; zuePSPtLe3~eFmaPH;x~T$RRX!?;bw~qmeS80=@t(b*}hFR?DrTF5ZuG3S;Y)C18kl zUMM&x@*_m0O1*=$dFr8YI&c;TwZ7|S`y6RweuBD-DZ`N3;%%|=SR&qi0>im|=WF0D z4bmRJiz};#FTjSUM+}*9nW8 z9Okd);a50CDQcmyHnD1@_;7hY zJP6Nfd@nVmRtCuOReor)*?_2imv^2~$|BnI3bvhOs;xk3cq&s2zZXiCNZ8>b`20@1 zrAjbeTzx(g0By{H>ZFuQbn@WbIEDb_k47G>z`GOXZS6Boh_Z1%jz-0Jo!RAbt3~zV z>;o|SmABGjO+lB;$hm=%lfXckOYRu+O5upAc>VIJ+)zgicpiq7imPUYA2S=jb$Jp8 zybrmW*o;JZuZS>Z6U2#1$(KP01H0qxbL@mqS?BD=CpC;2;ISnsY+`= z9C?}b5v>|~ceYna^<|ghHII^69Gt2yNxe$GSJU2(BdX$FX(2d;ItPDwVJ5s&wAPiZ zEII%A#bZ5BiivfgG4&K|QrY)g^EAe}^c1a9ae7go>oIz_;^{E!`AzLODqvufz+4-= zc9j2aV)F%CT#~p4=tZEggvNYfO|pGZ#rMJ9M9IvY#5Ia?k6882-N=WZFL||`E_ap( zf$g+-xpo+OESuix~( zRXCOA{{d$}n7?mrLcUm(wVcd}lm@esI5VhpTkD#pi{xr?f05rW=Sea;?|I1`k?Etj z7cQPgMN%jO&?reiaG2dbmgn6cU}ax9w9$B(I4PXsNPOWeuOAr+dAds3F|_u3HwU&u zOetr&=s4q|FlfsY{zVXttPW}+24CS)!$yiz<4FNNC!Ji|Wly!J;+PFeS6WxLV%Rv6whExR&yEqX zZpqFc`)=49`GD9Q#-WZF6K4?{4#2j{1Nk;2PxAFy7uD<(4x-95TAeK(+EV#s^lV{W zXp33Vr!RCjxMk((4@JJ5>ldgLM(2Q7ZzOl+5Mu$(%ktLor-5Ho!6yETYtyO)$*aB& z(wcV>9CS-Q;6q^11#%x!M^3YM0a*PT*$3FTG$;wT!ZeoaLT$M|Ae{<8J%o}o=szqBh45U=o zt%r4oyLS($)V+J8wE!MEK||_XVaN!hx=v#?sFsLskiZ1*hs(qcj;%Q5Fu0YY?3CT+ z>Ch-DUey}Sy#%N(n%c~*Eyi78uwqtcP1{1_*wa^_Q@-A3=P|8`L6+Nv+_a>rM(s}li_)uU#z91IG(t7jK0s2+^e2!SGknA40!{Cwn~Rt zv|T9NyW7%^dI&cjKVh`nDq9JB&z&?H#CfK$g~m6(L7b}4+=+5&M7PwzI zivs=aVi4ex0K>VaAwfAfmyy34<%Nx!H@dNd2jgcP#){7pJKzyF#<)e$l^)7arRXfsXh zGL^|yJeyB3f|E$Xps)rE<&=6j%JjP^V zFz^7y(X>u|j(YB!bl_FE!Y;;1IVw`Z*iCw}KJz++qqU+ZY=Mia%)9eYB~}7{a?gdE4vltk7=vF-2}N?xXPyh|+A1 zs_eyr@`nfqWvRW%@mODOt!^MGZ_5`c@Eewn@h{eut9u{+X6;D0FVxfd3=iqr;dv2X zI?t>-s-ZI!0s7X&R8OH%NJ~Nf)O0C@dv*92yT{54Bt(QukW=#F@}Saxs^Ew#rppj2ODQ2U))MSC{~9>QHVrS%W2lo!0FQ z>33u9^n>V~x|`c_b`E$-*vo%fWI>aq6? zDJa_pA98%7or)37r+|9U3TgC*U(imHX)Mahd*x23+9=}Sw59uWUP#6V#Je!kMLjo&1l0X{1-kWj8G5= z{!t(EL6G4woyUvOdE3z1E?WsfX3I+auu=joP#uqK1G4Gi>&+FMLs3)#g8M2^&W|^$ zy|l*4xn7yWz}I@vHuvMAjcU%Q+seiqNr^hqzq{5Fo~vlE?!U9#XHR7cWFPGw?+gBZ17ZM>7sln>~CJ#4!ZP^qregH?4M zr0CfwUjjY-!$GuL*%*X}pc}b-OIV^-E(N4hSLpa?YhhL0h+lneZ?Zghqj-w0P^zBG z`2TpgL$@`nG)KEdQQVcUT3$&-cjTfuNDM;;ZSUDDt z1#PHhNPyAG(eW{zv6G3Nt;<{L`?S;!KAQJ--Oi!aC&$?!a%DK^bEkseg;gHW;E|#w za&(HNbQq+rDRRuuQNk}BDO$7rrMil>{ny))C=nGLn=jju&zen;^FAABkex5u{#nG^ z7B*yZ)wR|)i;z9TqCVn4V|HVe1Y@rnZ`?g1PK_HlgF|S3(Rjk|q6r2!86Fl?*)v+p zJo*{SPcceDQ73Ns*{O%;cQn)Y>*01eAFKISx%6ODoKsFR(as-oK3?A~f`)iYI#P)e|GmrH?E~ zTRy9c&@>LZT~7Vt-vI3S>Qo+MKUS)RZGq5B$JIbh@tdtJYhInkg#G_R=S`2;6|;|< z%auH{VfL5tHI;Ebqk6qd%&9eQF0myqF^1dcqX(g`!-nWsg+E z`o?=1(8iu>?Aw?WiT|F9xC5mtQ*_Z#WruU-Is%`#`;4jNeVt z=>odqYO^71u(w6O1paVzE@lF0SFseZhXd`ogQ!C9bT3s>r_y&d(z-%v6e^puf%VlN zsl9_&x17wjY?h4ud1u4+NKOe~$HG+EQqEg%Pu=)p;ewQX_RX5b^LCmo z8UV0UOjj=?eA<@&0<}L;h|Z_UiscE4TbMwuvWm{DKj+ad0ywLBUucE-(mN~m)CQA?2iUcD{ zrQ*Q&lB{@{50h!0ogw=}p<%{NI~W0G8*qBszTHwLcd}EgJu}BW!J44`JTy8xIEGd?#AZZwG_=nloP11cj-W zv#nR67*jQIb-sOSG746WPRQtGjP>0&p zU;Ll;yPf-gdjE&cx2>)t3O26hC*bz(hA`_o z#dv6SUTzYn#7^AgZ2Y%yC!Y(Q-~IOn@Y%FWSME?%{YB!VYwUD97n^ZJg^|m|$Md$w z-)Yjx{8`|@bgBXM;^ec;(!VW}cDh)f(z-rfHWKU?O^FyWimiSp*?F9ZdflOpk-p8X zm7n1h3$b2d9X}2(V>{NOQjbtufbIOKlu3oWyW?v++O0fCx{I*`N$;#jXP!4Fg>2}q zyp9HgyX=)&rR0)zq|7bz_jgWNzwey7e$=7q10&`%%e{WQ&pj3Jb5HUc1Ja5M%oaj! z`*^Qh#vI(o?>$*h8nfDiGP7`qDen-KGFe&;V1Buug2i~x;+LMEr8N4bk6L$I(I51qY63^34kmod4c#}HpH*w8%9WA_HIOUd`%d5! zCu|1qI|NUjjMH*Hjj#J*D3!#Vxh!@KaCcGFLi-mkWyNPmK&>)nI$0$#JAVJhQ~Ki9 zoRha3dSctF0^M2pP3?SxMaVRTu8~;is%pYn1#kZ?c*8GktkLf(u51l}Q}ipaN3E#+ z6-e;F?zm=Gw4=|b?R@xiCwwXSy`to5CJEp5&M>aEz0>Ic3-7uj%rUgTK+_X^fk~4v zmrLs(tsbgq+kVfeVQzQa8>{46wbD_qTn^g^uXmMK?l>>0dz(AzG-b%(*w234cz>zH z{yp`F#4HHU(vlcbs#c3hmS7Rzo<0f6Kuk)tk1g9I#cQ_-P%&+W;jBhMQ~)MUE{jo~ z0MK-)0;L0&T*%tVo<`%zc=0~1#F9@J3f!#4KAJ63J4M8?25! zvhThXx#7TSrCxCaQBll^=lpjw$AeP2_+g^Ba{nt;S_pUbS8|h-U;VQ4@vC2Ud**7Q zpYV_N+*4!o2JZN&tjQDoMwzUg=q^8F!a6ZoP0V$pR!)LU*XABQH+zeHbl+6HD{sX> z(hKzdNwP5}kG3aw78heGI_PGtm)X&bT~_Wm6CVoBTE9lft>ybtx~cC~vN&&09Yq_x z!lk`L*DrQoGIG{Yc81k=Dq)9i9G0IEqOvDy*f4buss#^BFMLJVw0PYPRWyFMN31=F z_v1$iQ?$~&sH3e8nd1~|l%4BAQ6!^uj+A2^Q0Ul1aG?382oQAp1)=b?r0;g#-vTc7 zHd_Uncmf*Wv_AW@fTvhzDhG)_&Ke*Tr8UFFjU~Z|FyvfI10AG!3w;dxIj;*8Mw)#( zP}ocFc7UJ)m|5Pcbq6{t-K0wTFv8^_rfVzG@lLm?keCL^@1H@v^L#^()+C&-mYUD5(hgeJVi#N4kn(%z0j>R~1)W?TcrEc@+REzW_OQ zxE~t6yiXz*s{6!lpx;FItB|&L|MbV5ZnO*k*Xi^Y`68b7dEOvnME9cIot>Io=yFQm zxg&o`Io#x3=Y4>l5;0kyT2*bDXrsi9B&HRzVCh>Ay8v0CYx2v+(Gas`p{ogsR^;dB z1XpXjCpxXn(EWz&m*{3QUudjr{zDNy?D;jD4W9U6X40ivK!Qpd(X8mUL3^(KP;3z1 zy29-G$eL-73$lyS6U%SYlE(cFudu5aftit+sVmz!Sf8W5av4zeI^sB}7yk-yji_SD z=7}^6f+=7z=d13QFKBP<=CQ(V5NpjM`s>SIj$TAh4^Mvl82vwan&}O8%PS5}?kru- z*s9paN{A{je9bGD=sO5Alz_?5<1aP=<~U{_ZCN5~<{mA1Rp|NHth%U>x1M_Z21||6B_@QkWm=WpUR%8a$AKZI>I*AXj2XK|2O&JSsm^?g;HjE+-O*g76JFZ}J$~iLh8*fRTe%c= z?UmCcnYXFqfU{FLB*ye&d!bXI2_DzYdu)`3-N>kc{SL)1$iZ2yW0i3aa;6URNwRWT zB>l+}GdZ;t8oJRm&*ygZKo1`@2Y7z+6n#31+G9mU?~w<0xsre$!8i5f)2c5L&FEIb zn$Vm=a_AU{RfP@7IrAZnf&O67oU$|w25Zo>2i21Ry)5ULz^1GvWL(J;Y2WQgnob#8 zA!?{J4V1@2>Z-M+IoW~YQR3!2gcUby7@l$EtOpl7G!ysU}(l2{l*`Cx#R z7-3H#?bpvJ)O9fMOPZjw1MbSw?h7v(N%MBi3HlVA6;beQ$&{4J7OFjmNx4!?=BBRq zUeo>F^Ld9p)i3#%x<^sqCDxOzP&LXlJHIFX##g68>$h z+f7qpWSEI?TC|N$gNIme5;A;rAOv@jbClqUS?GPDCc+go)Z?;*+tg!kmK4C0`j0#IZmn?MVFg^x=#>#0dR7~xvL^2X9eKJC{?-pHsMfc$ zICG?}EBSJZ_YMT!sC)}fVNWA{nO)o z=*jDs3^CCdw~+UE((8+R+@9o?xl{*t+HORUg6$xyw%W8sRY4yx4vs<6KxA^IQ{JA3p{yUyL0{owU_TGl@ciYQ{ z=CrXBBl*evBNIq4SjqYoJTQmjF%_efG+zzLs87!&seLqyxk{Lu>pr6VFOnCZecX)( z4&D!LaS~C5uTa;AqqfM4Yx_9bDa|N;1kWR>VzPXgkFPnKD4N}9hNhCPTGORgR@r() zO1W1DlZ|SZHjrM9^jtSmt={*B_Nz)U_PSA}e1UoNnp1%IEo&$RFBhpT(TzrwoGTCa zdg`3Rv94jOchzkx*w%BF40&a@uBH_{cPi{6}xF9>H6XfMJ2P5N zx(n!=dMY8A9hD0^{xT=m&%{?lQYxoCOi@&CKCuWVt(0wF&F&MV8*f4tQB^YAIkPQazf=Sa3iCJz4=}mcqu$aYWnZV#PcHNe81Eho` z)M2pREJ+p~Fjj@16BW%di16pX39Z2m)3bfb$#u16Vxe1}Hx}jxCEqmH?xNF8Zj6%A z7XMXfS!fdLusv+mDE>`|nxnqaA%5#6X{{lILdoEi--I6C+{zrHmQtQ5D;3wU@-)Tnz-7U% zkzDB+x7;`C&9@bY^p|;*T!F}lXNkru`AB^8tyukMT}&Qr*OSIlnHTYOuVH@Zu`_SC zzWLUTK;{(c-iB|tcok#$t(}6P6Im@vcdlkkGy0|1?-S+e_u(&!eCmHR?$f-hR^BS* zdX@|3;!Ev0V#@0@UMHXB0@ysSR(?Kat%9&RKfy){Hu)B*lu5 zs(eD(o@jSUN%c4y!XNm!w<$l5!_fsUP-RJ;P)K#nM_Nr3f~)3+Sd~MQmmw|t(A9pZ z5`qU&yY-?1K|JDW0O-Xxx-iQ0Kq$BD084rwU94k?`mgPO|Dyl(zUqDT-Rt=3M>tAJ z@p;DB;s5IX-PzfDZ2rdQySon`J@~Ka>eoQP62pFA_)Smp-{il&y=aD^V+XsBcOE`| z{Pmw6{;{{SJ+J>U|0&q+1mlOYCd259b3G1w8_5n3Yi*+1fiN z^2MD__xHb}z?^uhoTb$}?O|IaC>4!33wD}~rb{vbsn^qVmhuqL6;($D43r`VbR&ec z8_fWl6Z|)!nTf|v7wbhyYFglp@FAfTfP$%f#R;9!&OT2~p>PFXm!^yU9Ej9~pox9I z&sniG!xQ*@ryKoreEQ?7x2F-bcysvj^e@q?XVKxyzeN9Y{PHOXr2pUR zH%BKYzyIB*=cqN0h#fk4~_+ z7e{ZN{0Kh}zdwF{eEJtyr)S5fFQM1y8T5J>y*_+%di><=^TRjM>$h)SzdAVr0G>j> zFOOe7djrE9y*PS#+Jj-?S#z)=AAUTI zeth-(=@C5q{s>?@{Qmh7j|KC3^8E1lMK^kS_~P(~Bl_wUbo1u-zr%J6VD!_ENB9g! zJcR#ya(evgCC=o@tCy#5;Aa;m`sP%B`_u8sQ8zk#b9@58!tCC>f&mbx@X0Ic1wMRv z#N8miBWGEl3I2Y2a%4gC^yu(8^mc+@+pT*-PvA78LLfT&+cKV}i|Z%(40UG1snT9M z6`;LpzscWptzQbj4Ahgf6f@LBq!6u#=+G9XSGK}FbxVcxv!s3`SN#(nC9GD`!+v26 z>$OpCM2w~%V>niToOTsooiz}44xiW8-cJt^Bu@|4{yu z%1gh3{P$?@@#Bj8xAVuX{I`|=w({Rr{@cobzb*NXtg$_;h7B8lQ#z}MtaDValCZSBM*a@DtbOH1xLU9$1rRWVK^&+X@4N|o;32IAA zov^n{7D7M-_oj+nwlPjMy9OD0wBWRfX$Ev1=#iM%6%aPAkyPXVBe+y3l2h$p(i?hk znGAu9UnC6Ef=f_H0Ur^N(Qg9C%`zb$CaNnxBPyOjQBn|KxbzxdihN(ZO~yRf}GCSPr8i)BWN+^68gaL zlX!;08->mD@J1F z@jBMER{H0}d~*srKuYg~{%N+y#JT zHpl1y{uKrTK4cl&o0sX-OT>j~6sAc=dFN(o{xVSO`_?_{%dR^_CzR4la)#Ms%LrAC zLS5!zRw(FA-5SPYRy%R8Ek`k66+T-eMIYf#7S-?=e$ErkClgGPdJyf{?Q3y5t{XiLsGt^k^J$e*K@MZw`12qY?a6wojYn;<53}0<=jmg){(!Arj@AE%@ z(BHrB1_mWHC*$f52WG4$FdUp#C+1`~5v<8uZ+10s1Dv`KO*T$wTkPL}8t_6gwNsnb zAtzaKwdl`P1c&`89zJz0?Op!R4Tj@p2hp&F0Jg%uPeStAR%cH5aysFVCFm>M!Ajkj zf0QKrQW3vde3p(pN-D?bED0T=GZT1YP-MY;c@9h_wF|B%zVOpP)^)k|!B(4V*lM|_ zmiku5)}B|VT2PA!OqVO*BxD?*&wI|;o&EaF4JQP<2xg^Jz1HM?RJfsz>XNWKv)sz) zTm9cw{@?2Vw*URQ`oH;dGtob*^nZK1yMOfKe;)pEZ*Qyr+v@+e`oFFIZ>#_NP3r&R zqKL2cuMyU!E4`mR^a9Y&ruo?!Y*zg{hwCX`oEwGWb$JtQB6J55hIHCHOBT=J&!lLp zJS9NnMj%>)jJ80;yxT40E&Heg!mnCZU7>gOS$W@$^iSjx z`g5t`(RKPsc;oir2=`Hsy;gtlv#~RFeX8xs@5%e6=mw1FAH1&GslkDr0jr-{WTqAZ zg(>^>gT43ugRVN-bqH8YZD0^pH|=7KtWu7>6^fRF zc~^Pm;?9G1MO<9>dg2wxv{FGjo=$tup@-+(s_oR9z6%@s431mEx#P@1Q+=VXEL|is zJn7XPZIKCl2BX3j!~{}pfT2qtzT0`fqUKCG;fA~KLj{76u)rbZ1ACxa`o<7yhKwuL zca>IqH>_r~4vY_KVT64!Lf29?`h&GcM*^#Db?rOU1ljuZjJSX9RiPX?*DuREOmQ`0 zg^U8y^<{vY2KL`12C}6!nP<~{2z+Os8dhhDMvZIWDW>rPjbEtHZUJ}vV9!@*_lI$r zj8nWrg$L=uFWgye^*bJx_%ARMD2TwN(DA!S7a5msYF#~k*iwVf;wvO!(YMjwy?YP# zIOTWi>g&fX?|bYPN3>x0IZv~;f~_01hG_Q%S$w8?|2R1;- zrGSf8fa0nHC5wd7ha6-Z?Z|vALa5%5GBB0}=M-|8O_Z>k(xENf%|8CzAJm~`AYvAD zHWgsw1>NB2fBzv)r)ZPYK)uWt)Q+TOJv52O3pk8(u1Lq3>Rvy25z!Wj4neTZPv8YnL%Ynu;Z<^a>USP5_%cb8&0D29_XR)fptdFv?x7$APAl>1i-rx6AwyDz~ zlAxLbxl_Yd#r()_E6RsGzXqAyve3b$loa!V3LL9M+Nvu6`SHX1Lu7Lht=9MUXI4UI z@#L0|fa|*i;k*~UEhX-Ox-ZbDImRmW3?*C>3dm{(Zd@WlG-C!MIW)FxECJ3F7e%kK z=qK17`DNMlwx8sB#AV_fhE$wYc4J%$+OoJv?M!#1Jy|aD8K(ZE>CibH-vo*zLSlje z5J^^ACm~C)4kKR3s(f}AOLRO>v*neGkIB;iUKJd`X%M!o73@Yy?+i1a%c1R+d2e@M zSJ!+cqeSOw+?B_SR%0nkim#kKw#Qg#eP@Nx@NV$J`Mtx+D2+ZK6zX5F=X`@&u)GAV?%T#j&warxB7iINmg zgG5H9G3U};g?&O9OimhVf<16ajii<*Vy}w75{+gOg&HuRQ2HAQJ#cU?R5x6+_Bb2E z5-&J(i-JsKva|_M;2S1FiFK~WdbBs(N@By;;@~GZFsYlXNT#Ix6z`?g@izP$dGMxy z8NcpwB8gPF;=VR~*D?-s{YFT9AWy@52%20$pp-8x#vdAo0 z;&}Bx>{4?0`t|eUCx@tY>mR;-di)B%J&5*p9{$OF`R7;1uOt2PYxm{zS3f;HdVcs9 zdiiMg_rH5``n-Q~blU&^`1H-;=}{zKKHS;avtAy)eEQSz)6*aI%dgGLXGc#Ar-v_h ztuJ3cf9<_|XkMNi|M2qgx%G07DliR!NkK^y9{s{7YQbFvIBo4mySqEPB008Zz|t;f z{BTb_yi7q}rbiFdBU)_p{Gob|w2B`+f=3^5XcREwsW&)Md}w!ncV}lueM?jZ9zNKy z;8~XGh@b7L4jrwW?3zi3J}!}@7Z8B5C}M>QzW)(J{-GHTkkS zuouz=wJj6|i=-;#`u>hCo&!OSmd*#YQ|)T*;wn(wC&T0%266sW=c-%Tj#?Eqye^Un zDt0>#2JMAsR9y_`r42Iv2AF3cvp?G1gIg=UYVSVo(!r#*uIp_8_{G%5W;gQaI}Zsb z6G-O6DmL(C1!BE*7-rzdz2%1|eA+_?K=A4Y=x)orm_Lk;F(1@%qp)jRm&{p}E@?mR$QWfkqCvIbVnwQ^&;@TWIG ziWw__7W4A3a0D$O@({XPyCYU~2T#R^g=!(~<*RR(rC5cDN zZjb)A-5R#|!*~1e_B~b$r|;U^AnvXI=hpvo>;Jj^?_bpaQ@rrG64a+Tf;RhqqM-gq z@BBZ0^l0nnM@?oxqg(A$mATXStTypEx3lZ} zwe?4J$pY`lMR!Mv;<>gbkcy^kCWMWBmSW00q#T!Upy2SvMVgn|NP0iI^CrH$!xEX~ zprd?raj9%vdDbuDOI<6iACJca_3;y~SSqzRDIFkMZ^^qLLq$Oe1d~uimQX2G_d-hA znJVs|ISHLA1IXT2CA%7aN)|fPAx?6QP8-wEu@?e%=_jG9b_CRTMLIi%tw=JEjgm3P zP71@cc5XYi^S&a>Q9ONDQ;HR7?#SK&T+(o%r9eQ>DO>^k zH>F=n)!ks-xYw0cQ@tEe{5IwyJRtwZih)B-_&|T+wGbaK{KtEvlK`$(pnpe5^J}~! zDd~?>bRM6UtfUDf4up4YudKA19Dae0^A6T%#+|O8Yw>^+`jL}vT=sQhzcwqC5Xb&U zIA?1NS`E96vl5G(r{Y@%ayg^H zaMlsTaGbwhq_xqlb6m#zR2i7kTefvSb|K2jCo8|WNsdiB!KW#BYY+|Z)!!d^f5Q{} z_lx2q;vRmbn7Y{K)>gB%|7`6)Tl>%UzyBork5=%0 zavG3k`_IFNkN0+b`_F^j-L3s+Yya8Wf426Yt^Mb>X#c?!vN}J<_i>p#!v{bX;GaGv zN$BDsp7u%oHQ|@>GzIa}G@;}eeb{2Gy%q0#Lw8CQdu}~@^&u%Pi_T2h-#}381Jp?OY>b7pbcdf6@8+)qV3FQet0P^t=eS*t^caZ7oztdA51{``<4H(09>TW2P9PE6xuIUBFbS3q{2ckklTP9f#Qn`w)O^$~>%bXL`jJCZmCDh#Kq z$8~kd!|2OW7i>gTw~e-{eW@Cv#%pL_@}-+B8g7%WTInp}Ib!zbSs99+gVs8{1-t(< zaClGq&z>Lta8esZXU(=6>0-+c=<0!Ugh46+VGAqN%z*40VVJDd8HLE*hflf=9v59Y z1r95J6FioaN=WzEDYV=+aa)2#KgHR!zjZ;qX(4A}5*F&pUrGwwPHN}__Sy;2a7)r83|GQ#M zsXTc68F%WPA9#d2&H_k@Y*c!~BB2IUsW;vp-*`hy=!|7GQJ7dU`9*TI_>40@h3-Gk zwC(@gHK+epOq;TJe8zeI8Tl)kUn?n|RMXQCd&z93g3PLWXm=g&!8eWSyCdw*1;h1Qxm|W38*D2O8=@;;1n8{WQ z6Gqmva{geR&T%g~y2A4BNxm#`n6H@ABPm+D>6e%|3kA>gECXh9>`cYa%H>JT_s!G4 z-utVd&*ctHie4W8)BzaGI-3EvOs|Hv-A*D~Pa0cGh~l)p{amT7Rk9Xb^)9r?u5B3Z zqPkx4#wn+e9XPTe|9g2Dwm?_iE_NfC1+H;JWofI#kfV&HQgXV^(Jr`XA1-U ztJe_^OqyO8WI2~a$%ue7vp+`sU`{$5D9xh31M?KJ}DaGswAUdrB|c88)GEpoW;kVqEkIHAK5`D*R5=cYELGgZPdzeXFLd{mJN zbf3Lu?w1hppb-(mPRkG*SSd7NbtTA$;*Vt8s}YnV1utKC_Q3Q2VVvjLxKvmCofiaX z^n|;)Q;(GTE%9(2Ob}d~K?Bdx;!f&8d$eM=j0HU~XllL+Y?j;Wpk9a$S> ze^XVHZM#NbN;U3k@ZcNtZYi~!iDE@^kjjC?>N{Ya?b*yzAk&9wo3o2gLy-j)%j#|p za#RK2Na(*ayjIGRhQ)2Z|KTvlqjM@-u&I5?PNmH7q{SN7?Cztr32+~{CDcQ0hz`5^ zt%a^p36%(12kK_-02Mh%icx61MjOQ^?uqYIM|f_&qn%E>L&k~pYvDAVgH%6>W(ETD z&KH?VZ?u68f=*i87gH=gj>PaZq5A7pH=PHleb>Q|{hQAtbme)yZ0OSadNq?t_(9p6 z+^9bTr>VN$%#51(sZkDFG7y7)<5@^YIE&9^Yp zDC(+@^67^-7#4ghV#@%UUU65h4RrIp?3pV!aG1iY+}LdQ$wgQ?eO$~Aam#jD{{IC5a{58J&IfC>UvaryR6CLkJxQwk&MnWRmg|~ zN#f-ha@c)J17vS0%SaA?ihc3r;ftda%4D->TSvjRKFUT_4$Iuusk|`jNW{>LG+R1ZSMEk`MPm)*&`pQ@SHw zc>G9rhTHP>+c!tN?>MoMvrq54`^WfGP;64&&aZ|j=|C=3LYO>8sLZA^KGPY4yF&ZF zV@?;o9-@HTmnODvGcUF*8@|MaIguBxAB9fwhNlUgS1p&Z6D~0z z=T*A3y~?n=d-swn%$k-irq}oGkrx2F+Q)WClf>7tqFhQBxLqo;Sm`mA=u@f1>GtbH zc=6su&rd0dJQU9ZI}0IYS*(qMB9|SqhLe5?_<%AUrqgsmfyF60q9EkjEr*f!xx=Hh z$Hk_iqr47R2STEYv$?pKbz@@c>+XqjPsp+7Bw46?h>w`|eiL6@7 z;ix%{S$%f0Dq*&glxftdjAHV@8Q6HGTcEiN17lcFN41$$jcU$qxOQ|8a)`LA@nd{% z1^9#$#c9kkSRF6PnhwnhB+ha!@p(RP)AT40U?XQ?fA)+&D(`SD*>z2mrX%GbvG!o; zWx%b`;BqIkqanNsUz%6cebLrx=nQA%_EjyrVz9YJ;!j#rVz6r5`~dAwlpAbjmP71u zGTc{$X<9lgphH&V-qySu;LLE3_GnJ6)k?k9 zhMKG4x~n#vYHCfI2dtcApIM6W+S#x-v<7PH7ri0B=*{~=ug~X%BKR^H9G`JwA{t&#ul(PQ{O@BBa7 zd$_aB|F_Nmx6S{z&HuN}|M%O<|0g;B7U$@wNcw;Eq=-k!Fdkj#C$L>W<{2fJ{!SiY z=s=#&&F}I$8>PAaJ`u$`X>w(TNYTghy&a*{8LQDX8PK6ycp^@C^6X7l7M^sJ^S0`ESDhJVhdKx9vWhL@>DvZ@Nyjn4B+4p?NmVSgtTgE-xg^D#w$ zn&y&SU&-3Lk14Cw!>|A6$G<~Ya8>0IOxL#m0BOSe$aT}U;HF8F^DP@D#^SOX16ju$ zPh`Bn*Hr_8@&yj5gx*kxdpk2qNx3*D^B<1rNbe`hAuWJXAEan#nUU%Mh_%!7*v1-a zlX7f}R}!I!RV#GyiYm!c<^W=5`-A!QKGkr(PZms8iwsBs!WGO_P%sX2iE+Ae0r_A^ zD#EnvinHs1U$XSuK8TI&x9ttU2Q;dWF`2%am&4m?g*WOfR~Fnw`)!fx>Vz z0weIC`}M<}i16U#+u(}XQ9H0=owamlA>|p4GVrx6TtD1e1J>&m=Cn~((kCzQ;1FJ@ zm{Ofejm#J?^Tn~+Isj`xl)uTC3>u#95|?VV>e4wAWE;f&eXUmp&ILjg^na;TeHl%Y zI9twxqq14*5;q7nyT6>%@lTSm4zR|P=%D^>nM{^b(%Rrh1@89Yax#I{quPBKzroiI zD!_Fx-#YimR;v?lsX>X|z8~0%NV{;KGG3h=fe0>>SO;eTV=04CL6+PU2b%P+ zAf{}4us-ckGwYJ>J$rNb;;4Ue{C|%+j^zy%&G2~#E%4#?Vb_{rt5s(X;MKKm<<$!e z1ex1MZP=lQe}0l@A3791KejJk<6=TiXk^228mJt%(izAqu=80nOiT*gubT9@ECP9x zaOZ9V%`6N!)3M}rEah5qZ=nVsL+?`bHv)lArO%S9WVBphQptnXWP%{Hx~NVsQO$4I z#(tfdUEZq=(JvQcr0QQh{1%}vn#6#V z@qUeG0X{eG1<-Xz0E0i9Qz0_Z(o)#!TN#`ByUih{)S#*Smwf;*Mm)_XIZU%aHkw?} z@(3@aG((=655L}6UzWWVc?*tubE_a&{ch}Cq|<4;y2mtvy>AepL?i#sF`Cj4sD#&T zu|S?#pv11L0N$yAPf*jF=Lk>@h73L`{fb3*VURQKML)&q!pB*!=i#V=6OajJSi=kn zRA+qvgz9sW9Swvk6sx>2v9uhp#O_MTU)%;GUo=BeZ`wAY471Iu@&eMpNuLy^Js_W_QoYMK|Q51CNy;#5~dSjS&a z@u93xz`}%i<`hsien!B7e@`rYGCqEVg$4Zbz>E^&OJ!(0np5Q@!d z<1}zdI--y6MNiptxMX(@9)o;12oji0ZGmQ*uM)t=2}Y=wJek3O*MrqbHuqXidlGKi;d0{Q>6QWw2r-u@hDYk%pUOi4u zgE>rKOD7-@v*LVZg>UlEKy}NEGIXU`;#PA|;L7gg?g{w8;C>3&#xMdI`*RJd153Oy zxx+WefOw~re^vCN_C7TT6fQ;NauH2>n_&HMFRKE`ynhbZXVYCJd1(K#c^Ad(TL`SM zql(Q>Gvx9`!!aQMn0K`H%hRJjzkK`rc{ge?O!x);@v**st_v_TrQYpFEG@=tXCURG ze!ExBr|H7`)b$^wZzw(AxZS#+wmNmMTHb6}AoW_y;Lv=6wb9Gn$5Semem^eopNC)X z?CkLG5&pABf5W9cO+F-3{2`Z6tK#Hpd;Q)51*_*yRByNCUhSBWx!viRO()yU+H1A| zh#ej@2`uZYB7}kXr|KeBsrP)voXz5B$^W0v<3!PqY#HduaeYv@AvT6otFD za6R@1F7jbQT73G8*tKE0AiD*#N8&LSj6=8NCR4`OdfjUb}peM;)aQ@Le zPqPIDtQE<9jf5PtabQdMn~=u)1vQ2y{4Yjt`jWi-;HVN1ctJ~w%TdmbhcSvE#X=QE z!eC3bKb)!kkT_E?#wUs(l3B!~b1V-RbbNG4~as?+v=lQ)PK6z*K6$8hWnO=dw@qbudm?4U<@2 z?Bd|935lMPM$A?S-U`86A-F~emJ8zmE`To6G!bn>(s4Bm;uGcNt;D>J#BAF0rE?Iq z@Lr+jik*(yExZpP8O7gF5F{Hs-UzQhG08Vyvee?ey^?_${AR&@sk6;gJkHNOBKj`!*G)d&m zc0)B3a+tK@K=B6WKv0Xk@CS1GLveFJsQxj^i~Ju>INX}WR4P6LOmPtuhj*(8Oe6^s zN5kg_$+=;jZMn`S{*-kf7}n-F1u-Xrm5|AY90;`JmV)cB7IuA4TEaOqn);dr{-VOx z$&3!7_%coxkqX18=d#*&$~-&kT_(fX9nU7m3D!n*{q)c)sU4s}#}myZ!rXpJvoVG) zA_m8K))HB9GGXbTCWWq5T^14OE}XyJbmwn_jxfndbDfCfxl0<6n*Nv@c{;A5Ob zpj@qOxg6>H|MQ^Lp2}?yyM8Pwf9%BtkI_R6r4OxZ3Gmu1I3zXPEKkJZ3`5!mbRNW| zsZl}@6Zzir0g-~^NT<|>sY*F3^k#>uN^*AA<-}JWj#(hZlR6l%@{biycofwMZIdpC zmxu;(&ZlmS>+bg6)=Hob3cv`hIR%sg0b1~B>a94Qngt$ zFJX_&(^jD%`IRd~k>Os`5G-=3{78;`rwa9&n(#PPzm9s(_sgm-cah8_6v>(hGw-hU zr}m1l_Gs7lR8j#(gMsWCN!g?ojIPtLC47W^hP6|tIPba<_fmhCb`Wphu6BqX3|hR| zS}NrK|7Y(_x7#?fHPQZEYt=hsNy`PmhEkL)%cr>tK1EBE%v09T8p>UZ#Rii=lFSl- zL?HoDv|Ih>zQp}^U-3S|-BZkwi3CZ@!-dy5B_cC2#vMC$?BUynz3TfOO^U)giPvr} z_Q%JpA8?eUsyTa`G4_ul!>hVU`}6KOOuJWFqcQhAcWqZ7%a2Ul_ApYrV_w(?kIR}h z6Gm_{_f!xzs}>+CCHA7};8YFj`lp0uxdKWLEMLI&QeX=K(CVOXF^$TBFR{uhF1|JM z#$VzTsUx4@I9b~O7YiF$t3XR*G*_qfs%hL|i>*hvWi2u4vN}W%M{xyHKU6%SX5SYX z_LBQ|mROAep$l&>a%r%)OFdr_!DFCB)sGXEvH+hbewYGcfEVUuatKu&Rtlq*N65hcte%E_HTq#V8V$4V_!bXYw-u zFY_Bj*6nndXF1XbYtn*`)H~;BLG&j@l`@k}lNjSb?b_TV&$)&!gC(V0U(!L^a)zgL zsHILnxt090MqQ%_7bUPx4cghQL^&kO_@g>AbDX+P)RU6XL?!+c&t=R=F~gKq<=pmK z4gG#=4r=@`U94uqVm9Or19QSB;3S)#jI&*{B(WP_dnaNMP1Pbr=*e?4rW2K@S8mw! zCo7Wmz0K)N-38Jo`3)NC<5bf1Ui#gp<#6_|w*so|H4D&U5hA01qIQ(6%y6f=cA$A2 zz)gE9`;}9GfXHp1RYs&E2XS|PTKYoE;$5xcQ_N{Pxs3Y`#gz_!tq=)e%nX1usYnme}qvL%x`epxPA*=;{e#A4iXY??;F9*EY!|)Vc#ziVFLrw;*ky!ql0$wYVJ8@r4i5(R zcY5pDpK};L_(3{6E-oEKMG}ljt472S9 zazx2YlPLNi!X&^%bUUl%>3?)KqD7uS*g2zfc)Q5cD$f?9^X}pn+bWXVJL%{DNw<#O zr2Ef{FM7a>0SPXiLP znM!@2sWb{!Ml~uB2N8k0G2D(AgDDqi2&tL$;zYQl<3?XQ^syZwmeyIGbo2BqMOVXg z=a^{{j^NLFQRoK2v~)YlKU2=~5bbRQhuf}67_VfW*hzPKZQ@X!>2;A6+WO|}uc=_D zkrgbWbh?@_5b%At5EUAemO2j))196Vk@J$k^|~4ZDSbnKseU}(|9Ly*XKw)F#>6XZR(63T75)C+T+q^u3m>Q z@~DbimKUZgXAH;X5boviO@_C26ohv|=z(m33yzX!if;Qb7poa&oalL(Y*=BBU4Fx1 zBoRul*&emyxs3pfz=1I!p_p-2QY#cBs4_x(SE50$!Y>BNz38pl;&b{`h)yMz->vCX zwRAO<=IR2Z>epu|zl(MDMVc7s^{N~(x$9r1@hUOI(OVH`I3-{3FFtBMw+8RKwqOVi zpTIkP`mJ4t_7W-&c?80Z8WgT^1dTW&cQ7z&7b&hF zvsb{9F(Qp3Y9Db~R|c_P_`_EnjC9*OB&;LUIw^MBsAA2hU8;GF5;Z=tp)R$9-Zd)V zjeDjY>sXnZb|PBM`=r9LR$au*j4Zccx`b&qWX?sK6QZrAl3%U=$rQ zOdf%dnN|qJ*fGP_*+u!dPJS|QDl~&$Cb)1yphoJ;5N~sX*i_R%xEy-&52{Oo>4Bnw zPQ7{TRCk}pCI197V5J5|LXRHobSO#|zXstce&V|MFgT429G@x|LtnB1aA_cv0Ugo1 zbuAH4Ti4ascs0bc(baT@>)o(7SCe#FP2EPraikg10|^>kohm3UpJ-V!6oUNfN%pDL zS4FGvYWExW6Eh8&k2?1kyDc)G8__v7KTKl&TB_BrVcd}mi!LE#Qdgsco~1Hu_Y+mF z`7BeWOEh?)56ucBxqQg{rOHluB9xqa0la`)P<8hmIT%TE-FaARIC?F0(#3#cZ0UZg zL8Zual>Y+RDYpM@^M7pd|F`)+w*P(d{2z<#VmO71CVH=4UVm%U=l{6(@WIa4-u{2M z^Yw#m{*P_`k8S>sZT^pK{*T{R{tq^T4PRv!h;99>_)sX%JhoyXN_YeyoqfLtNhj%~ z|0;`FxAR#w_-uip!(B8U^tGe0AQ!`*h;qxQtP7LhRb^`q?RlNQe1-_3-%y=W*f%2E zc>#GOFpy_?Rb^-S;~Wzyu)WC{UmVYyprEjDGS4p2Q%jJJc2QBbdtA@jTmW9!ewf$w=iHf?)AZ`w(iGV5X$&Umdk~^F+qBiq@7ijU zZChPu-x7KX?voFEmVKa{)!L1gyK;Ec`*_paS;4yediJv{_FK}$ZnT%%oUb`Zz}MKm zo1RXrQNDpqDoK@{Bicb0tH%!{8?|n4T#Wn%F-Hp-z6oGcfm9x!L4%ms=`ZKY<-FRx zt8@nFZhUu)7%k|UR^5dwS#@^_!aw{Y-`tkDxWnE4=6Lv9JDwHR&aeAuw*30r9op7D zdzEK&|J|eiy|In9kZOlOiN_jGucpi*pThm~6Yj?ny^pFTv(lN;Xst1zQ^i78mJ$v!^y zhs6LaCBhjN1cE}}CMP*6C(!PwF9Xw)d=cdi_`)9t7q3~CGG!!bt? zq7|KSL0|3jC3?8``0=qQKdi|>oKS*&1hSz?YtMU4OO5D;B!prqfplCHm=Q7;C5#%$ zBLc3q0V|BqCjFDGmTh~ z7kn)*?lXP$twm_do~_>B1e=!OJLT1s1ciB147l_DJ3SICpnn8|q74zo@BGrDojP(J zp_j+apE%?^@(B-<0@LwH;}z!^yh%=9Q6p}(H^$*(m0wSfaZ{qv_4nSdmEdth|4dXr zByQo;e&f-!-59MazbP5VmDaAUHsk}d4jhK;_S)5FP4MBj8D=ZM=+dB%9hqv47uSaPJGE?$yw^cjy^=rPmR zU`!0gwGl>1Cca3N7zM8n77PhotTA{EcvrrFTQ%Cjh+9;i+H{;(Bd9%xG9Qw`Ai4Cz zJ|7`YRE0`ugkd&!P~6`6zgO8LWn>iuRKfgK2?0ytI1BE+cYC84qe_D>r?B0qW^L`& z;FN^TY)lnFej~TeThy6bY18=rwBh(LWQfODU+Z~Rop(P3(YJ!>>0I19lp6cIp)z30 zYw8jlY>fC*^kG#`bKPFCC|Uy-lbn?X{kSf{LnZgDv}&!m8_6@EaLnPObPl5ICRLH6 ze9(!*Ro({%TUM;HoH=g;9jd zoRBQF4vz|nvV(gY>Q`_yV(V3yY&^buy`XDOIeXL*JQ+y?z+H%-$~a5C%S)^>=h>te zg^Ka;f6UAZ_3e2{W}rawb84Z)B4qT)X^FWI|3>1U<~BNtov|Q08Ktjh<;CeFdzT+4_;Uj! zcJmM$-L0wBv)*dI3DZYfl#BCXbdI9jB3#rqc;)87cW>Uji~yWzf>GcEdYuK9z!ZH_ zE>4Q^IQPEB^r~ad%BT~pN>W3!d{zAzEOfRf=&KZ_oS=!pY(0|f7)4V->anB_bY5sU2fbdnoPO0K@!TatvAuddFhM1HG4@<5bmLNvceNeK7dG!td(_@1y#9NahbDVFAjOg=p_Qvq`V%CN2EHIZkH)o{QJYY;1T;(9f>@0--~cmiX-0_spX8^^ zE0tSijZmYouk5?3$Dh=F8`Dr=4By9H_@fwm_)Y2vY5>|-6@|A(=?U$@nnWf1ZeU&6 zBVf_K4zz2ZoZ4%Vs*V|32;iIov@l+rK$$5V4#xjSaDg?FC@U)OrG#BDldH%h{$4 zvt9|fW)$!6YH|vUykG+LV;tma(3s0bSosylaqkb zBbi33_Euq6dG6hk9Idcc6*|K~79|~Y!^-^G^{SqDR7%~7Mq8-8yNNif8)RKd#&Y*fe_j$*BQ~G3do>^`lFTdgX%YWZEKW)ZoA&jAQo*56F0U7 zQ&m^53f#vd^8s56y4G$!_NZ()AMoSfD>&2Bgz}hhl_FPYXm8s7y5vn+nf7#BH#LXZ zc-%OF+x!1k{@>pJxBuP9{lA>#H{kof{{Dae%liTT=Yxk|f3>~;Z}0!x`~UX-zrFwe z9`FCQdy8lREJq)$CBOh)T_A8!;XFerJLMuIY}iYir|*{~`IN zslrSq1&#pVBy6OH37U~Rtm4Dx15Fke9n9Jr32xOyk9XB!~ zWDnra8}>+?Q=|g!7rFYZ(|a<`2Bp16t*3RG(QiJI@J}^+ari2k4h})lgTS9eS{m1* zy=s+;H)~jV(g$306YXmYsKO!RI#P*^!VpvrwGGv;L{{Sgd-TvwABdYzy~35No-7+< zJpBCB9Or@Uk;hded_~^IV?Umk%L8=g#8pPOtk8prR|U>y4ijPS6iey)3Uh8wRaRG^ zV9EtsPUm=D^U2Ll)^L!+J>)dUtbx4Pm6wA0HtmGJ=I`^xC1#dYyEL0zWS7ju@ytQr zR*`G;31cd;uvE-IU^&7eVwr&fsCW(O+oXg>W@vb=4F48 zPc&PNR%^%MM5`GLTGfMlMrNP~!V>;eJ?=%^z+{{bwKhZ~p-lrxFBPJ;Vv^hha|`xO zvnjD1wMJsM7HbvMvw822_VxMTB!rmId%ShT7h#iU!h$Ejz+IJs29?v~R zc6{DysLuXIpD*DDatwK~fs=9(D@+HDQ&b&6e)>FiN|b}#i6_*jS^N`o!g*nc_Q@Bf z)+?$Z{FALF%N9|H)S4)xlCxZT5P_y>xh>VI+|dNo&QL`exm1p^Fh2*{Ubn zwU=Hy4h=QNa1sSH^^Nb#k#5PiX|e~`s7XP2Ux6S%f}D*(lsrBrQaV14cKDHLSCQem zZeF98YdX2A>!mp3vcjOgbBqo!%o^zr`2wZ?RDZ-*nku7kB}|(PC+gcbkK%oE)Diml zXy~Wxqoz*c<;Zj^Q(^7oHlCq2up-O@+D62n|-L^rEW=d6atEvcsnPme+j8mm>zNYpfs>zlKAbG&|AF>EhKi$tb_Wi*Qadhb#Id|oWOjR*ayiW$*%;ttaBAH?NW)u zd%H&@+L)PuQcl-UH?M?Xp~<7hsr;sPCW#o~b_07@XMHE;(-0oPA7yjITM5_|sW1ez z6vq0~tzvv@H~H~!=cu3DQoW!j_l`c&Ec}S$`>~kQeyIA+P93u?~{Wb1@G4YNU*OSP2d5X8?vKcx_#wJs_9<6>FaS|>Nqm0||9D_29bD@}kG z>gvQ?hcT~vz%#j*q{S@-`P6baiN(kA6mx{^15X{9%_u@{jvDb}(mfp`e=rAZ@-Dx; zfcQRzR}JR&6(-6U|KD4EMBi4d>g5m$L*uI zh@8?-YA|N)MnpPy>QA~P#jx3qL>tt0UF4IAwfWYl9c#5+)p@y^j8WkQe_hOMy`w0Q z<(R@KNNcEV^lNQewJ!iCmwa)v!%x@gIQ^AJ!C5{LH7D(<6V}vTFk-{9oJ(Q1BBRz^ zV3-Wiyjsl_5LLEoWL?5e=mII!*OLC8`DZflJp<9jm|9&RQZW6wF6jOg*@^vy8)Yjb;Et_``p z>+v0B_wBrtx%Ca`viHZW!|5;e-`4+o>;Jv=|K9q42masHc}9;Jv=|NedXe~Y^{T`r4K|3*OgWm!%t{RD1HXF#3yH$|z8Gwi_4 z-fHr8Z?!C6~0q_@qEzDCH?mztp>vZ1k=?JykFFKg{8BOO*O8 zzflEM_G2mddE8gM%hx1sL*KYWUErzB%i*x9mrmH&HHEa-jDOq%KF@o~~tWbK4CNCs*pP?7O{i3v!%!yzhahQprm zlcxlB7=$efff05MKHlM<2t7!>hDZ0*qiRLYGWV79FHZRBB|MQVqD$m5GxkV)psLL? z%x%Y&f917*u*|2sO@Znp))4kLE?1*BWxk|{a{2;(Vfnz@M`hfMB-^C#(6osE`WWC? z8GeWV-hf}C9((Ufeokg6$}f(`(-wpK=kJ$xvYYxu=e{}znPQTUhq+>XIHz5gT;OcQ zo#JU*V+>P+H%1w!HfP2es8($8Ig<+ajx;T&SNaC7&L9{1MVj1nigBY8^hL#-!}4Io zuO``QHaZW!bY@qRL&`2o^qh$w(}V!q?z#MKgnM;jig|n5s@yV@kPL`F%peHrjp9ke{MQW2?p`mdc7(~|3NWd~;2zw&V#;ex_(3~XRa{T6Zm)Lvel`0K|g`z{^~(5a3eoBO)l~TL=|h7qo@H7PVjz7 zp<($4LLanVC*fSRe_YTgj_TXu>^SVIQa~L(v#29 z`=?dMF@iv2w9p`XoR)(;U~=l1sU~?o?^5|*t&C7ZQ_>@6B7Alw$AixvFV2feZt;<| zTRJpshYWjOP9{T2NA06=i-kMfVCVyrM=H)m{PwpHlaTz4u4+~Zb;;O-rqoTKo{~=B zz(v>)>vXs$xbS9Sfp60>NU!!RF=TC%QTjBRCw zpYeo69)R1n+j)vGaLT(B50lT>+I^9qR6@T?zHcxyNINu$w4BH4jX8%bN}zIyG1t2y z#hbhA$*#RY^*Mx%=tD(>%7J1(k$A*4|5Z6D{03T1<=;cL?84|_39Og=Aa)L37^Hqh zqWEJ7OtXuF?UQ#r$kl^~JLyiC+Iy2d)qX#1vT6KttIck?{!WQ_-LlNjmxE|Br8?2K zaogMk4f+JPC4^5)2$q`T0N9iPuGmZX6-9lZGagDO94Jd222mR!Di-A=Dc@u6D3v>A z#A~WuSkMavBd8@ELGI+$d|zbA?lfPX?;hKVS(YF$#~sxr-kl&UiQi9HmdaHQf<}^r zd1&x$l8eiHxh^n$h+)8--H>C{tv)wuJNdi5J;sn-a3S<+q(5Tu;rzylhcW8V zp-NV0{qjQnM6z5T>G#8VzGOHNGtc_Ihts@TU{5BOtYaA0rXjS4h9_4!&u1HH5#nxd zx;zD15fx#dXL`*?88VfAd;sK+JS%N+V|JEf2o7S#%wh@axDE>621#msX>~altKGQF ziK5O?n_rW&$%^P{eQ~#Wt4yRdUmKlE>nD>;kT8$>i5Yx$mKC#xf$8P0AKcoZG!!(W zifOtw8StZkbm|uQYAf7gB3i9-WW*7b=LF8N+32!qQ=d-CYze#iS)NrZkXh9?K=8|p z9Mv_+cl&#<-h8{i_l8aX=J#;#(cd^`3Juwn&%0|QKdn74t(kK(IET9YPtQF^NzY#u z(_)fQB!`Xzp*P1$9KZ-A5;-c-FiqzZ43%KuCprO7xwn#K*rfE4yjRn5kqdeX#ZS;K zSY)$GSaJm)PDHm33oruF9FGvqCy4W`D($AKq%;ioRERWGv82%>iR=!lmpDZ>-fzxU zFiNh@A14K6X3`5G(hF>|Q0ARX*c#S7gX3>TC^UtfA-GsDB};Ufr4dh8lVveibyX7I z;l`+%w0YvxfxQq5>&r(dR4|f`o^J9>r9bN zFeMs;8z>b6qM$TLQWKzD84W6}6yk<%0XLnJa_rL(b1PX1wzL2+DNYvI;*wW~yCUoR zEsR_28wqrFUc!vgX@Z?TEzVXL^0k7wDKC&@E@cj7NOq4h5ImHeUirC9DNaLo2<@#( zI;u3uKz(x1L**=eQs>nY>*af1l0!1gQ*;Vc;EtLHp$a1)VMA&1?WGDB=`(qi(_*<) zho~$Q^-cOBBgb0`SGmJcYqm6UC%I>3a9=M$>It)CKqrQo1VKv@+?(kLJe^=pSK>{a zbl3uO*X%0>_>(Qps(yktA03_e?gAg$Y?hy-^K!0K8zdT%_kL7L!)^_tpH-3XR&%s0 zrMhc&r|^HQPQ?rbrpfwP9JeelTRhK}2{`s#FS;FKfw*6h3BtZuDe}a|nG+Hj3Jt2G zmzzsFzOr%>TD{%z^ph^GHqhn@7+J5^zNcnNycCm^NR3Gd?`2eRfa!zX0nq@dOmk$d zit3|rgqWA&us$5nyZll?W*9@Hdkq*0l@5}hK8Bbh+Ilj?Yo1YpDXqHmblvCLls?I( zC*y3FiUs|lyELj2g=(zDe%i?Rb@x%MHLK#+@BOH_?&r66)`N=dq#DY(v!6`>eoif zL6&S5)xg%REP(uRG4h2x<{z6?T$b;2t@wAJ;=K6@{v}LC+r8~s_|=G`UIJOvkPzr6 zR4Rhwge;JvED^1Tv}a3@a0K$Ugx$LUIncTrO6Oq56KEEbU`O{Fq^FWBqM3XCsP`CM zpO4-d34=sDKBu`zL4j8?lc~n$I6j_bGmslN-WQ#62{TlkVst}ka|==A9`_QW#lSE@ zCyG;Tm({eZ#*c#Yu&<{>!6@h<^pd+ErU@#5YI8lMz?ZeSC2x=gJ14)1{bnLMI@(S4 z^t|gDZ-kO`Hdb9f9SH)GlC$KE%hXkTM9)r-WS;2CDEt!ZBfd$Qi&D=RIL&)K;c9Br zVwq2?u7NVaIn}y9VO**bZ*~Lqn$~0@ILy=Bx%WHzOC)oSG1l6=a$z)VLU)|~+8KAK z_15~X8m8PfI#;{9+3rs<3=J-)huYOzIq%eHB3kZbjAEZ<^Et=^hXqy{omT@5H082} zSD@I>p5w&=4NP-9M&9Q%_oDQTUbTPHE4;$~3e-`SiI)8-3RG>uQ;>2o#fz-~ zFwpH)u58XNc1cOiPjfi;{nM-u!76&1S<8Tc${2bgNYVGd+DWxVgO5W3Uv>*S z$CtBA^!k`}`RM=SO-q_4a0SAMmN0iYLs!7*Us6Mcgj38zt^@;%nva!?f3;ZWe+qTi zgCEPSH4_JQeY)^>oGqNK-2ttai_P#X8X+W5MKQZHYp|MS?=ujYP8f}pb!kB8zPFYy zXh0?1v()|?xeO+iPr{8}k6G1$Ik77tAlTU*T6*au>dIIrula<-eC>HDK4>Ud}E>O@rr{nv35>Di)O%}*}7!?iVggQdCPDV|xiuW?SXZfZo7 z{1p!?qW)$bhja2vBt_pE+vgZ`RiG>JfPo-)Z^9^TDwThA+k>DFgUI}oFH~z&^}YXy z+N$;a-p>q8UDv}C8Hzsvx>y;#U(2EQ*2S=0>?@~ZHprb>SZASv z>G5<8@1Rx^^A&J_QvIUi7z6wyH4fx~FooD^q$VIKp^F~)A|YCr{B*ur4re8H*S!lg zI6>GWs%jmb*Xx%2Vw#Fvgbs2YM=AHDTn?o~x7m2#T#r>pgSx~sum)-d>r+d~=d0iX zr5w4>G3H%F2wl?~X+!;OcfzJ>;yYTa>Z$&C$6D18G^;9oxN}r%ziX!CfGM|SI01J~U)9#~M*Sj39Ht_AG}bwz4xUiPMz ztw6)wb*|&<;#uN0ek@vfAqRNyo4mz0=AfZm^RPJVe;?Q$neqFPzGc5Ji%~8DRJDPN z_xn+euS5$mh_9HHb4Dyn9q4(e1ett>3fbZ53hlS7p;D{wtAj0FLa0C>)GyXeSre;T z+-;Jj@JCmb?A3Tk(CJ+hR1}CZHSr6Y0NLm!rnlIs!{Df#kZNQBb!DidDVCRF*r+J5 zSAJxt?^wuguy(`=ms+c=TYiW1AJn#U``iDJq5U5&n!%;_OmOmr)}O-9?k&M~&Xc{D z2e+c~tb`y01LlFL+Bkq2xZ@I)MrKUe3hn|@Y;Kc)tbcBcOcfmk%UZCxrzxE(U;gYR7#MXYd3ej@Nl$JBR z?jLKDyfsOu@7kk-qVfrC1!pDB%HET|xegwL49RQh-S}9k1Os@7aJ1;*0DrT|DVeXT zb3&syRlYT-WQXMque;bj;wQuE>At|Mvmy=2Mn^eLE?rM5a}!(V0O~k_qTK4@a4OnW zYe3Q)JKE;ns4exi_+u!<(pY`U3KX$QYR^(sa#eZ0QMT}Pni|$4D%$nENpN`3Ggenq zYV>+wIXvN*Qfn?^{Bn?Vm>fH?*OVb1Z<99R+P5&L6;+DWS+(sIv-cppB8Fp|Cb_a^ zw{7RcN`M!ljbp|&{t@_5G#jK_oPzbzl`{PJ99MHy^@l!P_#ZxB;QxahaYhm5-?8{j z^L!~(g>?p*8y-S*0EcHrk61GpTppu&v#+iWHoNqoASn25k93ySAwY50bQ9N|?tA({ zt-y;a@93;msStu&-ZXFUromW%V&=+=TxII?+WZL0StP8feT(_H#edx5KmPjgA5nR| z-I`ncM+Wr$`SBm`efjXg!-oO>m*(Tg1zN@A6_Ta?q4MpuL6Vf;(+uN;1**_?bLb#pc-pH{Z~y=p{e&>Z_{kOk-<48=?Yx+)BCo7x8gLVC+_QWV zU}Y|{iy?4HxX}i$RHi)DF8IMB$?@)teFiQ{UmkB$3gq}3wQ&Wn*%;$Y}6O0?1tyIk>OR`f!)kMZ<{xc3Y7(p1Mh7mdt|Mj!tmZ+H= zz;;PjAOVcaY4_g4UV5H?2&^L~E6iDq+Lfc^c0x|pyaaw8T~zLHqQ^tW!8jX_J#S9= z70d@WmF6Fon6plm3N39kqTPrRNGYP!Ty>pk4$bM>k*zLrDKOkA^^Qp(Dcy|0Az|uM zJkOP?2c1W_xC}0Y;ZT5E>Qkj`!W>reEd5tm%qah9L(lb;q(d|R(rOHFDl5WBXtwFa zfDFaj*NantN;=4;8evQvcPB1ywO>$BYRv0LwY1176_jqtb!%5f$)9^%DlS6$Z#qFZ zj6w6TmeK{Kr<4Z5C_D0ur?PQOM>8CBfEl8zfuv=Y&D3j+8f^Jzals)P8i66t@~-|% zJOWQk)e(0|#U`jq^NR*Uv*&APP+H0n8R6g>v7(H)pJAXQwQKQaH*~6=J%3K3J_k}I zCLBsam?RJ?F#$|9!CPzCtz<4`Kx{8J_lKdJ-^d-MYL%ngyz3B#;!cF&IW_p$pJ9ne zj@ej8u(7}?!2-jrLBZt-!|g+V_@E;d`q{;?W!2o{G|8Vq)^k`Be2xD$B9_FUYbm~| z0o(RG2g&LLcKT3!L;ckV3c!+hNJrL*BF)9CiWGs$?x(TkjaB!Tnl!cwk#YNv0$(5U$zG`N6b#h`aSE?dhn%vMf`F>! z;;8RPoiVf2WiZe3Jd6gn3|H~f#hzSkcC+t8^>Nbntg4QAvk7-abf6$n+pg4e#`ngi z{!EwUa9r46CXNBtnF4+qodEIC2t(N0S)1EgoFlf;R@P#^*7&25$I;=aPa4DXy`?SG z?Mbdttrk@^6z&kNg&O&6feGi)e?T>|1{lqZSo)IcMCBfHpfO09s1+5(2T>15bXg@I zpfkm^lF%+V$1pr(tdi1Zm%t?v!GqIP(B&D`V^swk&ZEpokb?=Xu$Jwx6AjqfAYo{< zTFDz~y#uj-Ncdx`If+C(J>gv`GV{|4#lUz+-9V>40i4t{tAd@p4WRTiv?5(-tDiiU z3SlHa@LRIzkKRr4_xWV-Am-uiPJ{i^jda*2zeChiA{5I-NiIVe3CA8SlgnCCQX|%~ zlhf$hL-)X|M(v555{HUc5!9#L5;DPyTg^SvqFd~cl^niQNOcdb5>ZZI*ATx7x^4KX z6AsLgdC}XqdG`ja#cCo{&a~n);b1oMk{o)`XW!yDzVpi?k06-&_OFB|j&FPG>b*r$+G3P@vhDH4{gg^2)><98|1 zYK8WdZiku}c6w3QU~2skzd3xkdz7x`1UrLKL)dcAarB;DxX>T`C<=s1%GbD%zmidl zo;dvh{-yo-n9W4l;xhE`CH-m*Knh51@i&?ag|8fsY$;)Lr|)0ArHI$;LsAt#=E=SL z{}Es}f@Fj`2hqu5EtYQG9>Q%nI+lwpK~ad{iQsaCz+6&8qH8$06pXU*y2gelmqVH3 zaB$WYF}yY+*CbOw7amV?K_9k@cp+&A?ABQ^+5$#qqQP%cDwj~SH9dV~rKRUkX&5tt zgcVDhlix<*46;<>S3u6?;*z1*is>{Tqvdge2=3&!Nxq{?xUdNF87d~Gwl~ym4xCl- zK6s}`zuW>Yzbqe2QO#iYl?QJ+IzfX}M1sV=2TCO}63HUXto0}boQ76_8Cx*8Hy%|Qb z`m9t>SCy@`66Ng*;c|f>SM1lxCr^FSAQ2uSnS-p0&CH`(42vZXU+plfWKwz>^l6bV z8~Wg!L3KHd5GkM=IkU8V$XC*hf>|(`- zh*Evj#$;m&V~0{t>y0mx$6Fc{-oXcEXagEwa75uJ6wJ0LDE<)U_D^t^Mc1xQZ59l- zchI7{^X=VFFI?-9HRlbKPi+vzd$i6AM}ntKe&GUAku}R;OR z?W~(w8Ai@-2DNO4rQjC)MF3Xo84CkawB#sKTQe&OY7BQa*TXC$*yC_h}jAU3; z!P;W02Qi7VaYw~wp-gNEDc6bl3l+f#kiSG6wnOjUr^VuB_lUduXb;ap1F>fzmEnmP3@YtwBWF5Rs;NLexD} zCPr9w?b_B|V`;V3#{rjUTm-u6ivTwzqTB!N5xZ+YDbNC1M^6Jkgh-JPznpFDo{D4dXXN(ACux+=sKDCV4)EXK#& z9!Omc?Kiir=H6*FvI@!(X*~7Fz(0+Zi`>BU2yU#DKBX_F^eJ{=_QQd%z)*A001&WQLYv>+}E+qDC7K@ zfx*ki`f1m_-ddez-#dpvO5Ppn&x1?%l?8s+57bJ6Via_H!i8Dx$gG+W(o zvk{f}7A=LKc00G3>k@}r)qz=FrWdErO^AH~6ruW(9Bg|Al<>s1q~R)I=U?d3)3*oTKOR1MwZHdfKjB?ZVIr~A6D&&Cc--WbXCrZe+0cuv#^4~@ zv}#t&=Q$x{5a<{@I?1YHL^dTg*UuFYcwJSvJ^A*G^0+%Z1SYKl*p6mYC;!B#p*h)X_Gu-f*Q7X6DHD_W zTpYn0zFjj?I}E{r!v%VyZtbqm&)|6ND!)x#Q%A{(%@yU>XbZy;tY#t(>WbU+ZNGP# z(cP<%e+}7l-G<6TaMkM(w8MF=^ug3%Ef;oKE#(^KWGa_-gQXiTBMO*q3%Xf zxGnZq#-+vOZ-ZoKtg{wFiz3G>o$U8vBXq8SBV~YAoH6K+bWwl6KNIOh9?Y6gd=m4!XC6|w=5nOwEhgPK%OG|9XEGW|uBNPhackOP2Mb2*Nya{w z+V-&skP+!ZkbJDGan(7B&OuCzVk!yjByQ{~x4>SI_8TPs!=qj+@Jq|4X;%>#)z)9< zUA(0h+>z#T=yd#086WL{+;E}nZ-P0RPu-dE^>5M1In74P5`}uqM64C=^0Ygj9(K@i zGMJHi^`-iBnh#hLN*$k19i3ONHlnE85l^d5uQ70^23eE}+Bc05Uo^JA5qo!Bv%>@C zLWMh#dPH$J#_@(*~e6v@Lc^>pyWf&qAA5RRFax*^_Cw;i*MTWAl>7t8{DVMIzcO!cA;! zsh(Ki>jqL`hpCqP^eq*RQi$1U8|+lG{0-ZtoQ(5@wUZIjB*p)UaJ<^>?^Mz($6Bl) z9~aAD&8^X)l<|jR zyB{rcRt>9Jd2u?)-sSAr(N8+8!}ja7@l#UNf;x#gi}66UfGAGI6a$|4kpxr9GZ-qX zhWZJH$#apz4*u;3O`3jR$bP(+c$W)jop&4fh^DcD3&kYeHi7z>@U%dB-Pb zUAU!H3(2)sse7S7UQ~n-+cT|JQ;tVwqCP;+e9B}El4wo{ zW}kvJD6*0})BJ3ajq{;{+`|MJ7zTJemMlYJwR-N-2KLc-utdBit;u9;G8v?vHu9rU zEote|tvBjdS;yp^YqzsB@{=tlZJ2>LGr(1S-65bh(IdS0Mh}4|(xK~egm`||gF`o8 zSxc>-@hMWn+O1OlMZako)G#$`cY4u&L4N%V`o=l$tNmv${=VO7Nl!dYpOm1k%5G|O zArU4dn{iVQ~yrNNnLu8mRc2OrZ?hw5p8-6 z*K68xh7zvI{A@4Q-_4F=HjSl&UAGC#=E?b_`>g$bv3eNYdB5Dopx8a`@P_2<&AL2} zP_uH~YQDo+PA_!?%9PQuoln+Dt#PNACeSvtsEqTI)mgWLfTR1*AMFp{zI==ZcNMKe zAhwt{6f>5H%UyEtm@_$Is;6v$5VP7)SLfhtQ>id0TiG6n_F5-RZmYg7T8qgwNO4{Q zQVB+{i&Kx>7HTF8-cyHZrwdF%9ecb@Rx-49R_IH($VWLw7Icc4isJ03#^@e1FRSGp zVt&~qjaK)rmYijm01D4wJI=!6#qm9vk$CL%Ev1fHhQR`E!x7J13cLea+zpsE<`> z^!#uqw__p{);J0fXnUR^#=P>W;MB$J1YDIIo0d(gQo|n*n%MF@_v`ZTFf<$n1L0

    N=8dWI3u3r`*&K&0Pn$*=QumXnZ9ycN!`x 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 J=(qsj9{}75sI341 literal 0 HcmV?d00001 diff --git a/discord.py-1.5.2.tar.gz b/discord.py-1.5.2.tar.gz deleted file mode 100644 index 79619c9a8e36cfde75e22f715d15cf4a4bdcbdc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 649387 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

      9I&RraX-kD2 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

      -O5Ah2?Whk$Eqb;`t%vP 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

      Sz2z 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

      2z7U%M!UkoWC&SG?D1= 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

      luAa|*bTAU63X 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

      W5Nq=aQxt0yqxKV@=NwMvYtGa8hLK}uD&=T_GE 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

      )A^}}-s0o=K~Vg}@yok9 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 zǓ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 Znkm>8)2%tce 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 diff --git a/pyproject.toml b/pyproject.toml index e7c56eb749..e618107561 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "./discord.py-1.5.2.tar.gz" +"discord.py" = "./discord.py-1.5.1.tar.gz" uvloop = {version = ">=0.12.0", markers = "sys_platform != 'win32'"} python-dotenv = ">=0.10.3" parsedatetime = "^2.6" diff --git a/requirements.min.txt b/requirements.min.txt index cf1b4bdd26..6d434f974d 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -6,7 +6,7 @@ aiohttp==3.6.2 async-timeout==3.0.1 attrs==19.3.0 chardet==3.0.4 -./discord.py-1.5.2.tar.gz +./discord.py-1.5.1.tar.gz dnspython==1.16.0 emoji==0.5.4 future==0.18.2 From 22689a7348676c79327d4e56da7ce5760923959b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 22:55:04 +0800 Subject: [PATCH 149/705] Test deps --- Pipfile | 3 ++- Pipfile.lock | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Pipfile b/Pipfile index e266f4d102..1d1bf9c936 100644 --- a/Pipfile +++ b/Pipfile @@ -14,7 +14,6 @@ aiohttp = "==3.6.2" async-timeout = "==3.0.1" attrs = "==19.3.0" chardet = "==3.0.4" -"discord.py" = {path = "discord.py-1.5.1.tar.gz"} dnspython = "==1.16.0" emoji = "==0.5.4" future = "==0.18.2" @@ -30,6 +29,8 @@ python-dotenv = "==0.14.0" six = "==1.15.0" websockets = "==8.1" yarl = "==1.4.2" +uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} +"discord.py" = {file = "https://github.com/kyb3r/modmail/raw/development/discord.py-1.5.1.tar.gz"} [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 92c9665c26..30dcc051aa 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "085d6c018d43b9b4c4b5bc5e1ff99543b00c735dfe744abbc5a813048b2e1734" + "sha256": "c910ca82e90b6af36846c730e166d2d7a4b82ca96271a6863c482ac6053c32cc" }, "pipfile-spec": 6, "requires": {}, @@ -57,14 +57,14 @@ "version": "==3.0.4" }, "discord-py": { + "file": "https://github.com/kyb3r/modmail/raw/development/discord.py-1.5.1.tar.gz", "hashes": [ "sha256:f52ab61650d5fe2726fb645e4f23eecdfcf3ded74645f3978a010259e1bc28ca" ], - "path": "./discord.py-1.5.1.tar.gz", "version": "==1.5.1" }, "discord.py": { - "path": "discord.py-1.5.1.tar.gz" + "file": "https://github.com/kyb3r/modmail/raw/development/discord.py-1.5.1.tar.gz" }, "dnspython": { "hashes": [ @@ -237,6 +237,21 @@ "index": "pypi", "version": "==1.15.0" }, + "uvloop": { + "hashes": [ + "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", + "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", + "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", + "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", + "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", + "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", + "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", + "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", + "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362" + ], + "markers": "sys_platform != 'win32'", + "version": "==0.14.0" + }, "websockets": { "hashes": [ "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", From 86f51b277ed3e72aaf8e7819d5ad51bce9b6af5b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 23:01:20 +0800 Subject: [PATCH 150/705] Test deps --- Pipfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 1d1bf9c936..b19980db70 100644 --- a/Pipfile +++ b/Pipfile @@ -30,7 +30,7 @@ six = "==1.15.0" websockets = "==8.1" yarl = "==1.4.2" uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} -"discord.py" = {file = "https://github.com/kyb3r/modmail/raw/development/discord.py-1.5.1.tar.gz"} +"discord.py" = {file = "https://raw.githubusercontent.com/kyb3r/modmail/development/discord.py-1.5.1.tar.gz"} [scripts] bot = "python bot.py" From 84924a663f42a9bfd313547845092af24051b5f1 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 23:08:32 +0800 Subject: [PATCH 151/705] TEST DEPS --- Pipfile | 37 +++--- Pipfile.lock | 327 ++++++++++++++++++++++++++++----------------------- 2 files changed, 194 insertions(+), 170 deletions(-) diff --git a/Pipfile b/Pipfile index b19980db70..4ee505ee4c 100644 --- a/Pipfile +++ b/Pipfile @@ -3,33 +3,30 @@ name = "pypi" url = "https://pypi.org/simple" verify_ssl = true +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + [dev-packages] black = "==19.10b0" -pylint = "==2.6.0" +pylint = "*" bandit = "==1.6.2" -flake8 = "==3.8.4" +flake8 = "*" [packages] -aiohttp = "==3.6.2" -async-timeout = "==3.0.1" -attrs = "==19.3.0" -chardet = "==3.0.4" -dnspython = "==1.16.0" -emoji = "==0.5.4" -future = "==0.18.2" -idna = "==2.9" -isodate = "==0.6.0" -motor = "==2.1.0" -multidict = "==4.7.6" +colorama = ">=0.4.0" +python-dateutil = ">=2.7.0" +emoji = ">=0.2" +uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} +motor = ">=2.0.0" natural = "==0.2.0" +isodate = ">=0.6.0" +dnspython = "~=1.16.0" parsedatetime = "==2.6" -pymongo = "==3.10.1" -python-dateutil = "==2.8.1" -python-dotenv = "==0.14.0" -six = "==1.15.0" -websockets = "==8.1" -yarl = "==1.4.2" -uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} +aiohttp = ">=3.6.0,<3.7.0" +python-dotenv = ">=0.10.3" +pipenv = "*" "discord.py" = {file = "https://raw.githubusercontent.com/kyb3r/modmail/development/discord.py-1.5.1.tar.gz"} [scripts] diff --git a/Pipfile.lock b/Pipfile.lock index 30dcc051aa..214fcdf45a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,16 @@ { "_meta": { "hash": { - "sha256": "c910ca82e90b6af36846c730e166d2d7a4b82ca96271a6863c482ac6053c32cc" + "sha256": "2dd04df5c296e35b94cc2f364e3ca331d06be49a704240dfa8fdd6f99e33b3bb" }, "pipfile-spec": 6, "requires": {}, "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + }, { "name": "pypi", "url": "https://pypi.org/simple", @@ -16,55 +21,84 @@ "default": { "aiohttp": { "hashes": [ - "sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", - "sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", - "sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", - "sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", - "sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", - "sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", - "sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", - "sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", - "sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", - "sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", - "sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", - "sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965" + "sha256:1a4160579ffbc1b69e88cb6ca8bb0fbd4947dfcbf9fb1e2a4fc4c7a4a986c1fe", + "sha256:206c0ccfcea46e1bddc91162449c20c72f308aebdcef4977420ef329c8fcc599", + "sha256:2ad493de47a8f926386fa6d256832de3095ba285f325db917c7deae0b54a9fc8", + "sha256:319b490a5e2beaf06891f6711856ea10591cfe84fe9f3e71a721aa8f20a0872a", + "sha256:470e4c90da36b601676fe50c49a60d34eb8c6593780930b1aa4eea6f508dfa37", + "sha256:60f4caa3b7f7a477f66ccdd158e06901e1d235d572283906276e3803f6b098f5", + "sha256:66d64486172b032db19ea8522328b19cfb78a3e1e5b62ab6a0567f93f073dea0", + "sha256:687461cd974722110d1763b45c5db4d2cdee8d50f57b00c43c7590d1dd77fc5c", + "sha256:698cd7bc3c7d1b82bb728bae835724a486a8c376647aec336aa21a60113c3645", + "sha256:797456399ffeef73172945708810f3277f794965eb6ec9bd3a0c007c0476be98", + "sha256:a885432d3cabc1287bcf88ea94e1826d3aec57fd5da4a586afae4591b061d40d", + "sha256:c506853ba52e516b264b106321c424d03f3ddef2813246432fa9d1cefd361c81", + "sha256:fb83326d8295e8840e4ba774edf346e87eca78ba8a89c55d2690352842c15ba5" ], "index": "pypi", - "version": "==3.6.2" + "version": "==3.6.3" + }, + "appdirs": { + "hashes": [ + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" + ], + "version": "==1.4.4" }, "async-timeout": { "hashes": [ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], - "index": "pypi", + "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", + "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "index": "pypi", - "version": "==19.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.3.0" + }, + "certifi": { + "hashes": [ + "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd", + "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4" + ], + "version": "==2020.11.8" }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" ], - "index": "pypi", "version": "==3.0.4" }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "index": "pypi", + "version": "==0.4.4" + }, "discord-py": { - "file": "https://github.com/kyb3r/modmail/raw/development/discord.py-1.5.1.tar.gz", + "file": "https://raw.githubusercontent.com/kyb3r/modmail/development/discord.py-1.5.1.tar.gz", "hashes": [ "sha256:f52ab61650d5fe2726fb645e4f23eecdfcf3ded74645f3978a010259e1bc28ca" ], "version": "==1.5.1" }, "discord.py": { - "file": "https://github.com/kyb3r/modmail/raw/development/discord.py-1.5.1.tar.gz" + "file": "https://raw.githubusercontent.com/kyb3r/modmail/development/discord.py-1.5.1.tar.gz" + }, + "distlib": { + "hashes": [ + "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb", + "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1" + ], + "version": "==0.3.1" }, "dnspython": { "hashes": [ @@ -76,25 +110,25 @@ }, "emoji": { "hashes": [ - "sha256:60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174" + "sha256:e42da4f8d648f8ef10691bc246f682a1ec6b18373abfd9be10ec0b398823bd11" ], "index": "pypi", - "version": "==0.5.4" + "version": "==0.6.0" }, - "future": { + "filelock": { "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" + "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", + "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" ], - "index": "pypi", - "version": "==0.18.2" + "version": "==3.0.12" }, "idna": { "hashes": [ - "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", - "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa" + "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", + "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "index": "pypi", - "version": "==2.9" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.10" }, "isodate": { "hashes": [ @@ -106,12 +140,11 @@ }, "motor": { "hashes": [ - "sha256:599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", - "sha256:756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", - "sha256:97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a" + "sha256:428d94750123d19fcd0a89b8671ff9b4656f205217bad9f44161748c64c5fc80", + "sha256:f1692b760d834707e3477996ce8d407af8cd61c1a2abedbf81c22ef14675e61a" ], "index": "pypi", - "version": "==2.1.0" + "version": "==2.3.0" }, "multidict": { "hashes": [ @@ -133,7 +166,7 @@ "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" ], - "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==4.7.6" }, "natural": { @@ -151,67 +184,73 @@ "index": "pypi", "version": "==2.6" }, - "pymongo": { + "pipenv": { "hashes": [ - "sha256:01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", - "sha256:0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", - "sha256:1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", - "sha256:18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", - "sha256:19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", - "sha256:20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", - "sha256:26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", - "sha256:26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", - "sha256:2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", - "sha256:2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", - "sha256:316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", - "sha256:31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", - "sha256:334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", - "sha256:358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", - "sha256:3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", - "sha256:444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", - "sha256:47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", - "sha256:4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", - "sha256:4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", - "sha256:53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", - "sha256:568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", - "sha256:56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", - "sha256:5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", - "sha256:61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", - "sha256:619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", - "sha256:6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", - "sha256:63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", - "sha256:6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", - "sha256:7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", - "sha256:7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", - "sha256:80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", - "sha256:95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", - "sha256:993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", - "sha256:9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", - "sha256:a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", - "sha256:a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", - "sha256:a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", - "sha256:a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", - "sha256:a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", - "sha256:ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", - "sha256:ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", - "sha256:b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", - "sha256:b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", - "sha256:bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", - "sha256:bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", - "sha256:c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", - "sha256:c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", - "sha256:c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", - "sha256:c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", - "sha256:da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", - "sha256:dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", - "sha256:e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", - "sha256:e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", - "sha256:e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", - "sha256:f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", - "sha256:f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606" + "sha256:d6ac39d1721517b23aca12cdb4c726dc318ec4d7bdede5c1220bbb81775005c3", + "sha256:dce1fb1a6941f98764c62b00010f52143aed19e2fcd8f100aff4fb3bb1bbbbe3" ], "index": "pypi", - "version": "==3.10.1" + "version": "==2020.11.4" + }, + "pymongo": { + "hashes": [ + "sha256:03dc64a9aa7a5d405aea5c56db95835f6a2fa31b3502c5af1760e0e99210be30", + "sha256:05fcc6f9c60e6efe5219fbb5a30258adb3d3e5cbd317068f3d73c09727f2abb6", + "sha256:076a7f2f7c251635cf6116ac8e45eefac77758ee5a77ab7bd2f63999e957613b", + "sha256:137e6fa718c7eff270dbd2fc4b90d94b1a69c9e9eb3f3de9e850a7fd33c822dc", + "sha256:1f865b1d1c191d785106f54df9abdc7d2f45a946b45fd1ea0a641b4f982a2a77", + "sha256:213c445fe7e654621c6309e874627c35354b46ef3ee807f5a1927dc4b30e1a67", + "sha256:25e617daf47d8dfd4e152c880cd0741cbdb48e51f54b8de9ddbfe74ecd87dd16", + "sha256:3d9bb1ba935a90ec4809a8031efd988bdb13cdba05d9e9a3e9bf151bf759ecde", + "sha256:40696a9a53faa7d85aaa6fd7bef1cae08f7882640bad08c350fb59dee7ad069b", + "sha256:421aa1b92c291c429668bd8d8d8ec2bd00f183483a756928e3afbf2b6f941f00", + "sha256:4437300eb3a5e9cc1a73b07d22c77302f872f339caca97e9bf8cf45eca8fa0d2", + "sha256:455f4deb00158d5ec8b1d3092df6abb681b225774ab8a59b3510293b4c8530e3", + "sha256:475a34a0745c456ceffaec4ce86b7e0983478f1b6140890dff7b161e7bcd895b", + "sha256:4797c0080f41eba90404335e5ded3aa66731d303293a675ff097ce4ea3025bb9", + "sha256:4ae23fbbe9eadf61279a26eba866bbf161a6f7e2ffad14a42cf20e9cb8e94166", + "sha256:4b32744901ee9990aa8cd488ec85634f443526def1e5190a407dc107148249d7", + "sha256:50127b13b38e8e586d5e97d342689405edbd74ad0bd891d97ee126a8c7b6e45f", + "sha256:50531caa7b4be1c4ed5e2d5793a4e51cc9bd62a919a6fd3299ef7c902e206eab", + "sha256:63a5387e496a98170ffe638b435c0832c0f2011a6f4ff7a2880f17669fff8c03", + "sha256:68220b81850de8e966d4667d5c325a96c6ac0d6adb3d18935d6e3d325d441f48", + "sha256:689142dc0c150e9cb7c012d84cac2c346d40beb891323afb6caf18ec4caafae0", + "sha256:6a15e2bee5c4188369a87ed6f02de804651152634a46cca91966a11c8abd2550", + "sha256:7122ffe597b531fb065d3314e704a6fe152b81820ca5f38543e70ffcc95ecfd4", + "sha256:7307024b18266b302f4265da84bb1effb5d18999ef35b30d17592959568d5c0a", + "sha256:7a4a6f5b818988a3917ec4baa91d1143242bdfece8d38305020463955961266a", + "sha256:83c5a3ecd96a9f3f11cfe6dfcbcec7323265340eb24cc996acaecea129865a3a", + "sha256:890b0f1e18dbd898aeb0ab9eae1ab159c6bcbe87f0abb065b0044581d8614062", + "sha256:8deda1f7b4c03242f2a8037706d9584e703f3d8c74d6d9cac5833db36fe16c42", + "sha256:8ea13d0348b4c96b437d944d7068d59ed4a6c98aaa6c40d8537a2981313f1c66", + "sha256:91e96bf85b7c07c827d339a386e8a3cf2e90ef098c42595227f729922d0851df", + "sha256:96782ebb3c9e91e174c333208b272ea144ed2a684413afb1038e3b3342230d72", + "sha256:9755c726aa6788f076114dfdc03b92b03ff8860316cca00902cce88bcdb5fedd", + "sha256:9dbab90c348c512e03f146e93a5e2610acec76df391043ecd46b6b775d5397e6", + "sha256:9ee0eef254e340cc11c379f797af3977992a7f2c176f1a658740c94bf677e13c", + "sha256:9fc17fdac8f1973850d42e51e8ba6149d93b1993ed6768a24f352f926dd3d587", + "sha256:a2787319dc69854acdfd6452e6a8ba8f929aeb20843c7f090e04159fc18e6245", + "sha256:b7c522292407fa04d8195032493aac937e253ad9ae524aab43b9d9d242571f03", + "sha256:bd312794f51e37dcf77f013d40650fe4fbb211dd55ef2863839c37480bd44369", + "sha256:c0d660a186e36c526366edf8a64391874fe53cf8b7039224137aee0163c046df", + "sha256:c4869141e20769b65d2d72686e7a7eb141ce9f3168106bed3e7dcced54eb2422", + "sha256:cc4057f692ac35bbe82a0a908d42ce3a281c9e913290fac37d7fa3bd01307dfb", + "sha256:cccf1e7806f12300e3a3b48f219e111000c2538483e85c869c35c1ae591e6ce9", + "sha256:ce208f80f398522e49d9db789065c8ad2cd37b21bd6b23d30053474b7416af11", + "sha256:d0565481dc196986c484a7fb13214fc6402201f7fb55c65fd215b3324962fe6c", + "sha256:d1b3366329c45a474b3bbc9b9c95d4c686e03f35da7fd12bc144626d1f2a7c04", + "sha256:d226e0d4b9192d95079a9a29c04dd81816b1ce8903b8c174a39224fe978547cb", + "sha256:d38b35f6eef4237b1d0d8e845fc1546dad85c55eba447e28c211da8c7ef9697c", + "sha256:d64c98277ea80e4484f1332ab107e8dfd173a7dcf1bdbf10a9cccc97aaab145f", + "sha256:d9de8427a5601799784eb0e7fa1b031aa64086ce04de29df775a8ca37eedac41", + "sha256:e6a15cf8f887d9f578dd49c6fb3a99d53e1d922fdd67a245a67488d77bf56eb2", + "sha256:e8c446882cbb3774cd78c738c9f58220606b702b7c1655f1423357dc51674054", + "sha256:e8d188ee39bd0ffe76603da887706e4e7b471f613625899ddf1e27867dc6a0d3", + "sha256:ef76535776c0708a85258f6dc51d36a2df12633c735f6d197ed7dfcaa7449b99", + "sha256:f6efca006a81e1197b925a7d7b16b8f61980697bb6746587aad8842865233218" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==3.11.0" }, "python-dateutil": { "hashes": [ @@ -223,18 +262,18 @@ }, "python-dotenv": { "hashes": [ - "sha256:8c10c99a1b25d9a68058a1ad6f90381a62ba68230ca93966882a4dbc3bc9c33d", - "sha256:c10863aee750ad720f4f43436565e4c1698798d763b63234fb5021b6c616e423" + "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e", + "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0" ], "index": "pypi", - "version": "==0.14.0" + "version": "==0.15.0" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "uvloop": { @@ -252,56 +291,44 @@ "markers": "sys_platform != 'win32'", "version": "==0.14.0" }, - "websockets": { - "hashes": [ - "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", - "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", - "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", - "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", - "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", - "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", - "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", - "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", - "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", - "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", - "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", - "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", - "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", - "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", - "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", - "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", - "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", - "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", - "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", - "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", - "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", - "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" + "virtualenv": { + "hashes": [ + "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2", + "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380" ], - "index": "pypi", - "version": "==8.1" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.1.0" + }, + "virtualenv-clone": { + "hashes": [ + "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", + "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.5.4" }, "yarl": { "hashes": [ - "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", - "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", - "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", - "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", - "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", - "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", - "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", - "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", - "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", - "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", - "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", - "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", - "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", - "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", - "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", - "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", - "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2" + "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", + "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593", + "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2", + "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8", + "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d", + "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692", + "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02", + "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a", + "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8", + "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6", + "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511", + "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e", + "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a", + "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb", + "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f", + "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", + "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" ], - "index": "pypi", - "version": "==1.4.2" + "markers": "python_version >= '3.5'", + "version": "==1.5.1" } }, "develop": { @@ -322,11 +349,11 @@ }, "attrs": { "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", + "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "index": "pypi", - "version": "==19.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.3.0" }, "bandit": { "hashes": [ @@ -357,7 +384,7 @@ "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], - "markers": "platform_system == 'Windows' and sys_platform == 'win32'", + "index": "pypi", "version": "==0.4.4" }, "flake8": { @@ -534,7 +561,7 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "smmap": { From e17c2c9bc15539d49c185280a70c156348afa749 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 23:11:29 +0800 Subject: [PATCH 152/705] TEST DEPS --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..de59d776a5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pipenv==2020.11.4 \ No newline at end of file From 2dfe72a3463f579ebed3bca8e477e4a5592242ed Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 23:18:18 +0800 Subject: [PATCH 153/705] TEST DEPS --- Pipfile | 2 +- Pipfile.lock | 35 +++-------------------------------- requirements.txt | 1 - 3 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 requirements.txt diff --git a/Pipfile b/Pipfile index 4ee505ee4c..755f74716b 100644 --- a/Pipfile +++ b/Pipfile @@ -27,7 +27,7 @@ parsedatetime = "==2.6" aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -"discord.py" = {file = "https://raw.githubusercontent.com/kyb3r/modmail/development/discord.py-1.5.1.tar.gz"} +"discord.py" = {file = "./discord.py-1.5.1.tar.gz"} [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 214fcdf45a..9942ffab90 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2dd04df5c296e35b94cc2f364e3ca331d06be49a704240dfa8fdd6f99e33b3bb" + "sha256": "878a40a1f33596a78d6ddccfec3c116687a6dd2a98ba77d7f63d2a86d07d2718" }, "pipfile-spec": 6, "requires": {}, @@ -50,7 +50,6 @@ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], - "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { @@ -58,7 +57,6 @@ "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "certifi": { @@ -83,15 +81,8 @@ "index": "pypi", "version": "==0.4.4" }, - "discord-py": { - "file": "https://raw.githubusercontent.com/kyb3r/modmail/development/discord.py-1.5.1.tar.gz", - "hashes": [ - "sha256:f52ab61650d5fe2726fb645e4f23eecdfcf3ded74645f3978a010259e1bc28ca" - ], - "version": "==1.5.1" - }, "discord.py": { - "file": "https://raw.githubusercontent.com/kyb3r/modmail/development/discord.py-1.5.1.tar.gz" + "file": "./discord.py-1.5.1.tar.gz" }, "distlib": { "hashes": [ @@ -127,7 +118,6 @@ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, "isodate": { @@ -166,7 +156,6 @@ "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" ], - "markers": "python_version >= '3.5'", "version": "==4.7.6" }, "natural": { @@ -249,7 +238,6 @@ "sha256:ef76535776c0708a85258f6dc51d36a2df12633c735f6d197ed7dfcaa7449b99", "sha256:f6efca006a81e1197b925a7d7b16b8f61980697bb6746587aad8842865233218" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.11.0" }, "python-dateutil": { @@ -273,7 +261,6 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "uvloop": { @@ -288,6 +275,7 @@ "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362" ], + "index": "pypi", "markers": "sys_platform != 'win32'", "version": "==0.14.0" }, @@ -296,7 +284,6 @@ "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2", "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.1.0" }, "virtualenv-clone": { @@ -304,7 +291,6 @@ "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.5.4" }, "yarl": { @@ -327,7 +313,6 @@ "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" ], - "markers": "python_version >= '3.5'", "version": "==1.5.1" } }, @@ -344,7 +329,6 @@ "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" ], - "markers": "python_version >= '3.5'", "version": "==2.4.2" }, "attrs": { @@ -352,7 +336,6 @@ "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "bandit": { @@ -376,7 +359,6 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "colorama": { @@ -400,7 +382,6 @@ "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], - "markers": "python_version >= '3.4'", "version": "==4.0.5" }, "gitpython": { @@ -408,7 +389,6 @@ "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b", "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8" ], - "markers": "python_version >= '3.4'", "version": "==3.1.11" }, "isort": { @@ -416,7 +396,6 @@ "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7", "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58" ], - "markers": "python_version >= '3.6' and python_version < '4.0'", "version": "==5.6.4" }, "lazy-object-proxy": { @@ -443,7 +422,6 @@ "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.3" }, "mccabe": { @@ -465,7 +443,6 @@ "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9", "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00" ], - "markers": "python_version >= '2.6'", "version": "==5.5.1" }, "pycodestyle": { @@ -473,7 +450,6 @@ "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.6.0" }, "pyflakes": { @@ -481,7 +457,6 @@ "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.2.0" }, "pylint": { @@ -561,7 +536,6 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "smmap": { @@ -569,7 +543,6 @@ "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.0.4" }, "stevedore": { @@ -577,7 +550,6 @@ "sha256:5e1ab03eaae06ef6ce23859402de785f08d97780ed774948ef16c4652c41bc62", "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0" ], - "markers": "python_version >= '3.6'", "version": "==3.2.2" }, "toml": { @@ -585,7 +557,6 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.10.2" }, "typed-ast": { diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index de59d776a5..0000000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pipenv==2020.11.4 \ No newline at end of file From 1a3b39d5e17a1007c859de137f1da96011dfda80 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Nov 2020 23:24:51 +0800 Subject: [PATCH 154/705] Final fix for deps? --- Pipfile | 2 +- Pipfile.lock | 4 ++-- discord.py-1.5.1.tar.gz | Bin 649410 -> 0 bytes discord.py-1.5.2.tar.gz | Bin 0 -> 649426 bytes 4 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 discord.py-1.5.1.tar.gz create mode 100644 discord.py-1.5.2.tar.gz diff --git a/Pipfile b/Pipfile index 755f74716b..b878d053e9 100644 --- a/Pipfile +++ b/Pipfile @@ -27,7 +27,7 @@ parsedatetime = "==2.6" aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -"discord.py" = {file = "./discord.py-1.5.1.tar.gz"} +"discord.py" = {file = "./discord.py-1.5.2.tar.gz"} [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 9942ffab90..0eacd81d2c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "878a40a1f33596a78d6ddccfec3c116687a6dd2a98ba77d7f63d2a86d07d2718" + "sha256": "1f660c7237deeaa50a7098002c0f3c05cce254d6c0ba8bc02993c5400e335a59" }, "pipfile-spec": 6, "requires": {}, @@ -82,7 +82,7 @@ "version": "==0.4.4" }, "discord.py": { - "file": "./discord.py-1.5.1.tar.gz" + "file": "./discord.py-1.5.2.tar.gz" }, "distlib": { "hashes": [ diff --git a/discord.py-1.5.1.tar.gz b/discord.py-1.5.1.tar.gz deleted file mode 100644 index 31eab92a92e5c718020fdba80f5a9ac7cf7016bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 649410 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 z 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 z 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

      bI~J_^wPCSsSR<~v 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

      N=8dWI3u3r`*&K&0Pn$*=QumXnZ9ycN!`x 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 J=(qsj9{}75sI341 diff --git a/discord.py-1.5.2.tar.gz b/discord.py-1.5.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..df0732cccac17a0d0b0f878dde24c204773b8d80 GIT binary patch literal 649426 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/Q@d9Q`4-0o)w7tj34MYxDAsHT3*DWV&mBT3N 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

      1!ba;}Hg5IgWP`v9i@Qr%<+n_2AY)yvA5<(J*e zR#M;iw61G-lg>0~lBWaocy`oZ3nE?Vh^Ga>(}X7NrA~OZ^AOGbQk?Q)YOZ(=O@FSJ zEyWd%b#d^iL!A#k>ya*Y;PhvDlA;3}r%KYdw0KUN`ir$=N6(q)w=r#eY!1S1ao*H0 z?K3w?E_#%e#I>WD+@!L5(hrTI5EfK&LK}$XBSN?lh8<^7;J3D4lmK*QV3JnGub_=G{;6N(&LNNPmUz_ozq~Pdok+h8;!i;!kQDtIgi2$>T}L;UqaiV zPkMHy5K@FuE|(@m()N@7ilM;X7Me859wSrMNS+ysXvP6l-{-Ejl4_K?fPcjujd}_5{C#I>+E7m8XJe0ust_% zT4s~2!^6E2zz?GHuoro4&etXNRUI$LJhJg`CrTei!?0cGm8gI{Yx_Mv&AG7%O;vu_ z+PF=GD#AB#(NuBSQXOZz%0kTOV8~B&wIYrRF_bFIFkOW$B0XxAn)O;Vft~iFeoRYT z7hBp;t9C%oN?H{=-aGe#)bL`sY0Q1XR4WPHT!f5B<7hoiz19ix04@$$&-jxKxHPO{Vwkg?Zr|yat!{=r zN$}yYf6N>ikpkyD4pP|p<#)YMwuv=;PtbX1N(|ajj#wTf32?ETVBfT|GQ9r=KnSG|C;%K&HTS+ z{$F4E{10^p6C0{D5G+l~61((EzRU1V`GRG1X7|jGi6gFS4;5Ix`9{{-5clBlJC5kr zyvqWPaU}Iz3N$N0MPrlV*<^mio`2@|sz7q$3o~X?aOX58SEX&_pC4!t9w7ix)zX-B z5WxK1vg%ogU^xgG*lKP5!~-$iiU=SylJHto9u+Pb6;LpZGs5BMBvSZD_^J;zq@=tn zszH0Lm{U>Iu=JHe{4fdq%XL;QKlYSjtNIw(7HfU9G|qeMb89}5#KDSh*;`nGr$X6; z2^##K-?yZ;^ziJ&EZRC6L(!)ddSgUCxBc+KS`=RxC37GZJ>&e`122fH1inr%4b5S6 zE)&HvY{~}v%y_S2w7EnsMjL%kB#bqu5=T8hpRYVcRxP#QC>E|#3!^ip<^bqxCuH=y1Kxa;^h}ru2+ZAW_CH5ELxS;Ja|zMdK7gZ1Rbf08D(V4Thf}8 zn7Y}_$KB&jD6Nfe&FU^Z>L=COWMRdWhZ`}u;#6Er?NY70m8`uLWAbGLM3_xq0%@Ep zwo^30X*1!xmAr${xTWH3Z2%4G`tlZF;68Q^(4daIjgeKnQan;C4SkiX?D{eC5Y{g( zu9O^O3ThExNeu%k@9KtA_E&_e9dHID+Vtgsrhue9w*s6T5?zYtOw%WIY8r6pC>}LS z6=uRJ^}+#ez>()v8K|ntr(rqV%#o=>#}2D1OPH{-YUcR(WE}xbl*kQ`ADRf&Ic<&t zSJg|52bWwVuyM;FR&yoBLp%@K8v9{`XqFfcF~dIXFxH^Ls%DSt_Osg@^q_}^bF`1! zH-IQ1@98iQ1AR+MYZ78mrj}w&;b1$WRW4zx8)Hs*QX=49Y@)&2fPo1oqVql`3u*g3 z@4^N{$_0HtNiai!As+y=YQ-u!m@{fEBAdA!5dvW0ow9r=eh0H0tQlu!HJ?4h>!g(L zBwt9g36}F+#CxS_toWQlZV~)@)41N8?-xNH#qrwh#n|ryJ{8P63>A*dZ$hDp#puH4 zB;a+s=QGEn4Z5z4O-&N_F!axxbW9rTmi)srCkThR{!niAtVi7CDLN(kVRZ0HoyxIX z5`Sm`3A%o?Qx+8Lbiql|XC_X8zVV@hhR|`lp?bJv>*E=&3 zs%2v6)#!NpNHV@nNQCbNq6%)G*R z0{1zSFBez-0RI?v{OKC2Ik ziWg`G7!~W8X?opBas|^AXIX+-ebI2%!wa*V(1*~lyO^w&wtCxTAkRIt{GfJ6TGHA+ zq6*&dYxGo3AK!qf&0Xw!$)uTgxvV~I`IVr%^m3!v#An8R#p2Fi${vfefWg4@tWQ>{ zV_K}vu%~$sJ%laZkCIfho7A~J{C9MOJMrkqb+)2&pAvM1P7=YcVlFXAGbkeVI^llm zeR7=x-!DT%Brq8e&TJ+6!H%z5GOSL}>j7#-!?bwwp@s3j#R0GhZ&?u|QyziK%DJX3 z5SKk&MUg^~F1CSTx{2Ys$1nMsKxjVGhMV61^p5*$l@J6jtl3Qm=494I5<#xhWQAsJ zqP&y(Ax<-nNeKhYTirSdLE6FH%aN?SlLc+dCy!(#)-(L^qe4PJMiRYXG+?1CuhG=} z)U*i^2C&=&XnyFtTkN;4i8-Y`QUv0%eziG>ht^Z*O@|9ORDd_wd4v;|ut(ZZTnV1- zfD$Q0P6AyJS!v2{?8VV@lw+&4y7S_+L5p=(qm%fw?wlzNBwwy6)Q^|7YRw`MO)*{+ zm>f2$Pf&#=Y4&%tOj4!<5!jaX_^GZGvdL1&X(aZm6ot-g7^am*5iC7_R;!oQ6Ka=+ zwy6z+QP!`V#YlTmgnfDS)uoZX^umz?5;?wFu@z4jfw5UhdB$+A2-IXV?h)8#JHM^{@YOUe)r$c zGhbrZfK{KZSY=fWw?mpqb zs&f=uQsoSWUSIsCj(E*%l&b^UW)Vl;1@XdB3ZsSt9IMi-HJoFL6K^;zeFwdXE#jr@ zvKHT^D{H9>+q*-Lya?I3jnm1(E0$+KXwe}?p)S*;bY*H1IX%iz^a)0ZcKnpn&mu<> zM(5mU2wb5s#p>WF@}=*4=$eRJ5osT2o-on3pQL_)p>7F{i;*arpB1$kRE6YE3u=!^ zZH?6^r*)n?ZL(xIQGRSyG?&0y>jty;qP4PM&ujgO==c-Oc(U8C^` zfpd4l&QWs)$;@rgEXRA@$#%mif;|eF zLE*61(@O(i)d{*oV8t+0f|Z|)tU_-qt|Jr9*2r<_xI3H?#CIOUM+ZgTUtozPFuqxe+0zwL%C zUl`li->gmpq6h$o(`@q9c|sDvm!bb$^!tqN8emA2BMG}EY!aeBM!G$`bz1A6%N|=G zxCZ@UUkWPNGHhh@ckvT_7J3(KJ@h@0?x_K1I3VgRLBM)2l$AeTUUF{H&DTu7fNsPj z;*%pN&`BiYDayC#R!Ei~p9u#h?)2k8rWeKZoqxQ%EPx3&(?rc*KG#^@dk`y)@~|VI za?A=ky&~^Z9_Ip=karl;sB^a*_VEbIddD`@)Q3Z_SDJb3fR!mnN0^K4=m_TqNP5o~ z6F~HlI!G>iNf4vzSfrag$Mkca?m{QBYXzaocG`zNANvAzR0^=szGm3o+A{f^$^NfB z^m>Wq#s})!8r3KmvM{m^-Yw-H1ERp=<-&794l-~Eh_K)*&aGR{@^Zc?OeLwXB5@Jr z8W9w?AHiu9g+Z&D^8$O4pjIk&qVrHt8)e-lTk!D(<^gM0i&niRzU&OcmH^=5KQU>?&@W6(GpnxX{V)vBOry$+h00r&m`m)wn@b`t# z|E=CG>iL{?C73 zzP-G1Z_c?h+y6fw^nYgmnc074e_uTM-wTeT!7y1^a-ZM5?Y4Wp>$m?b-@do9dON@W z@4g@n>Io z^w-}YUBDoYy0O=HT3(3W+NgUPVhTOy!R`UtMtt|ijrng17<-$5ga7V7;2;0i8*~5h zug=Z=tGVC1`47JO)!&)>N6@R^d}D47=+S@i8}R*|q_gBBDkMfPVKl_JsbAQwQy}2L%oAC2b z-;Zp;OL{9oaNukphEcD~%vyY7I?;TUnObH5HB|6{(~(!1_+F8AC2 z7zYXEej7gjcT2hBB%yiu6@2hU3Emw2*!3A6%{k2d+%MyLzEOl1a5-9&BT;U?Q0~X> z#{MCG|0Dco@CMJzujk9X`(rolQU6Y;Bcj}I=F36RKK*aEKK+ZIJp8|ZVQ%ZQ-}>oa!IK~T&s(2<6@Gm6ukrO) z{|qN2{gti1q}{drw$Lr7j;s^ilSHAwE{|uh`Tc3UHttA5fJHLTr`E2mZ%Rhyd8rafre*Jgf zo!ff*zyJCVe;Ghnn*HCf?45u4FSy~aeEo;N59L1l#UK6n>p%Q|=H}$Xd3gAvpML#^ ze@pGWar!T?9hkNsr#Bvd`jdZ#c=PDf|MjPT^Mg131NV)&uN1pmeDdhCw|)p|K%pF&Guh@?VG%4e@PT>>)-o@V%z`C|Iga@fJaqbiO-vv zK)~P)Hc(V3X*;?zLNRHvGL^P@@E*L;7r+`d*dTO6S?Rhh-DZUCLI5WN+&*5wmaMp% zYIk+lT5a52L9}KwGlBd=V3HsN@J~S0Hv}Yrk_m*&@0@erOaivM-+tfEPx9W}ci;VU z?)iVty$?$g?o=wpCM&eS8(j$x{9H!A0TKK(!!cijOY;bBnde`pMl1f1DYyY%2uGlP#ScT5rQl9W?xA74Ng#y^ zQn~^Q2Vn%6u_vw!o54oFQi%Y<`%bwWmUY49&>nHG;_>2Xl7BO zF5z-eFGKy~^F@tYGymN$KY%2TYX&dEvK5!dWgh39DyxeXmq!B8ZfC$Oxe{bA4}J}*SSX`6@g`%(vRJKri3s*^1L( zx!?7}5R7L$+wtdYmYes4&g0A*lUlUx7udoWb~JH4^X`Qo@UOHP{zaFuv#l4{Ly=`{ zTFZHMZ|};bP!b6rJI@|!5_KMq!@sV|nSkJ$nM1QGj0}Sx%XK@k=^O`jBHE6^Ox#YK zmFABIk1;Qf*9+qXL|O8~MnWnLu&My+m3gMZ-x5Hsg3C5uX$C#YrAN8&D6uTfKja4m z!q`-l zw40TCn;Ql_cBKDvo%dCilGq6SqjzNGF*SUq!e1DXiJbwrWz+6tPeynQ#y!>Yod8}9 zH^zPL(BFEq!yOg>9gbjoZ~5Gg;2(RQf75=;x*a4-PnQ;Yi^k!o7^@jobc+BR30*r7 zG6iX-sim2w{II;ZQSe9T$P4&h`8UwPXjr6`56hv1^aj2W2t}nHromr$rvGXHpJoUA ztuk*5CKP{s&3LW61s>)63c4%J*#ysJHYe6tnJ>!W6?jmlZ-O_Y^aSWdE$rxNRCpZj zQ5|kvLEtiB!owec1?bbhiNIyYH1?>^fJ zWEMEPz4OHKmSdl%QqXG*hJdZ~L(9>Dudvr)SS{vyyJa3#c#GnTN4u|+T4eFkwJ)?^ zH9jBC_>1^esu^;DZrq!#@k3hqy}8EA9*fxVUc@fcfepU~SWy%(W)&$$AP+Guz~9k~ z&7Ky*f-29eaAghd1;#c{H)=H8l0)5+F-kEf#-S{Nv*umx$mcX{RY@V4qsI6yex+rC6&J~hdv%u{rlKvRBoupS_df~;jl|!aQ$J2 z1Ex1Ke1?TT9wEwp4`oxJOy-S<&p1uRH-YWk?1_`g@|LF;u7uQTVd_t*wGKyTcgT{y zIz@18xCChmdtvj>3tBx50#$R!=56NeAIk;byYCmhvmG~tCTn;5roWq zcq8$+Yq-2KX3tar7b0TeHCXRm1fEHEl6kWgI5adP9XO%Js=f^x zkIMT&ChmuosQMe|!nmg>+{(hwfC(X+PoY&By?lLo(yV&(2%K1N)S9eFz3oX;FLL?2 z6f;L+o1exxo5~Mevbo?2^htxTI*-CicNKO}kJ0Yy<-UtB7!@_qUHF1M3FJi&gOrKT zECh1nlJ63-U|huGc9{2ps3_U$#`S`-Y?1?^W;Y0jHuybv03`+Ug19T~y1>d%Sd>E9 z*tr9mKNj4FkW}CKb2uiiPa(Oos(%Ln$gJV8{Dxy4;6+^r&@nQkOJi6=+wv%~qcoFQ zmW9kH!s?=#l5Zd<>H-eI>W=v0>l>;3GLss2;ho}3vW8>ZiBDmhNn~yky;DSu!eq6%5J)xO4-2NZr+=Uo*2m*IzZV;4=?fF04c}+H~cy1 z&*0CfgYdu*50G%HuHef6I=~TDy_gnrwxWXB5&i-Euv>?9onhZ1#O?JQGw?N7&wH<0 zPY13idoW7ciU!(B57egt8h2;wpbi%4b^|zE93~9JtMEr*nBVOKjr3W-<_y0l;)|XE zH2s`NP%)>jon@AN!@-YQYhfme-{MhbPKOoeEpI+>|NZwz`zQCE;)i_){Abyg0Vg5z zT0&-<3|rteo-FLhU@;b6==gIOh4>wQ0amr}OyWD2(S9%=kg)nmKtSHyv&)#R$>tkG zUa9NRQe(nAs~!ng*+0mt2OXlfH)#E+OTZUj6tKb;mTBA+QWLPL4J4;5&=h{PUxTXh zFkDs4b(2n{Qh@8Aj3BP#Lxnf`I{DFb9VsR+k6~MYM_+6zHq_K6yQ%2#V%gWCND^=*4Xd($P8HSpLXZ|d55@I5TTF-q3$azygB10NQLNjtJ z^Fb%ft-J|2;q|!ayU_gPr?8t(p_?9O;ThvTg&dvX4yIa(!%37?w*SJWyDcG_JFMVS za^IkAPL${c;Mw70OzV=(IUvX{u;Q-u{pd&vbvhEaUm|>*BLPl26~5P(^a+WBi=ViG zG-8MOAV4cA`z+rnRk9T6RHAQSxV@+N64HT0$3WWN-i2_+AtY9zT?p;}RN^1_n$4Um zF!7YR`Wp@_y9Z^;15RHvx7yG0BSRgx^R`4z|M2$H{s`+g?EsWLiSvU*OQ$Z|`ntmV z67Rw~5M~_BNShyn)J~Yt(pCD_`qPL<%=en-Il8_j7Kr)8A`0z3P#!m4^DK~X1!w1j za<3VIYz4Hj84|Iq*F2^83|90J=uEjLfs=nk!;YVc|=9IutXyH0(=~d5S{m<9&5~YlW_)i z$0GiW}y!INc-;HZ{l`bdycUNYkvNAmjJ9Mjs zXTp(+H;^-6)5H-J(5!Jho!u}{`K$Y2fC?8ytZI}C?W4Cm8rEc0|LR6ct1Jb}+qh?j z4pIvrz=EK_`r$;kLo?lEr~-W~Z${; zrs@7j@BqJO2H?z0<~;-uvCb4qjzmssh@Nqs#-{?Xw)R4)v{I}(Jc#}rw&`!-npibB zn{skWGBq!4L7MahkWPc&Oya@K24g6@e9xy$~>zTe%#mo zCQWG{=n2xk_A842Bbm)V4LGcwl6_6O>t(_K*>^gFB``F?Eg>_0;nkU9!Cd_x88$dz zY;5y>8vVjS#C&A=_$q=TU*-v&Uji5w$QhV<@yRM!%hjG4mI4e;neq!SXcsuoRf_NP z(3J_5d5S?p?pDpEQ!O=oOkqklSlJ7E?S2*Bj^2$&bdWk;l^@40>>iVy*c0K(3>=Wv zeF?>@9K>|{3p=crFS#6vza2pAA%1|cZc2C3nWS#0edr5X z$9C;miP9ddYBHz7~f8XL(GDK+z2H&zz9pwg7JtqesQl zxR2e5rqUQscz!iLf2DUAKBuuagU)IEMSPw(!JWoqnfy5!L{2<}YMbdst=jPhMsN^y zlWz!a90L_#etY8E=-ut8yjL;rP8qXjz$E6IC0pFfwl0q#KSC!Pavbuj$UG`X`||)x zZi~VnP^yc;3_8ST&ye}P#Loam#k^DIEr~9amrzu8d6<52wZGyK@`s^oun5E^%pWwZ zRDkaTxmnDc$d~b>d}O>`L>IzI(bF z8XS-Dn+qyy$SX^?$lr&bN*QP?9i1msUtBsRcXn mVFvCv_D6N36TPC87JPG-A6Q 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

      gdXl9 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ⅇ1p+pdQ)u;Sc{UHl6K@KMEPq0RP}} zcW9eGC%`PR0pcnn@u!~6DYRbuflN_FQfwZ)8C>JMyWju~!_1>*x|qHtU$FUZH-7>h57?Mb+3(=d+f z^xM;q&T7FcCqDlcTxs8=q#ai6iOzWSEVwC+;TcaqfmuT!V)tlGGbZeNhngeaaI*k(59_e0?Pb^Gs3(3;5rf7WWDDS6GrBjYKHCj1N!E2LVqkaxRR)(E( zOG1_hKE`h(T@nJgv3dxS(J$N9AJ}Hjo_nhu%bRebId+;1yf^#rI$VGJ4j!&8+3$6@ z#CYI*b&7*^!wj%<;X&(2Ny3TTw`}_|`3HMB;Kv$Yf%FfC6eht)Z%=Ru09^iBMeSq@}&pqr_ zqX_j-yi|?7o~c|ks*iq1svKi*4Sb!mh6hyJE6{$U2v%1&(Xleuc4nCeTAU>=L%l|C zZ^$v+N71d4y`_v1%VN7!Wdo%f# z7Pb%XOZunI1^-i5%K!8o^h)%IIzK~yN_gLd`RlI**XiNScYa7LVC@p}9HxAUqL%H1 z`XYYrE^JRMmp!8sVnR?C@Xr(i4;=69v}ixR_`NKqh_^*kN&imKUu~V>SftM*^qKfT zlAodXHT;2Gd@&(=7thN113CCCp5{+X?;7%PZgsb^(ri(oYck~@OW(TDM_0T8Mv7cU z|A_u2|2u!tD{hhgqCb)TqEExXyA02xq=-&)3zaaiPwJ!53+66RC@oaMLDa>*?M`}s zk{!KNmK8DC0!9-#`J%gd;9RHs%v39CvyS=4(>sx8a0*J&h49#v^Ue{wwWfj!DJw92}DUG z)QobyluNJlDXkgBnhD^^D7%LfxUIH$FMizCdtcjn8~VzZie@GW`6A#XK{$tm5HZyZ zgM3;tiIKc(t$k)PQ2V^U_j&*M=|g7EoPGAkT5GSp*52zw+{)#d3o80sV325!m9Oy5 z=ohE1=0CZB^|HbmXDJ7Tvea3MMQxd+$~1ANeF>E|3_5Mw$0IPzQnkng$+PAWfg}7u zx~I}v%9gfUY%`(r#VAFiR{l*)nGNrzvqs!aP-o<0&_=NeZy9G-CzN~zq%oPs(95>` zYnqwgR^3beI5e}LOn0AZYxIQKuUh!KV<+y2x;hKxZ)vvqOqnYY^_D6zNp%pERL3_x zk)NJ(8PtjU&}zQcnaP^}auPIby%XrcJ`{FE_)jL4wa!vWIVaONYnLa7qJ2-ISD8i` z%FR}7n%TH&^8jj}-ba=t>?!nLpq5;bL|ZUVd&j~_9K8Q`D#q%D>1%c0h~oi@w)i&5 zJ%GRBd|Jl_?l4@PK!LnhIVJT*fvtF3*j|9rm@XZ6bxUFQad+ox0D_%0A7{-Gn1+2d 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�JhjeX~FdYcGA@_0J}{@M@@mFG(j4>V>;w} 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≪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 z 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�ggG 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 ie1wA4?^Yn9m_%khyPj;a-~ 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�|h-|zj*;OI+c?*30G=$_$! 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

      1!ba;}Hg5IgWP`v9i@Qr%<+n_2AY)yvA5<(J*e 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 mVFvCv_D6N36TPC87JPG-A6Q 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

      gdXl9 ziuA;Zst`FV#E5~A;`c}HOKlQQ{1}Tg(L+_=+%eNGNDd}nW{)8*LE~&(o z8O41O;Bcp)pN+du%QP+L&XG5K6qY|F9*9tOt6TUstjZoK%emwT;yl$VLnmm)F~C*q zQlUylnF~xNJ{;--j|GDmo4Pj9hMNCCw4$v;yO5PKC_Ij=ig2Uwc#v``mA&hz2rGy? zcKHIc3QuBvL83KZ6uIXX6jKC3mce68%S|VBFDPXlaEMMciVvW715`B_v@9Ei7Z9?S z?7Xs`2zPr?pCB>jEa24!Z`_BQckMt70-c=+oQkXWaSlBGKnx0<5@jHQPvH>XnirFJS)aITbo6lWx z1=YeeEDIa-Ske`CR4Glb;hs1T<4N2Jx=LdH*s`~D0M!Sn8wtd;22P3qmgq(rbk&Jn z*hdtv;8nUZw=&j;K$$yoZ*HOQuq!Y6tiJhCs!UhK^KeW)2&v_H*a{gDjr-s2 zw`y>|kT_KEjK$b9#|UrK$skBuFzSD|>M#a)6su1V4H4o8&vc^fiA0^~0aUM899KAS z+q5%M9ScpfKwoqFp%Qd|su8fDg5j8qAR1yOmdqjnIU6(EpFzV}*)LV4Xxah*PqQix z_GVN;L{@nYa0ZwszpXctDqA>u;h!Yth8e{NmFWk!aY?E^-cZCbv*z*F^&zShZSCZ? z;(E;Q&W#wxB%_sYX`jkb|Nh{MIx$7-V8mIeRUDkGy9u1|3>>?dNWUk-E)n!j)aouh ziQjZ1ZRM5LrXpdwxx+p~=P1E(T0l|ll85N{hmK^9*)K32>{pO6uNfw>y)*nrvDt)N z`$#qN@LS_n=_EzQt~c+;qa*smf(4>`oanQ%86MuIOPFp6B^AA>B++qPzjgGpn=7pU zK|V>#aZJv%Tgc8KOLcF5JDs~+07AT75sp35v>%^{qu%aI-K%S2dRr4RV$}aX+o&pK zZ3t%OfAi!67rt^Ac!@H8awgmTU~)qR!77%b!7(IGCW4nraFUhukPD1pgs`SbUunMy zXqXNLOqrp$SS24`7|mT({%$-mvJe{-l0-#V!Z1(4khp0S?F-?id-l4UW+q5wc@+B8 z#KquYHWti1$4nofll~;8lojNL!uv}%>O?5a=w1NZziA5xSddFJR_HwS?<%jM?FGs}7Hm4$if5*90-laO6wj=B>^2`<1s^JflU=@r zJQld9cn7K*xvOW_DfgF;c-{tZ%5~sa>#mprl*GtI6Bt$9P;UNNNJ}+qrAcfGu@)8n z@Kner{g0gK&~paFURN${FpL$XUHfm`Hl8eQ2_ulvfpwD8?<+L(_;;jB^?EV3n(4*? zW^>keeVP%F0kb*1G(iELA|LvizCy@Z6<}zvk}eqER+JnF8Oo#pB8Gkx;nsf^i|Ej& z5<%MIMFtV4KjKVlN54KE1Bbt{1$Ii z=f(%92B7F#tm6H1PA}^t>5vLNu(6a2kt$+)cYTF&RFOdQ#E#oGpK<+$OlUxVwmzL9 z06&R1>cqt)@qAL%>}M|5Sg`t>)l7FtPm|#f=o4^k@dtDxX8gN&+ete5T89U?Y3n5~ z2zhPafxO8ORELM?Ocd3XZ#S0T9T#TiF~!H9ous8^%SKThP~eyEuA5O1*19G_r99q% z!~H04j0mMBVOh?AN_ z@u>&d_N(%BE1bK?uJ1kX+ss##58891@~S91CE>hp&j5&6(y0YyYFh&HYwj80%r|D^ zTU|^r-WoZfJ77$A9QtH)z?}gvxDZdG8R2($3Br|Rs#i}7<{n~4pSl4dwm9LUhb>cc z%$);JhSK_}-?Ol|qzW-V0QWkvmvwtLaL$8X|FO5$ztCgvlHCe32BjI0NM#-xFaK>e zYT82DN(qsov$EYGSDYPyDM-QeYhG9SeZ*{{d&eracBs;i*gq{{cj4G9kQdyC)JIwT zHdLiu4f-@!w$$mvMlg6uNU-6-N3WO8&_!bV;|BBO-%sqOzEsbZWLC2~oT!s;C8|Ql zlac^ibYsjPrf;Qh`#i=?ka1a|r{Lrd+s1d3H-&&|g)aW<`IzS`Iym89F_3l}P*P^D zYixX^tnX%b9((zmt0BQ6Fo0Om+|qXE@c2SREXc_bK#9LYHM1pWl88t%aPJr=vL8Oq!K0j4fJHxo@34{x+Rst^z59jhe( z>jm|vbP?pZSRdF>!}RGC%}jzpuo)xSrn}lBBAB`r3Vhs%frf+gvFIOOR4`U(d5=hF zGsRR`@I`<OgN0t-2Ij%&n?BeW-*q$T&6ODn+)o3hp3A%9lAHY5(;cZehhZXVpJBA}s39_iNg~$% z82mN$-E#y{jFh>wR9af^$X0&HOA9}E3*eqj(L{$zIn#+c{qmIv3;`Z4Hk7h@2j9z~ zSXOvMKCeq4A!14RKVn>xM|6u}}3r8}*uq@TOT+_cp#4%Y#~0 zN)JVKH2HN5x76$F9aR<#Xj&zm2kS%bn>Oa6!o3Xm)_fLzlMw&4$C}>dqdkhl3>(_h zAC{oIsmyU&Q$hvDD!DEMAI3djl|9@4?gDB5B<$0wByQErqI}uR;1MU921C-OL*+hV zaozCu6o!@&MvVkN=mt6jp*$?8L;Uz>t5v+c&V&aIpRwHKDVpw(RrhADd#sRb#ii0d z`ly$VfED+aE^5oP{?vqkC5g^0)5-isY~-2>LqD+{HRxzZhnFsIQBQ1C6ygRGnT9=z zjpT~-MX5J62PGgRxYeks#=HmfemPC*M-8ZJKPZ z!e&oaCOF|y2)mF%H%4GHcOm8f@G-?_AESxK?`YVBo)h|@5{4xFfjc(jMC45`q_&+z z&>q9|r|hyxNe1MVN%E$?5J9W4UOKxrX0to)u#+c*#N~vXkl?J8((7T!-V%X!`~*Wu zV9mdCxl(EIuXw5AMl5MvDj~sStjW=w^blW-cB?ij?DwK9vmBdylf;+7_$cWrLifWB8^QDghB- zGmD>oxZdjPqyp~;*So~)g_Q4rP-Uv ze>Cmw0}t;V3LSx~pj?? z8!G4z6%KcPL_EPq25nN-+Tr?UiAodfeA*OkvmM;79WE_oK|Cmj-!n7&!Ip6RTC?9 z(Av6}DU#A_QvB5gITC@rG0Ie;(gBEMqyJ-}9P7vf{vv}& zWPpgPy7Qvubs=}oGkY|ZnN$<;b z37Shfd?dgYyN385F~M8)I3r)cWAmpY%OxZ&5v31l_=*O-#Mx+yKvVnruEu;0tuj1< zHPyMUPe^vXN*}J6K%(F=)<40`#Ia^#-xO11g|>4s%Eq=DqXjwK(Fv|7tBmwiLcGCa zQ;0CENpD*dg<^^l@ea_*H_K7S8L4cZZMT>3{I7CKZHPWV3(P~GF?C6+R+~@&6V2Lb zWA@qlW#PuQP_+B&sU(^%8iK7WVYCocEGa+5pRCrO(-0i-C+tbfV~RQF)$ViSKbAICrl2H2k^P2ze9fzvPV|n(dFR*{>-xh~EIni1nkm!b3U%*~ru^y@sogECgr|NL5VTQ?pzwu|e{siQ!iwr*ew zIgpCFtS-2Jqey9f?}3Vl>Wj~3-fPbELE$s7#QVfVtv{6HTBm*KM;&8vTf?mK)E^&d zQ8}7OF@D#78A}VnaZYV}v;px!*uMDTLis5EV!FQ=cdJ$zF;~lq_wZE-ZUn`e%}2K` z;aQ^PwiS&mEPb4U@0T{Y7t=(k)=v-9kOt*$=Edt$R^gE$&ApXfUrxfYn;O39BKE_A zI#c|8bE^^6jXqX{BN99Iu_|M9Pa5*f{$(7wOgm~FT~R0M$3VEq8dx&wbPT!};`zw2 zDO4G(5go6<@?cOsr;N7ct1vHgv7%J^`7T&i`pz=lGro5N5(=C-UVB0-YIM%B@5O*N zk(G@-gy__fF!uFL%<6|X)n!bh*<4)&)O{I?QQD@OYC3-dC`%(O>7IN`fe48%9#Z8eK67ZEVp&9bDbEJ)0^V-IKjUEjxx6Id(3a{j);7bTzW|bfL15oX9+(1?QlCY-$a!j7+ z-Nm(|O{`~krwjCJ)m{^A{E$Z2*Qau;-x!UP$UQ~||9a}B3nE(d>m5gK>Uz8nGK_0{ zV_%xAeCtE4GG$#a{YeF`9w7luW)mgf+7DZW&3?AA_*It6YG~;`D=N5d^{hep6pXFd zmGtrS7CpL#&=%~|lgBfw;E2Y3^p7MdXpY|4?~`n?P3di5&Q#sJr1{)S?~M>BE{Pkn z8?qyNYdeuX{^d-{TJ2?{+r<*qZ22iXuvlu9X;_%T+9UD#m9!HzOoz|b8IW@eQ9PA& zX_CYG6rQglq+&6~2g(s*-&|!lYFH}Dh|VP<59g(+Q=I>snB#aWa;1pk5y~FPkf!}0 zIPy-B(rWpbci~r2u;i^rQ7q1fn{G6(N-<8oh2=|bV7F<7)*ngxJIxYqlPGUTIu84e z@G$P@eme>6yclj#)UKLg(M?ir%!GN9d^gcXTaykeH#@gb`m9guMZosuh4NoctG&|3 zHI3eJ=bUM+gH^LCxyA2yeBygWKZy^6b&ju$1zGFo>~<)+-}r2J>3tbf4!2%yvCG55 zjg1!0EVLROY)W3fd`I|ls4}0e9(yA1^M(ILTkg+XMYdm7wkkijc68K`O+xSt-|s81 zwAAY5KaYf-I8BOq`=4ZGx~D5wu_vg#K?x~e67o?RBa0Iqi(y5p_K)1FFD za_4JbT|RMpahSgPQF8rSX!%3>f)FWSj^`?|GuJkbQueGT)|)eG9bXa59-OCjwmi5y z0%1#wjr(|}IJ=IiN}t9t28Qsv?C*qq)Wrs@L&D0YaHd{RZAE7eZ1^C(vAr8y<%3y` zRupp>G5`1tSO}oeR=`rM3o1pc3=qiCX2(hTAw1|gIsKky6EaL{fv-E=j@3p!VGU7s zmoI-lo2zBlL*f7W?+RiSC1C%c-}xM8iGI!Y7wu*=CuS!8Npqv_&z>x#1V^g70(6kv zMpp-N`Db(_W&WRTCL@d1(DXI(i>PJu2s^AD4$R#3ZXgDl^G9q!p9h!5iGC zv~YA>6_@hBW9#)!BDBKmEm^luRQX*UQI8KA*$XZCV|J3EhGA>1W&MqBzGOuqKe@n8 zGl+3+s2YfF-uB_?Ti_c)C*QX=g%ClLO2~x6Tie0z3<+;O`HsJ-Y*|p*xbF6{OUAA` z`YxxMXW?2dV))=ax>n;1Q>wEM1jTy>yexs_u6s0Qa^gMnJ=MSprAaS1wy9nbbnAw* zk}G{{O|ueo=RdA-%S_+(KD`HYMK$u`v=UkUyt6t(6g#7BI$gJ(WOKlV13!e#s(TR~ z@-1b5|B3&F;gr0kp!KEXn*YB2*3RVe$K3A8KI>l!xF60nk@-+!MQFKLMlIck(v;*N zX}DY6_SQS|g)?=5nN8M@t2G`RjPA)(ZVJUST{xdyMB{E&9$i+_9|+g>g_ySypD9!! z7`Jgp%L^Mi@AYQwFqeU*m=cvu#yIzAx??)>$W z&&~Y80dpT0KSw=b-r8b_VXIM3%=Qc>bTTa)^fR5~+Ru3oeo|N5D3uC=Fj_!N_F4)+ zFC`;pFS{obr<_qQfl(A+lU`ok+V{QNG@-Ik)TX&?Ou}A)6Rs)=w5M6~xJC8E?0<1I zSiuvTjg-sGZA&hq$c#~;&7zF{;{qIF(3VsoA}k1i`?+nEZx?*oevSxxa6`NMarL`b zen3KY;E53JZV>BiWq-Iwdtjq-yH{uil=y>@>%s5I>10qZOn?QV;!oh*;+4iD{a2kXok?aqdH-D!XL2@~zE6zfa? z>x>5LjDI@*0sa2~&pwPEBvp+@Dc9ux(LU#I5`0W;<-+&S zlFFpHDI(a^Fh;v}dS2dArtp>ug|{46c+1Dec&%ThEJorgGJ<;9jHP{)B>i!Fh4dP_FtF+$$8^A5?I+ofr3X<*Hx7yzk3sB$dC^&!QH6fewD}_ ze@a0=)=RWc2#Bk{tS@FXiBf2IZ>88Dq#3Q)_r#w@pvk&Id%qHYR^LqDII6c_xejP% zh`iEOc|8s^9eQU5+)dR>#p)%FrUqw2L(?)Rzjq_PKk8gjSu7&89U(0(hB0g7Lqr)xini0hBZLDta@Oy}exSQ&7t>PXB z-yd>#)-3Du=9`7upnyDgv*4@Z6T3GHwNuicLZv+rlX_8xXUs&kcZd%D6uS$P+T|KLDgd zCi^Bp27e+&_5os%-SyVgSgn8}pW$6HUgK^ByFV#K3IN$IYp3K^D(PquDaX5H+)OMZW#bc>ietq%m5XVQkpZQWwV4P>oyu?V~F*(cpct;TP$Pb^$d%h0+Gh< zcl+$l#+pi*P4Bra_I?10_yKuXro;cdEmm>m-w1RYeIh=_{da&wWcJz*NQ+EkhZTK( z50G^-np1#yWZXyF;{EUv8-B~Jl*R&xRc6x?K$=se$O2pJNkEF+Z;L&p#lJTUkb0Tj ze+$T~25ArXV#~5f(r1gU+Ca}m^UCeB%Ejk*D9s19SnZVeUR$i5$xAv7+PPO24*@BY z#f|BJbjl>H1fcbq;i=Q=>;V7r&44P zka4p9j4c8wmP={AhKSsM0O4fqR2Ic5{}gEgE7SZ*?2k;(m%)OwV5f$YX$H%JlPWNvyidk8W&7*5`Lh;>X2lK(b_``@-pu_`Ql!npQwwmHFzA0m+cv^(?k5v(Br4 zbcpTDcRQUP$u0~(x`8ITRC?DaaNQ1BJ2wF0k=d&NkXPl|4j|u=jpcg)vB~l}Hx3F} z+-T(=wu`m%6d=#Z+IayG^C%%Ez`X3jOxP@o2`|lv)q7JoPqnKNk7H)bXx^AXy)MS< zA2VX_rQx4UoEbkaUp6!L)=i3hV`gkmfg;lok9Uuo}y#5JDhs?(={uakgmD%fhKssdOs{{~RlN71=R=fq5 z0uqr)5eB3}X0Im!G0MiyZvbhR_2*?k%(5tP{9Ezy@Dw1;vUoV=PC#Vi;s!vBGPz~~ z5|Po=+=&m($W{t~WXO8>2q00J?7snIP}a^KK#t3J_1qbIcOOOGz7xOWQi^MX2Fav(@z#49$Chi2Z&iF`wT>6{qZ9rH1f)|Y>Fsl4?`Gk%K|stht$F}?R6b4tvB}!m1jwMwpLYV1B}NI-!@Str z4*8sRZhTblS0JacWx18-#hwc1*QbDF%WQEoAcHcw?gHefOslo?VtbL`ElrK&1&AKm z7+g6oK4%LfB8wZF=Fz`mecm@OUWzCnn`GQSoELi|D?b+i@{G(AE}0L!WU}7^NV5#N z2atAI{CNNno2=#afOO0HycrOWjOGPEI%IS18}nn|?8EmN5t)@omV>t}ks?qkbXdHGX0EL0CciBS%3ptimX`>+Z~`tJ0MmW%~rhY?pRcJHrDW~KU(*E39fs* zPJ6YTWT|um$THFEto8W46Yad4RypfjjanC>Nm?eEIeTU~KJMpjf=R&dcU0FqYm_%N zI{dC>PP@vpW;S2@%gBRRSn>QF(eRcUcnv)lQX z1%RycX~#4>4vTDj6Q|wlboiPYIp&QGuEx6Mc8AAf_pkIg#dn-d6X@={?>^vPS6vM) z*13Fsr`KNV#hqpf);Qx}$!#@GS0h|-I~~xkdPj|;!Qrjpn!Iq&O1s}t<#uvN(CBmd zSK6@&XVXNN&+C|I-CytYJIK?Iv=;>vr{qnU!t?ZimRx?)G*3=? z;cRqz>s(GB*VyE3aJXGQiu*vwcqC52{HzLXyP#Wcx5MLeaz5~UM-8YxCP_?W?73Z{ zI?~CBQ}XjBlPfZ{3fCr0mgmiN7jkE9kVLrrPhL z#&b4SH-Sfx8-1?(oD>E9I2%0m4luTq%)Z>^ueUp^p2`u2P?w{sr=-xo2Krab5$j!omrX3VDc>r&;;#p|zR6vKS0)uwd8-3He^Y}f zMYZ287fTx4=%A3xR|va z6+YGA1Gkdy5}Vf6f`wru$39ilKV9^1xp)wL+>UCeL<9lhwJRZ)4qI>%9J2P>Chu|x z;?S-L;mpTl@qOd{tpRmZ4IT;>!oTwitX8YNaEjHQn`h-nz#=>04ia{kyBcenmg5x^ zfXu(K8&ttuH84*NoWzkX`VCvd zg&Vw1Je~k|1gbEcb3QO6GzndgWh7)0r&Fb;nzmT$!j>rL2>6?@X(>6KJF1%;UZ0cB zek+Ne(aCrcR|Rt@Tz1xC5?4e2^5Llmkr+K+r4`PJd0G|m3O7#xN)Rtogl_~ckg1gm zG^#ZvpwjyVEWQPmSxDk_(qXc~WA`@s37!j|{9c+-(5c(r;P5RK1A~N=V!7P>vUw%b zitW><6_wAKH*s=d?qnGmj10SH*}c5=zyuC=ot^ZU{KfYktQt!zmO04;O(%7`i>5E} zV~wBVh)bvsV(L9ho!&;L+wKF6)C3^hxEeuEXptI%5r2rsVwnM`p%Glw=hKQ5a_N9B zPlHhMr_beHYA>37hkYJ-GMbB~aotDkXrEJC3%&K(=jK|q8d7A$(u?3Oa20f_E>vlGnH>}fpMk|qS|syf z?cwy%%m#Xruf+_4jH}wI&I$8=dlQkyz7RZ@Xi|+3vqJ5wfkqe14h;p`6foW)X6Uyv zyLA3^d&%N*CZBw53aLPiP5Ls?Q0jKnX_KHOJS01UIYOUIl#SR;TR@V)dz#$TlV}32 z+p-Vs%#woYS4yPtIhw4gHQ|Mc((ZOHbK9I@ChvdZP>UI|d+R6sL}RVET)2rKnb3ZdKKb&;T44Y^fq zt!hWhy$)PhVhDgcZnw{cH8h)Unv_mtNgPs{!;@=`O_)Xa>Kzak@1;|iV9?p~=gRYT z5rtqv)=0{$Wu-;@Og&@Tyjk{X<>fH*Oy&qYZFVsNC9@YyD=)DxSg3V{UJ#qBa|ig@ zQt3UudM8OLWmC3%{wEZ~$LK^zW4|vU;zxs2UA=4slfflJsvq)8xMVfLfQWrup-Q-EKatS<1G1KXIKW1+@55+#gTs0db zS}B7TyK*b7QHpDCQ=xMg}lFBK}T1Sf+za)b3Vb- zHPb#mohQVMoF3`0(x>eD!nyWEvm7u}7pa8h8Jd%h+`pXab2z!SaIQKYX!JPb)dcCJ zLnjJ4X~vV_mW*05RK_-gay5(sprq0 zr#`Vdyme0hJj^TT#G#QyD(Ggb(*YlGDVA76vE)&{LXDg5VhVBMrW9Yi$EBl8POZD9 z<)Ql3{cZmAq9$Ltqsl&g=3?l!GS)g89c1y3LuIKwS8=_{1(wGOo}bkFYn-_nc%F*W zRxNj~@W2p+Ty0XG&Q-k#A*^jk`Akhl$kR#O@%bHf&Pg=8Pk@k3l9y;(c`8;GODqnz ztFF;mV<&4o1)%Rp9tyMOULr?pcH;bFaj0GJZQpjmFi8yEIsf1J)!gRqH7k z9Vl-a-Mn)(*5z6!PPR_5#y(Gh&yx$)BLt|R%0(*r8bQatoW^R*-LYJE`U0#B8LjUAi z($OE5n4!Cg3S=*x%W6#Ly2tBUhEZ?YyhNz5HHb&^5+I#9bDoq^zF-uoaq9`m?74}s z4|wwIGv?}FwJ-NNJRbePbh0!GXV-Xtc)WNiv5JDRD@&7Gvy;RaWYy{XZ?Qm+-fZWpOl%P>5pP|83psNnI; z;%_ILJ$SQ=RP;5d_=5-%P0J#8txIVn@I?^8hua`@|I9wUv`i%*@_HAN%>;5;#AeZO zsdfu5SPdcY>}ImCS8bi>17*^_2>Gz)MX`A6)1eV| zr_^awrb~4?=trV-v{+m1_qtU{q~#c~Ni{+tccwKcH43k@E&y{TOs&L@PFhgbqV>7R zjt{>vR^0^4g_s}2Ush{kxx?!LZ3^3kJUdlVnsUaPr};zdvus@;A)7Bo))*MK5>w@u zNS~?#-a6cNbk({*3RQ|&I;uVxG*uJJ=K|G!Rf?r~4oweKCS$7pK-^t)8Qi8)8;J|O-ofdD3vZjeZZ@sX4xzUFCb3@RRRqXwn3 zI^MvaJ%~w1(-?_Kc>m_@-q6(8WN!%gT-7ntNe&u#4)lT*6eET{r@Dw_2)Z(eM z*hhW<1_9!;M?^?_4FR{` zg@-;J4KkOIgd8;zxufNBzJS-;6u^UC{OqN5t1LF?wXCENc_>JiHF>LG!fb%N0#B>z zOO`;x>SS@_gWZf4q0HgpCS&Wc~@ym;)?p~%qrC*IW1Tvaqr*$e6e zN|=7bs)(Z{U5&L(oHx)Ii_!y9lu*ZuAzZ5S2Bde;9#O&gzxh%x|5_W# zrQG;SUS~C|0%V|7LT?o>Nf^?nS@0n&|@-O-)N(PWq-bi{zp{Zbvn{oefTi z<8~YpxCW~8)jC{m@E`7u`SzlwMts5BJcuja8U#vKR69MmU{Zm~n#ds*Uz{%ZN1IR+ zocu{Ag%#VDZt7%D_70QQ{B_|fr_|LK)@Pg6jOzd{@4l>M0n!GE8c+uck zF`qt00LJn-U6Tr?*uic6t_Dnw$*Eqrce#W1dt%{aYeBx!hVvH8E}uE8#9lVPWI^#9 z`@E9UIYrc_C9{jcuK&Ufb~SHVrD< z{E`_|C3cunYp}L2T%kLL0*XS{L;4Gg2y*tgAz-KPU&O!Y+Zye4jRCt;a09VDB~!?d zQLXl+&Xsgz2>O>?ul8}mWxE@~DO|HJpOPOVaMaX@4aje#P8CnjA83!i#a>=IKmJKO z?Xv^+g?!#U6RmJN7(wj1;tFS<4q>^hg!ibpkGHR!O&@ooy}&X6y)eDWJFTV$f~ZgB zVi9C|{~@zl`n@a3U}uxde4x6?=cWhU@EwHeRKjH}tkr6^u`~? z_2gBiFe@(bIk7BVU*e590B(K*ED*__W|KaHXs5+>GU9x~Q;&4Oi61@kk0i)XoHBXx zq{;H$xtbui2{eM;91XrYJDED{@jW4a4D1`|OOC`DhH=z@b=Wnr?T+|!*X%tRyM7>3 z9%axu!NS;$q;oEP^`#wM7X~`~OCLg*lxKH<>geb~oztgop$pK%V#)lPP$iOaE>G*2 z2A>s>hkgG6WK2|p zU@P2`QGy*WcDkK@XAw*wE^rEA4pUE5^`Bzl9e8fQ>0K$ZbBXM<&eQYylg3BkR{G38 zPe9)st8zF#=E7Xu^E}LR?C}rxCYGuR6G{_)duz4FFJ?g6M|`LZ;L`m3Twae)+|I1w zl&AJ$L}hf73#iK7K7beEE<9Hb69q&)zmvbrX+3|D*b!%~!-E=UkL~sxx^h?bQkr}JE6Y5_*|3;Ogn$M*gD~CXlf-A8E5xaC+5D>ckc{>dtcfMNsu7A`9Z0hY{>}8-W>@AtYNs@D z@~Tl=mvD^pVRRa$J(7i;xE33H%P@2}VqU+jy4nqW7rb7GE!A<}Bj4!JvxWMLji{Pb z0|evf7GLgz)QHnuM+kk6$d)4FgO!Sd=K7Bt)6S5*yv*svY0uGE?IivdznYAHR+xDlmKT(Mi9;f* zXZfSAe88crQN^Z(=40D-JVWP!q$CBd>Mu=UQBQDGCSil`lxr}rmPSW%?3 znl%oU5`%i}iGPikW-(7u0Mg8h=?kb;vtywY5no@FueGH00vd?@dZrU!ZeW+x6_gW= ztI^LfcAQ9bmaJqI5nh;_rS2Sm+MDr2H*G;}@uGNDgXYurd{s=y7h=mqtq>|>D%3xS zDa6XItZIeR2(4NP78C2lnu2MhgIaGAOz3?U>RV0f@9apZDUAx3-gGT|ACVB>XkVlu z4l)=#=ly$laKHzoEr;<>r`lP7WJ6<>w|0vNb~ z{TD6d|3`lE^2`l*Cgs-LDc1ZcQwj?6Z<=Tw{eR=)|1Uo^E+3w{n&?^ijogWoC+6MA z12$88DR+YJ9-aP@N+a9c+G<(h4V(!X3&UhndmJ>I4|ucN_S?PzRl z@|&xiW^bU;>}oU@&zWz=cWO=?J9f129lT{F99L=>#f|<1da%#PWsKptC^zD|F@}`O zxwFu--A2;6=*9HAsklt+si#W#Iv^we9jZpr4r%1Wvp*ccfB&kP-iQBWQWEkjYUCcq zFYg^Ra-Bw{Y|ngR<|3Ej?P*;81=>0=W~PyEFN*&;4(&dpH}CS_a=YbBD(w);8rP3X zuB=k{rrQFJmz})2UQTG^$|AzI6F>1&>@!^7i28}AtF#H)9fHi{D-(XJpo`#J+sSu+(C@>ba%@qdgOw(4HISF5+p0oG z7DpVl4cLh2aGQee_Wz6U`ako7?`Q8dT5u@$4-Tbrp;I5 z5W!AdO6h@DKeRG@N!CaHs^I&^(BPoycUN`-54ivBr?o zjD>G5H-%Gy;V1B6xV!MpWgms|E&Yp6rE+`IkeX;VZ4>`jZe(xT7XI&t(mDnEiP|G( z85l7zz#BjkvyWiIqd+w9Tex&$Y`gSl!J^PB3+IRSgnEMSk83>?x+Fc*UlnjYP5db0 zpV2?&C@5i-B^|kvFP;R!|Nd?&2O35=RADh9w3~-sl!Erphlc?KE2rdsus02x204d= zyT^t4K^04O)wcKl29(@ZGz>OgcAfOzAZ;-CS!(FTz^)TNXxs8N!d^nc3C;VTmcoVf zPB7++{y^|EL*SYI2j7SZVc>1F3_pd%j)PX~am#^HC(SPdoRHV%~@kaZC(7QB3 z*s?rT{TIN6{rt#p+d;k)G4$?|T~d37-X$SnYN+JZ&_2`VouOIB+wxn<4bv|Q1-iTX zja^Y=|Hijdxt!hMlJvF;3+iCW(SW~o|C(9hl2_aE+lUtrhf1Pt#z#r7N_zSJXP2V)yD%p;gar9F^tNRqwvcJP2;Fa z`4kN9{FJwUxa4@-)Yc);6?9^C@0tVHf#vCxIgAI0W!Hz7^a9Ip%kws~zbd@sC`i>d zE|?p^>#F>b`JNMN@j6k4HN47V3;Qj_;R?%)KI0z^d*GkGuHKh=)3!mA_}80VeG&NY zOy7rZy?3l{dC{@Hz6#5P)+2qzmI;*V=$SW9uQBIF`i$S{eW}m5mfSP$JIJ{=@ZPcB zW4$Lv)VAaA;BG5Ox9eDiCA)8b2uuw|wLo*`zWwlT*0FJx{?|bLKw50cCa!?j!5!fL ztiG2{v|`8k@eAYgH5i|}La%^L!{{CpK$qrl(Kz^J0c-3xJsQb98NA;-5`b|JTpcbl z!hlHY>+f5_75XjXLZ7d>AFsZEe!u2#z|P#d-#??T1j7^<2VoF;;8?HehY>Ur{ExnA zL0i4>IyfzUo^K2;HK(^8@^9+vZ;kXt15bmvKZY=al;Ws@J2oBUxD(y6_ygC=pg$S# zdqN-i)R!IHJynRoOLoP@qlNRqMyQlbP(}vWEDP=#*Lq~l!ahUpp|=K>jXH5bpYi)| z4J;oS+-WH634C1Gz4{6?hw(uo#Ppqa-?J;mf6cXh#cR*r-COhE*}nbv@D!5kxra`? zaI81fePTZyRW6WaZ0+S-n*Ec;so88#5*LGow({*~RX-A){XFY_TwL39O z?>b|uUAuFE+4RRlrp-MP?7ercH0{`F+Pv%TG=dG8a`x4xam~W;rToD^LBLE9I?MFu zq2Q^jO@IERZO%V}C$H{_w$1)W&bbX;|2@XledM3R!#(eqb{r8Iw0-yNRUBvf<3ZQU zc+s@E8+wSBPMg}kgMZYn?K*oETnEO`u{I<4qAOCj+->(RBVP7UVm@Pa% zBfJ#-s~}vI4nTg$Z=gJc6JS=2Hzf;(`DMRqp%i$T6eNcUS0 znOgUapqH$0=?1tI+6y$1Lv$82F1V9=xxA&(#K$CbXyj=u6P6QWC_b22Vp? zmkLP>e~W4JUor2?!HySMTQM40O|8F%#YNlWxFG5J>;mdU>z{&7gM}xA2D|#NHVhsd zYV+Gt3wztLMnD&>rgh6;T5c=7JGE`@=g)lJ&l@j=LKF{%Wq?)V@j z!wfwTWkN7TRec62(N47LUTPlv0b=m=uIR`O;2J_)8yE%r_PLbPPSWaKVBFUBg$OdN1cp=#9d+OyBbW-d6lTYFpXo za2Jl4bmDp7A2065TO=NbVE10R(|{MY?gCXx^gZw}Sb^^&xEoR4pTO5bdrx$d^+Ma9 zP*LGK3%Z6cfLwsAwOWTw>v2McNo7LeXQuT-T#WfA&k@JmF_;5W(@A3cLu>aCXFN9+ zoFEe~{MNFH!MC2RqTnR3*FVvkgD9%HMeH*aD zu3gxY;@(|x_tMX`HvmTf4c!|s936wq5XA6rXq%6}S9HBSlJt3J_+sJq!kwmd4}vjI z9frT=Y$vLdtWWvSxMl@v1Cn+$M_UnUGQHpaSBYXmdj{$t0xN>N#2UFDkWk+fy(V=V z8POR12gaNMJ)PwFK|e!%IbAtB4Iddk9(aJa9t5Z|18BN%$h7VXXteDPL#WHN`IUpG z4f`;MBZBSAauTfI~wVhu@_*R4@Cd+-Yt*EsjSC zj7}CT$Xs(Hq=T7ja$q!|$F*R8_|b>?U<#dhh^KuICZ7{yq)ptNPYRT<5HIG3HT^Yk z01Sowr33eY`?eXtX&yfX^H1A21BPmHA4G7tbw+R7^x?u!OtX5|;#37QR8ZB*8r}R%c%5gb+iE$vy3Pw^wALqb)w}&1&=x*Uj;rp||6q}G=Da6D(F@D$}mdptI#(@Wc`-&Q}o4a>$Ht?fJ2+qf+|=?@(nyvm zM!Vwe;OUWTE(-1II-MGfjs(JBB)umZ>H?+CfS}fLqk&E^WC3J^wNy5l)nS2v3k&#- z+S^Dc8=QYi$^3&67MGvJph^fS*Jr`p^Wuqgn*Sc_UAr4~&le=x3qgoAqcICKrIGx` zXUzSe^`!p|)7EvQ>F_4Y7WnlXhK8QEgYOxxd9C$>5Cu&wAE08_S+MeqiVD*?YbwlH z#o?mym>T9DLMw!~6Pns~R|HoZeQCQf%ShV?|B{u*$=%I|_aE!)HU6+~-1l*z^LpU5 z5HwIU0i;e>6RYPE11A%O%12gQF-0Y!puQ}zr5EoG^~>{BNbO-Q4MDJN!m}Jr_X}|T z1|Fq`e?YXw*3nUmO)cFtwIf;sncK=O^{4?DQlw&!^BJt~4i1I(;>x0}h3F7&%^((y zbri02#4?BizOTj5*HCZ&EuRbzA1SuD1=i5L6__UUr5(U(LAhns(f!b7Ina3C+z*S& zQqy{rI%jE2hS9q3-dCTTgpu9u)f*1 zA9{$&s{qZQWLc1)gnFUNFe|{_&%_FwGk|I_{EtgCBYd{?M=(PJqoE;hD8lN&V)(xz zXHW24_L_@;q`a;8rhf3{M|ZXyGL;O4F_6$6yor2^Awf*XZ0#dVa(afa3xq*2S#_gR zWPpah{TZDV%ffDpttUF_#ew~2#rfq}FH#DHu&!tdZzbYMBi~Nt2A()8tw;8~M1%!# zc;=W_hYs>G71K@#9S|j^9qB&9cSMjBV#ABP@Hu;f!`W-HU_vR!nYpd_oBh1lgE5hz zX;d7lIL0B9Pg0+Wx!4S{*y-)J149t^@Mky~^Z6}p4E-27FSs)N&NR^98Du53(-1+O z2H!S}>PEj0(c1(crx6PkoF#E?;Mg!oy;<;L^k3@9(DV!g9UtXK_s6_>;I7ZftW)r( zH2m^9&*>VNM9HSM4zDQ!N3cOS3Vqa;{{js_!7d|-JE6T@ z!&$(h02mbXefw!TDh27T6Hn zgOOsKVU;EO7Qdy^w62B}rl*q7d91=>#wy*7ukckm^NBz3_FoX&aDn?RFeIkJyoix~ zf-nfeHZyUlJ0_SmzsQdWF+YSGVKuX+p4?naoZbrN$S`fbBONena8F9x)Q3`ms?GQv z7(;zTGSiOf=S({;?Hvg%nl`^y*xh^Uc7RvI^2Zp25j1Wsu0^{8A06vGk#ejzxYr2n z6i&4SBG7hv5bJZu%`gFpT8Q|Ai1Ag_S7 zvv5&&3^^OaIg}Rnb8tA02QOF+_v~xk-COFM zY7im|r<(o>FgaF!Nl^|!tp5i082hH51@8g97WRU=?Pni20b1T^xCQ*vKLyrC3%C;x zl6)Q9C9M})J@IR*R@06WPLvEBMG)$Nuk)4D@>twljAH_Rm+^i$u=i*xCk&_D;emgi zqxmA%>RQMGrI2Qyuw20yVrnyExd9h2WaR>*V=tfC)3xIa1J+cE#d1pvSsQ_~t-xu7 zt~ZK_v5Ucp+h(7`1dp_5+L2`i&05ceUgv9DIeVa)CujyRE^KViJp?>Xo$Tqy>-j9tBBKgF`$e`9?SE?AFXMCOOE>7lz}MkZzWQk+k)GRTM8 z@nj;Q*^8Nu1fa@~^?!@y5!6Z<#&Xd3&Qx9r{93Tj_#lvMz($M@25v~D0tt7msvRyLfe*bC9>l`A>7m7-?7pZ}(o6r6idDN+sn~lW zX~fhr%|Lo>#m4Y{Ue#2=y``3X(79=c5yOGMCkj@X&^p|f|Db6-=}#p0Q11S|=!ucR zE<@pI|03KzGHvC0hJsN;-~_nWINU19J>)t<63VW%yGS0nw>e-u*4r0pn=l&eV>ko( z?YO>izYX+4GbD#CJRR6VHZMjA{@dGn$bUVbe&LD`)@QfTDN{@p`<-J9+=(;@+b|43 z#|F?^3yp5$4G;B90+hrEFo70QC+3$_{#xEi2UdI@n{T1- zANEBDetC{x5BH88LUZ$KJl1D=@L9M-vJekHzhmv!j})L!R4eE-z0J52R5`GfY`0a& zg8aAk3qgLM{d1N5Q5`u>}5~m6FqC z+6-|xcpBI~N16kk;R;ghnwmR|1qB#Q#=#m^xzgtUz(Bs_&R>XjiH^vh|%yyVOL-`(R2Z5+K9CX;1KLj zy~SvG;DR>eBwX31o%+ZC5*vndBZaS+eiAX9%so{2SJO{+8jcvc;m?=h&md+=hVHIt zI*?`tjTS@j#gwqo0=`*pYP|xdCQuAk4a_)C7+?y6S!=Or-CNX=a6@SUT+N1c*_FJ$ z%X1Iia7TLE3}a{z6|?x%MQJjXHxu2+h&{vEf;qMhb~=H zjVa__a?k~%K3SmIPQje~93Hp00kYE65nXTN-6PtJwzl$=+sWabt}`jYGjrBtuRSx2 zr6Rn2&6wQC+A|NpurfUv3GTKKKLgdB*bp4L2&<2#ry{1UkBd7`%?O6q(q1tv@pN7HQ$B_#4Xi}igHuSzZ z(07I5FywE?f-jPZ%WW|Sx`Mlnq*J0l(f#7kp5XiLP|5DlzVHR11+T(_De4V4@SmFzRM{2kZg3(VmFgp1HekZZ#N{n1F*z}44u!J4kHkzNt(+=McFE|hy3I{Sm zU7^*zAkf~D10*|syXRbJ!9GYzOzZbS*Mh4v45mj)z&s_9P|0@ExT&=(l~hw(R|5si z-dTMm<8Z|gF3BPX4*aBQmk};W2Y%tzyTh}(!wX&w4fTKRLvYkN#?US-0vtleD(MX` z*cUn#a&8HA_52R_ za4CsOcFQBC^-mFSTPUz8xHml<*dAK49n1&{-^KeE_)AW>BodzWYWR^2xPNZi{Cb=5 z`-YF(GC(!E`SSS{FfnumKEV{HWVf+!Ni?uG9M}|IvVGv2gh6)hew1**tKpK}{jR@( zeRj1uKMnN~Ujo5S9lGWvuy#u$=nK|dty@!gjjq3%+~19bS7C8jVn*wH){~0j>?w(G zdrP*H&=<%+olnI(R-5;h^pbE%&1Kp;izslgC)#r+JZpO>!vY2!>L2^o@bEy@x!8P> zh?PK$S>14R^ZQ_>MQEi%rj`ky)NsiGaH(4$d>#&c7GAv%=C_0ALfwYp&_|$}p8iog zLkps~qk!V@UUmyCZ*N(0AiN+N=n3_NSNFCK`)`I80@2X9@ak7XACXxWoS4H@=WSSb z@V*MmN9wNqL$Hv#CD0q_2?wGmXwQF#XJxnU_uqP?q&t=l<&kscwfo!*8OX~ zf|9JxrbiNB5%3V*km45sp^r!s2zH|Tle+|Ssad1pP%0{YU@k}lE5tjy-cCXJ0+G;y z-4G3yZ0h=ZO6aelp7!v9?crIwafaH9vv^nNV}%FpK?e%$3%nYJ<;Rju;gU|uXq)5^ z$ma)vpL5H=cX6yMO-9U>LFwbi)=Tf9`-Sf?;$G1*T-63LcxM@S0VjxrdZ2a9BkJ>ArI zqK1hl zwvB6p#wLJBQ;kP`^SminVuBBG@OH?GZqy7Em3tTqFw&ylQswmEbLrs|qd4{qf3 zJV$DkpA~*)n)4R!I2_LD;yax47TMLCZH8;>?nxmvx@TzKkF2468wwJFHQ^x5&mjB7 zG6XH0Giq;mI*yjs#Tb@% zuL=#(S~t4EDd@}a4xoEP(4(m}9Za9owRROOw9L>LKB^sqaC+Ni8g7|%9L0G$w<@$Vhu`bXxWxpcFS&Qn-SV3Auzd+ z)5C?dGF`gsRNK{k-G0HggvO7NOoAi>FFu1P zMu|h<(%J3`opDV+4O{<_jO#uz$6Ot3~`+EC5f1Hq?sHXQ*MQw`(=Rm-X1R?2f3I34o4Hg`Wn0eAX zXn8jb#>9Tr=nm-*152BD3Z(KHL<_k#zkX@@>y`3Uvtd9l ziS3i<1%T^)IsQSbYifN+o>_nPEO-b7+@Ooqp9E4IaOv$l;MKP2-$pY+1pWZ<-g_<7 zbV2bIEEaX?&Ej1Kxub0B2-Pp0Aq2OZJG9+`ZNKsoi#{%1H|wk6Uu=fg=WDxLvB4>= z>B_5-=ctf6xX`G=^ySd!6Z$u?Yy86k`GQm6(I@dyWrfntI+(sw(0w+l^lE#unC^pW zy?sNx(#`a>(9bYT?##8X+9`{0y!)3;H`1ciPtM7F-HphT3v>h=+)vo~& zk_3xi?gqi4soxMHCexcl6+>-i`dp~nR3LB?jfm?{$#H3W%4THD(V_9aAt9u zx=TFl(uc+&SPC$ns2JUgdr-slY}{!dGfu;&(c`o?Oh1Cp%ULvzPdrRNNHF0S44u9c z%X69Djs>yUZCI%04yK#14#xMcf;}~08*y9tvaBwBl^jHuzFCy;aj+bjZKfCFBEohW zYcm9c%=7|a=>&fpErLRQ7FMexfB=9Bol~0iZ{cUnxO1Z{S}qFCdNIS5IPR)BVz|+z zF$(9hY!-nLHAY)tgtgZ-MxkAbEz`gUapR4IW{2QZi z9vqrJ42&es5RO=#Tl@;cr?bNF>AYy&v<=moMga(Q`&jTu6N0(Awr^+-9sx}7|N69$Tg=a7Me@v;ge3i>vBkcB82fgThs2omw3 zx5dZ;MM$SRxdD417QIW4%dxWkbHcDg&DXI5+<+ZuE}JRX_FS$v!p4<7H=zW|sMXkz z(~q4AOcMGPY@q_A03nAqTgBAJm1TtYboOtz5VXp-6!$@nLd19QEC36h;HLt#^ z3x`Tt39-jjxYJ;Mt-qJ+FnCmrg+`s)qFx>-V_~TNny)#uiafqDHo_(xm3 zAK7t#x3;KT(As+rQGE#^we!<waw>%tS|8rsPM?+2y5Hr-1Nh={(@U#_$sjQCg`#*sSfmEOTn3|ytRVOk;%x;-v`xU8WXNg+H2=P!y1Ul^~(`C(T5epQ_PxncEayEJDv>$l}U6iQMuqt zLSs`lO5+9|B0Vd4N}ieyoi-#Qa0>JXhH67Xu!|epVIUyc6W2Fgz?%hp3`y8;)AP9gP`Im=x342j3=?+ zvXGoI<8l1y9*hYt4vSe<- zXU1yWa9kH-6_$5ldF5CVFpU*hej$mLn6W$sp12msn;A9ubg!JBu@rxH7#67O~o~VF5{7LK0!(RCcB~$^w z5mAF6vUVO1r!bQGU4lRx`cjR8y9EMxwgm7mKqq<;ava%QFTjD+ju99c#-GLSJQH+@ z03G@>;zj(U_zB{XFnq|qn9c4MO#&ieA7pn6@Bmc8?iS#yVj+v`4lH=M4%my`Eojv! z7IL`$HWqwbKZgauS0G{%a<&fmMRKnCX)GhI(c7?${Hs2MW!zZZgK&-vu8x=m2^7v5X8ji3GUX zo8@YseIAys#2yE}dtAQjeI7OwS>2`=Gi|a=s0NkmO^2`en*GuVvgjm7kpSFHkNGXDjm-d~ShofEh294T@&G5*oaa$4)AJGo5V0ma*VMl2^p-%XI zso>$>syok(W*i*OJ6eRB*pg(XwH>_-WdbMSdgl^>+5kukd)O-}`}gio(3usS!j%`< z(K)SHH;f|F?%J!Su55)C{bt=CSQNK9SkAGl#DnJ{zUp1Fht~8T>i-vsBg>XJo|-Ok z*gRCa)ikmm1p1Jd-qC(`_n-AM}gsrTZ)FpeaWokj~GT7jGnQLn?1 zrUCF8`k#|sBLM`xBh-ih-;@ZZ+oKBm_n~6UK}s~#)Zv&APxYNe(TrD#eF8Ozw#S=6 zS`sm&3<#V7$Ii+Mz*q(N)H4%)=N+R{*>{Q^GQ6R@n9`otOLK{x%s|5L^+^gI|7ok! zkpK#Y@fpd^FB=)=N+^Z#;7L3*YD;c9Np1!LC!Q)g`|okKl3ILFr|a^pXN%*QlH>lS z^!B|$IBSLNi7&hbs4kHsj)yo}@wY)pO58n$59==>m?j56gSmVdX~+7#hVy6Nx z4O2TTK73wAQPmC>wu3zcU1!qb2_AfagYu>Z6<2nL+a;O}h{!GJkDt0nb=!p6xT2NdSDd>8q&)%aHNGT#dEXf3bv)j`CAcmKs*-2HRiH9pVt}@6^dSzzFf<}e%XIUR4U-)eaL@F&X@lY(*iFy_0)bG>AC&u z)&bLB?aS4gCcxvwB-_Qx(B2C42i@}Hhh_M5PdmTEePHI}^pg0lM zddDrbU-p}#-(t|si`8APiYHk1SnFM)tZj?=#dysgZChs(xLIb`e&|F32W}6C9AChh zK>xG0Wj$Fvip3)28tw>Gyl7cvnrf*UM5T!0g!pe%`m^M{VgYp<12=1V9uV)n)<)GX=UDsAEikge3*wh=I7`|aTxg?!f6JbAS?X`iZYyq{#NF;O zuQb*5p_pnZ=KN7ep=AoDUp42yE!wN_`350RgE%23{BmL0WA3+JGGD@)J>qFL z`F8aL7YH0185Q;!_~->LcEl_JB9f!U~&Dg26N@Z&H=OV&*ETy z&(04cezzz7WhxbKTOr1w{t7+)yOiF%gy?dG=wLbF#g&Qn%kBN-Z&oL!u+XKqH#{tc z55C(zz9xr%W2I5?`KiKwA=b$DwH*RaRNvsx_PD>O?N&3iJ=I^#2(_2w?FYBj9B@1I z^_>!|8>DH7jb|{=cF`_)+MDY-ZEv%*{sEt~<=kBRW#ir%p|KfjuDp1RtKlK>;5=4q zyImAJr{$-4>A?qBAKM=~yNZ{ndcT-lJ`X?;ST(5nA-vlR-VAouWXL8a*y&p#D$v6` zu}J8>34!M$Vt>lC9bIf3Oi47yJ|zbJ*M@3H{8?cqJ}JYHnMNws7;02LEi%-IELNo| zlo$c<9+;cLZ+d^jS0Qc&o$2d*Wl9_o#W^vIm!$o88@VlI%Rq?&8Jm(%tX;9~84}v3 zN*CO@n6KzR9S&!muV`MaFE{us8wr73OiU1*rHhpcG9)V1zLI&;+k5jj!LgF!V>5ya zLWx!ci4ss-6va{xYBWNbQ%!@xt(TIBMdIe15{eKln%6Uqox# zii=ny7P!{8l$k%iNN@7?u`WZ!FfoBJpI&`6Hma{KR{G>9AMTv)uLI^<>ru_f7#OR^~3T zzA(p`$}x0L5HpRLJ;6T>Si@I{|1!`~d?{p2$tU*z90a#kVJECp)1wrRyG8n6SBTB4 zDm-iylT%^7A^R&4&&$AH6#MH?OqVihU8f}ceZgUh$*Bzhkb-Ava*V^*4Omv@FFyh{ zckq7)Khtcb*MFe)IxBN00EVMK@o4{mnS2p^9lSrw$$ndAcy{6j+7sC1gFLJ~xP z8l>+jP$U`V7k}{=PM`#Ur@aYnDvjT??Y*ne&(Ou|-8|^((qRA;i=*;KeN1tNLm)n_Z(ZY*j) z>CgqkxEzYx+Fc#Z;aX7)&V%okWNAC9ynMb-Z(sW{{>^;2t-u3e&;c zzO6+8kCIUQ6X3L~Lp?-{+7r5e3OIhj`P)>ncfUTgQB)5 zkj-#@Jm3YJ&ZdvU_IX)2XNu&DT^r$pBC5eFy&T_Y(GoAe#}hhtlTqdpGQx4}?HSmW zb~QHY6!L?fEw|b*;p5f$5aWJFfoOhpuD0W7Xj1GzA^g;F&s`X892-@Y-XC8a<6&4T zZMU%!8{P@C8@)n^hENqj#!wp#^(7A?yk4fy6)*k?CqgTpC!RfymGR$7Z{AV=Ic?E7 zy@$0vj=QhJOtEEwaQ~54y7>J?`r+D#l=eC64`MoPf0H<-1A$+!nK-qyaYiJM*wF}S52ZNlIf#3MmP-q`EG5| zd^b1V#wlmv9A^pn6GpoO56*NCf`9&zko>~17I}N~EJL6UZO0*|=g9N4+G{l)2VfHG zImucJ$X7Y0Z8=;9iKYzCRyHblWc&OIK-nt3&l4n%9ST;S#^hxI-}IQCNLvm%eRM+O(h0hj6`d6C{v@+OwGM!E=5Z zcO^rDF0Q0ev|V&q*l)CfYxJ-?r4JG~1+Wr$oqm9DaA7+Q%+BFeN34Y4!8mpRK31VF z71;{hPh=y)xZmI#?e<|_9|J}e_oAj9iq2Mfk_657N8r148+dt%-cx&JV-)7&2;NA` z+@-h6nHp+|n8-XG7NGtgIIh4f#E%T?XnJ-5;pr+5SofyxpkJ*xn5P?Il}c6^FG7M< z7Tu2Dy&w^>gD(~M8MlIFf#?qyIepdSjB*o6321 z0+v1UB&`4I89agrZ%Gr2?u9<1un|Hq#?4c@SQK~5X?#azgX=q?vC!)iOyQ*yZ2g3g z#`4DUUY1$H5*g>8X5nrOR|z-rD0Zm#PEwLV%>Bc$IZz-A-Y)*0crJRTMHj&Mey1-$pjkRe`XTe=F7*+neYp=B0f#1-%PnG^REPm+FtV}sTZFJH~eB8{3pf0hkZM$=A&^*SLbA?_2UTpq=< zv#yvy=yCJ~YTYY-^vR2`9I}xRG943ujnKaa$KziCC z>IILod~q=~5BRzc^k6VgjQ{wl6BQh8rw+$%{Uoe!!*bpVXT@0?X*AZV5KZv<1pgq* z;y;2D##->4jT+4`y}W&R&ImVYTQ(EOqwFUjUO=okB6L6!OD2={ktl2%8x-sejwg!4 zH700OhUbpFNyGC449mFxr(k8Az(X8q1ayk$*x2?z(0is_;iSp&W1_ko%hp?uFcWmo>t}P!Zj0V}@ZcEHTmh@Ec+v{;?0rFNR#0%dj&#*W9# zQ|9kQ>phl7wkG5$qTDd~Phta{hX25XXi0D^mOz^3?1N$;LK@E^UL+I;F6gxZYp}jzAa29%YC-o_i+#pK`nq!*&DEJTy4B`?D9&EE80ipf|iSqClk@Ddy2kiW{A%qP@ zGB^0cj{v9X=ih<$=+HTk?S0r#+evydLU+I@v3%zi2=LtGD+OyS0J5OF@)&>@q`MTN zwe5wk2>@k)m6q#$>vC9~krN4PMBC{3IBbj9m~mUyw<6^LlX!UG+@fs9SC{j(UShTc zPwv9$H4@h-Bnu>AT9X$=U@u?h)uL74FDIVP(NSQ#&l7s;O}{EbBotbkJww~N>yseB(zJ&AP&#v+TZ%hbO^2RWv0vytBq#4vkneg|; z52x_vwgwQ>)>67{7Z^N@rHU546uNj*-Xtayq)A(KOfZT4o~D5x#kve4^0uM-or zQKdEO$T;Ifo6_p(0^1kpr8`4faJB)ZK(05flHQPp#<%*%lloue`jVJ1g%gKliQp;m zKkuN$@%?1FA2t82{jP0(*M9$FbBYE`?-Z)h<|;`f%q63B4Pj#0@eQ(#XVSi8I8I0n zCCFynWQk0@g_J%gJb2cB-MhA6iiQZp(7dJqr z4vl3r6!9>8hL$i(-C$*|1rVJ{QZ6CTq=0Fs5`C49I7w>VleTY4@1&I3BKcGHK(gL7 zkZ-jDaHXwnY$L2~?6nMB)Cdw;y+lqWsc92mF5m79A<_}?ut!iI3F?bce9N>~MdD6>5z?QTB&X=98)5em_#mzz2RCdLRzd9@2rMK!tHf9| zJ*A|`MTwU`Kw7n|Q+{M9wJlBX9+`KDfX~UbQMjsYnSia2fLK2(LSp@yJm4b%3>1#K zK+7R|C>GUP;TI2M-*`Bbw``rufE5~3tR;;ND{o9nwe#;C*pu)Qu@6&>9uv znk}nFZ=~bWYXlmds67cqv1MaPQ^So`$*2`KS574Rh^wf24*m%YnIvReBZWOu9%_Z9 z5@@2K9D#TE2KoxPEC}0@ZHWHP4aRDHFsL%UQ9M8M=uwQG8UYFS(Zg70Fy=oOJRXWc zo)rTYW8Ht*d*T#$H#Z5O5+=v2xcC}*|9$hoR|b@`X?Qdd{Revwt|V;;WP8cMYR!5r z>VQ#?jbf<~GN)tp_6_1(M^glujwI@bK+KC~5n|0EVGcdj0L{J!lDneS7IhJUKa)Z- zH5*cNp&ivK;%T1gCzUAxb2c4pZFAvu5I5r@Ov4{85u6Lckfy^Mxa4EYd?)fyx?lXY z^l}utg@nSMep}G5ADg!UTYC}36%0VIGS7kbV$^9xP!CekAx^%P*({)k>G>pOZJber zS?Z#s*(8O~QZb2hqRH5>8hZ^gy@l7~G~9RLObiu|Pi~Ty@TwebPsPkha3Ia=)^;OT zmJEkVMm;UYR#>-D>#K<`Sf5&%QAnk0#y_6+$c>8?_u?aciXOV~lo^3ehE@q?UNrl$qzLZyEZBcb6)OTEjZBXtBLK}9OEXv` z3+i`*^NqHr`udE#4%Wwx@-X%q@xaSNeSZ?ENIN$N(Hld%SKcw@6?TavuEGmQagZk?+fZ*_H{m{xW*|l~ z6Flvr;rS6S)GsFOvs8n7t~1;>DP~&!NU;NE0u+QUq~HUlSZt)`=9L0pXJh)ic2#T= zsI5DLuY~pq*Z|DsZ$*s!Lyr1rj>E+4nSi7)hiPGZC<@!=)ShU^+yjE%wO50&AL~Fq ziUN+hZS+AvN{Zp{HaqGQ#FT+MMdYbT+uw3@(hlZ1B6D5vNH>+T(s|4zYZvj^ye;jm z*B5{23Ba6Q{;*0)Z=+}cw+%>lsU+PYBom5JlQkqqh9Gy{;m|1ovKc_}t3Ch>_Vr3( zkAENS4Lhej76S|7@+6edHqcgS#s_Z$x;{jwcrT$KTel*$5&bu;Vz>nV;&-pH7DWhebW5|MrM$t^Wkq2TT+Q^iI|vkzK6S? zxYEc*I+`=QleeZe5R7{dUkwn9ax!8ALw%{_mf9~H>UJklp503`=4NY6pS+p`EaWg# zM2@bYI*PFS&%zx zzxLuatZKr)FZc#PRj1RBfPt(Ys`slQI@zT)ea9;XS+W9o%aSUT39*8d4&9kjO5Bc8 z;$@Tg(rRMK?N)g@rT)!#!Nf3Oa|2&uPs1{TfEUjYGM;p1VyKo!`zda3NfA*}Y&L%y zO0LUv`CW}ZNa zIZ0TgTEsXR<(amA?nK#x7g(>hqr;pHnnkKhrU5f%`oa~D)_$2jGH18=P+wN_*jY#) zc_`Q^*aCD2url8UJ6aDrf3aW4OZtU|n+R47b)MxgZ%ML}h*H^O*Z~NyTRts*D;Enduu(zF-puQw>Ou(Z7`}tIBCA;CQm{pVz8Gp0 zl{fw4nsJ|i-@J<)^@o%|@hZ_AMi7u82Z6PqupLmFe~?IteLz3EDyd-V`>ObKkci#7 z&Fp2e`p-cqVI6vZ?e#=E(BUI=$*EO#qGUIkG_Qn^YAZYne?qvf86ljb$_jv|LZOIG zpSJZs(ewa&MG`Y3go-j-hCrek%z(BJrk{yPLq9$b+pGUtQa!NcD>ozbrfPLH4#@=g z1cHF2W=JgcIAW=+=~(L7uO}DbkH4B%cGBLz1o0Ha6V?72#{roEx5ZNJD|fDwJcTGQA&_MOKe_ z8PJz>G(hL^e&bg<#FCfC zVxt-U4z03-)4qfWUsT^ek=zGu2kNGhjk6AFJ~p25on22Rl)3H#7oPSEP^!;S(6T37SuAnI1g0`2-!ub`0)}ak#mgvbR{@40M50`btkw&L<=uFU`JN+`02yJU zZ(J;XrHlUn(uKUPK;2LsXR zb5O~=6SPXCl!KGE-hn5NXx5xC^uV|FLO$ew13xT6D^@O z7vB$>lrhl@!d%Sw4-(l|KQ5g%EN3Wi=Vo5oMB zp3Y$jrt9U^PKjISh2egOh%Qb7mqakug87P9e+l5_VsFY;Di&AiZH%G{s`f@QJQ<$f zgE_x_N$xzZ{hd2BiXve|yXUx|mvuFLQ*z}-F0KE{^$!WC0SHmAI=btN!4P7yZ@QZEc zAo?fjvoP{W;;884vVl&!yJ1=QJ=w&+qRT8A4h%qm#=RAMNh2?*vQ0YZtAScYo1W~G zNoMvD7sYCQOF21`*7~Y>>nN3~@S+Sz&TCtD%6Pq3Ock6{N{HyeEd(T8ic%4$VbqGP zMdwDm~fdt!+Ups z-kMSc)%ubGBWnM54D%J-XQlVN#U%Lmug+Q;rdi^tMtrkiWP6BKSIJyDug6-8;$WPps6f94*v( zd&7r$c=cpb57Ys9Lx*DIvw0qlP6Vv1jZrYhImkJNEnUeYU;(w3u3}49Yr2l{-9ysW z@fr9PU4fn&`c%UwIJzN|f`y0APP_jYtq37$b+hekXQ(df2T{`{B))sdNX1*@s7fC* zJg6#mBExB@*D6Py)O7LlR;DRdsLMf@*g#+gM4vr40r6#B!IK>MZa+5Hut+wGXe6!i z8BTm2JC*UjZ+kR&GBl<<3*dKMJKDI&+h{KGMcXCID%g$dA-ft$Rnv_it? z@h=m6mgMX0ZSTP6W#mCje!}!G`U%^f=PB7O(LVy3y+r+aa+KhB@-M&pg-nd1t1IiA zVn0!KjCj!r3LOI@KB*JsXgRh<1h8B+VD=+JPo66Tlu`yYHRCtHB;#SXEs2Ept<2-# zb>w+5ZNKA#2}|8*zLqjEWdvtKg51=TcI9}?-x)k2=3s#xuJNqHHlEGVeU}?)#*Zhg zm=!L@8JxvX2yN3-Gch%N=4rG{f|=o4g7~39D02v(k%2C;btXFAjC7&-o6O`(ZQHzb zEwo0g2!MTJ`>TX<*VZHsj@kKWNu7hb0vsHifa}hnf0;ZFIwToFr7w6K-FgO-ci`!G zq@_z;uh9Jukh?PB5-+<-YRTsU((IG#=PlaStB;BSTyc~{no3ai@Necy)6I^fdOMe3 zf;_gqVkS)FnMpgsw@8*klT)>ywO#8C_4~1tPH?NQbQK=v_Y{C?8-<{7M_#WG%NNC1 zEHr9cjbjo9v5Kuq*l8O)y5|s*{2RXbG2}jp)dhEaF(C5D*YuUW$o+tg`+L2~_=?sl zo4yA;bjyJnzxV~wVbGhX?v+065IG<{?!Zj-K@>qS5M`Ruw3WuZ-1ht4923i(m<2(` z$gw1|f#U*^695T7Ry$vtW30KJjWRS;Ng{>BOxshS?OB@9_ou$s{O21!Z4~{^@II0B zPrJfWe*`I)&kG#O{77D>pU2>5_h z1PtARHyEiUAHj4wSri{}@eKVH%s#5Ms0-@A^7`U$=(d)LaH@r@n!pGZop=EkFxH!( ztHk^_Y!4H{LEX0d4Ed4>Y{b_%9f@N@(BNjDE~~8&)krgjq_>y=ViA1Y zHI^hYNJ*J#-#V|1!l!vq=|QMOw%XU&=%LZ+7TMdsinp#KMg=1wErnZNJ`Zk1MzlhD z=o^7XjN|{7)ainEN*1hXpHn7S){`#$5Tw7+;UaeqD=368@>Z@OS&30$emU`fg`);HZt>C{8JbkAtcK4p3k3{ozAAk<6>?IvGPeQzFB~_^ zS|;qvSsIeHm zld86*7t?Ijpq9f$%1PxILtjzBli}=#i&F702Lyxl-GO6*AY#kX7s4i8Xx4)G%ih|c zrC1AG)&kYa5TAfk=z=V3fm@VkK~Vhg4D_c1m$)@E#i;g+hX;nQKoTYTSo0(C@9?8J zqNiij)9^N#Klhlu2E!ZZK70C=fcViCl9sGe6)It`r7qEfo4!KN3G`c*<91+dO}15{ zN`?|LGyir}{P(u}yzI9V@BclyUt6jRoAJ6hiXrm%fK_-{zkpBCu5>-lSN(z5BAa`a z8+eBNPo(dsRNV9_y~MO?TdjAJ0*pmYa!nru9y1N~_%AWRh5ZghAEx?HBF z4}$$m@|+l_Xzcxv&DhJ%vD@Km5Pmn9?RKXPH-tuKG@K2M&T4o=o(cDc@R-)^Pfw@0&1oTrO(*4fB0J_u?J<4fXfvH9p#i`W#2_nnt9Hj@s)RQ9yIlUd>{$u`A}0E_v%qSHVJK zc+S2I=1CbgS(moOb(L*l(Dp3Ku+;5V<|s0YD0z6cYkRK9i`g!`v7`%0XfzXoRbZ3p%@@jq6Q)|O<0AG4J~*KwZ(4LVvpfqi*Llj{GZQIf2bi7&kd zX9yz+w5{Jc0TLZX6KGAVPS`#P`r(Efh;1bXRqT)8PaP@#lr~qAghx)Ko15Q@+f3ZP zj~KM_V&cvqurTHZjE}Z-JKC6#n~_pj&MoC#Pwjk zL#3cGUzvwIq_+7WY<}x;NseV}g-gJt3w^m*Ya0?TV4gF`$(T?X1qq_w3v>l9GXt5- zb2q^i#60K?wdX*-qW}tVIHp8v7fKB16G$F`Qq*`uNDra$6447}iR8Jr7NHXfC>6Y~N=s za2w55<+Vr%l8Lioe&9J@`yrH^GFK#{3ABwje+U_g%pCD7(bWrLsMTZ6Zi1h;3MBqd zFE2mia6ESnsT?;O!{X7=#<_~a|Ed=0&~_gVbzGZRGi*Bw>xY9^3YJCNS~8n_T5ov= z;Yq+Wav^+3T6pZWzj5d(y9 zq=MuGf`F*j!BdhdWSJiWdLrh1$Ws5^^li7Rk_mb+MuIXX3kd!q@xw9P@ypCNgh9!O zgGMhxkPPiIyWIT{zKZLG49z3xgvT=1v-a<%LPWisjxe*+i+*IULkfAcI0&^<9<|E26qx3_3t;9 zHEW9xkvTPkfe(kj(~h=WhyqWeKhQ+fK-;`)mJQ;Csko)GX#Ql{49fvWL?{p#YM>s6 zx8|b9%2E=>49@_$t}M`A%+g*gQ4H@jN;?lz1Z_?->UDUzfI@5u+z6GvE)_2!XTAPQ z_5aMH;6~V`ZpHQSY?(v$-dAH&Hx-WOjVm2o-7<$P$T0;je7&h~G;h>zpw+uLTWi`r z+g?{?)Ze>q8;`iLL5?HFj+H+DrMe#p;7+|@mxg~R_(cmmV(GLlIczI*689dK@#rB$ zuZlCeDj7ZLC!(k;hwbSR`nL9)vm5d7556U2Rt(cMN^J)K@drJ;QKwcf_mNm!gL~>8IW+o+zci!X%>>V_JmN3AKcnsf z4S}~7qpFVb!}MM>^ZJ}&7diob))_59F6Bpshwb~Q$RVAWOX-NxV|G~T`rs@}-Ixpk z7$HVM2<&KsL+<+8!IPqM%e!fKc2Yh7-WZ5wXYlFJct*p0Vxsf`t~!u-JSv-NQ0YJc zrsStoGMO~+<-eO*{UbO$n`s(43IZd|UE=<;?-#&P^PtmFcvw)38i+BN7Pw*i$GIuZ z1e!E(9Z=#XM+di$x1zF$>^0}&?l!bZ@CD^$n~~-LDWPU1qt|;UrM{lp5mIV}kkkKl z6V}Ecj$|D-F`E>Ank8$4RA15r2N1Q?7aBfF3P>JqoFt_PfX^d%ziv!wyYYTqWPWS{ zXa{BuCG${lbk<==EE98o55);IYQw*SJ?5tx{|akosGk#Sn)v6xNVQXmU^w)xgLXOz zNjT8U;?AitA%^>{%n9-6&UJ#s(erixaGPTs?5Z=<4+J?!nQ7lA9X~uXY~>-3=8!&i zs$l`SMWA9Xua|$`#btc*pyB<3;r)CH|4!?rqI3fEOdW%<;Ome>i##rOa12LyPX~B2 z(}4lqxGE@DW1PoEFr*0~@K<(LiK?~c(_W<5(rn#67#mE~-fm^?g6|u_tS;o5R12G~ zbrbv0n@nCan3xuTPEKO)3O%0|%b1iU+GYYhefPFuIdo~Jwy2YJ+K$)|RSs~L7(Q-8 zw%$`)M2;JIqokbZ$A8V)2j3eWh}@0>02n81@=O|Z@(x*Z0=xs(D2_Q{gpHB4z5#Rn zI2d28Opj=EooB#g;q|eBYrZr9E7bN^4yRa+ z;sIp6hbY@eBJn)_Bqfq~j9QWn&tncr=^K>t@vEKroC`ITrtOzG&127V|KIDe_le&m zJ@z);WgkRxrb;}FotT$--T}Q#%sgiMkHvL%N(-s_L}DRoux*D!8uAt}OSGb0 z??Q0K#bdGYE5vTqySg?Vl%8LSPoJ<^Uw>EqwZsZ*dpzGsIYgmWUqNLzXyD(NX#J~c^k7B=pS=ph6mn-ia@w#{wnZrku9O%2_eaT=WCP^Z)KF11bY z&k1D&#_)b~NZc_+V|%Z_Q8D60oxm7oNbLxdIhNpPCa!yv#3O_$Ckg-XC-LRJG@Fdl z?k6kJ=Ds(Q1QC*Z+Aa_|NkZ!9L0P&*X*p%TbAht~UEUdLUrM_DCnqnr ze?PPl?x1lIf6hv)5{D1t3ZxHj0Sc_`6I*BIMTwR*#*? zwWvvV36m^Wh}R{njn1(k$>4B?D9MzV)OL8D2wgx;-L3=ZGU1+w(OR1BIf#*cNZBB= z2ONLZ`x5UQ01CSt`BQ%sDGTMCi9#%!7HK!C=Z&(mc@uQLLh+2Xw~_3|TR~78zM5Br zR5nvI7doScMyG183Vl~qf(c%+Q9K@go#IjEQLqNa+%eO*Z>s(}va0Yf_U8RQBV4nO z{5O*3>9lCS#D5&HO0cSl}n8;|wC4rEW+X&La2xIe(dk)|FBFS9>0?clPe|L(E3?cHPk+{1X;1i5GZ z^)Y|EDMf+tIQ`ukeNF#FTpZg@t?6TNsoGqN2J86c{DiHH=zirr`H8*de=k3A>c5lx z#2t6o{DjR!*bIT~tc`oT2lULCsA=$w)suK?6vPV5eI_%WB|O7ZQ|r-K+KptUBAF45 z6nOc;Y+-I9@I;uW=gn6lF`G~l17X}UU!YCbflB~FQ$bg^C*TktDBNy zyNpFf^GL8S@%7GRls6GFP#u;{lZB(UwfAqx!t$7$i;q9^{~{6BtR;zrN40Az|7{ts@s-^9iU#+uT%n3%Q+?+y{4om>d~N|R z$vgMrgO!4B(zbTMgBS3@48b(s2}#p59rL!9`O3l4^d@){JW#>13ft}6uq}7q^ilZY zB`35ANlNd`#RoI6&D){P9DML?X!9SSsAnhJtZn5kcHde^@Oxh!FLyDH>5a?XjAOdo z@+`)ivEX4G6Nr^(GmaPLmU|h;82x8P{Sf2NMmKv(l2pKJaIQA4b(^Xgo{X^iznhC@oI>>Ydd1+b#hx zN8U;1gM$R$4-~Vk#HM%PJ{4>%1kpf=NA33D3d|*ny{=pC#b$F758CfTqcgQlMffy3 zQIZ@{exgX0jjE~8xLBPmtm8^}-$~_fzm|VpbJ6?+YDZ_AY zG+vkmP;a<@MVZR)O=fN}%3Q^UTi*pjS7`;_fdP4oKIepm77hKgOaF6&&+z=(Q17@n zsJtrePv~C?7bH|oSTzOURC=~6bVSPWU8U7{p+qS~o|Z0kfLL0(oZhXVyM`{mk628# zAaT!x^jD;Fm&YF{0AxU$zY}Zv$q9QgiV`24u-8|-zmi`oUVFr&He}G;6B1q!y=3uP zyy*9Rvvz;F0$dFRXbi}tTQA{dy{t=XdLGmNsq9>AXr{K~s8O9!EE7y?I~JzW-gtdV zuk=`rF9+SrLN}YozOAxvyShrfNR3K!ux66(Z5{A88_!BpNA1i|y<5?mU;;dNT*mMl z3$9^HdhPsApT)S6b6o+{==_*{)x22mX2%NqS>QC}hc2Q>(|}v78MMX%L)w;ljG#HL zPc?j$*Z1;(sl3u+WqNKE@D)=brTP2`!I`(4`ziVNE5TD@aDs2(fzx_>!;QS&WQPjd zt;}rrqFpgHXZ?_Mo${tXa5|WP+>afqf0;{+3D&ydYvN<*T5um+%-g+vU5E#ci-vCJ zfnK9nVZD^EUiP2Xxj7qpu(FkNVhn@4@}Ou*?-2vh^lwstC-t;0Lg^*=SG#TJXa1ln zmJI4&uu9a1vch&uzlWW`)s?ZqPE*|=I*OSG#D52AGRF^E2Q6=>bpZ8_HJvI+OZ$Ke z5gilAz5_nLkAKwwuY!Q$a! zX}R~YK%0H{biG$p+RGREV8irv;%Q!Ys6IPG{0s`P@CdN@J~)flXDe*kk*>gTG`i}K zD)7vcA?PyzP336;DsbuZO^Sdqka-S`vSOd%Ue5!$Osr>R7OHguKD>#y(v7N}z+Q}O zse}xf*%)O}*@oBmZT|-FF?->n+{%OGVwo-AShSnNm-ys0ejd1pSs*gL#AKDG)CL)9 z3t!UfT(S#TUQEB?7L4 z2iYV$!2$wqj{qWoqts@&o5c!OrsbQUnLIGpuI{L9Q>o4wDl`1Z;_B3B+(DsWuv1Paln7$#fN&VpuFpxbt=59|c5 z$-oQtV0&S(YO@%%m<0w5YftbTJg}hFoU3wm5+oNV$eiFmcDfLjQ22 z?k~Jx)2F{Wf0I9yoc}?4{%#@2N*5kN;S#PjSj7k81;bFeah#9R99Wnf?M4*1`o0to7gsCiH}h z<$5ogp-T!7q#U@Nx`rG0vb7hhc;IrmAAl#c;Vxi?SNv?a+HkipBl``A;AaNhuf+}M zMcZ-6C~7g(dtyVGthIZD(&T)fs^K2xG^*7_e5ofisj}9+@G@eGf7fYxe{dGB znhWtZPQ2nA>awSI!52$~oDSpnFLeu2ZEB0|cJo&F%zsX+*vE9}jO#QA9Ts7_oA``7 zC|53^GG>g9VDg;;D>Dav>u=-7FciJLzh}TIyufvA+pI5PZ*ij?n|)R3RgM|zdc*Sr zPEAPvBbVhcPo-tFpyX(;Q$Msa#@z~f-}qzeo`N_Xn3>+gOLDa>e#{C7JHc@sy7c&n zEh+bo*p?>j&-*17X&XUTS@>D}B^DimpHcYfkD54*w&c!g#&6Ie2HTDTd}w<ZIzGsOuU6#MO;P;Y(N)=rx{W^uUQL;V_{$!9RK)rn2Dw@La$<&x5A@G zuvPpKg^~JcgY{XIjshFSKCvd7pUd@wxK0>oc4#zj6lQ{O&6}bC$(T>e0~a$Qt!uv< zG?BPL3za=`gO2bhHo6cdk|SgPe0*URnOE?f2{H`y*TC~Yx5nAAudo+nRxw9xvkD#o z)yKmGX#mLa6&FDzyekQMG!;A`m4$sUk?43C4>X8kz+q)T(O#jmpPHu$Ra8Ww@|l*h&Vq~v@G z2$Jl(oAj2E^bFMh^GWh!92!aHo-SY!oKgglO=&UHpMkme9vWxir$+GpZSn6#)2Pwo zZGctsdKuQ0Ln2&Yc&We0bFm{PYpF&&+ zJN2AHumpLR^2X@^7~Y?-ND~&0LdYPl35ztR`h0F`hQl#Ow)acy9?u?mCxwPp7Tt`$ zWu_QJq0w4=lDXGui~NB8|8ccupTjY${l)rqGi@e6hS6#dhDBEjA>0mWPKB zYh43URHl=_2m!~&Oj^?d74v6$;CjMr?0wsa9aO!`20O%7bTK!qD}<(x-3!)D*gFcy z-DLx2vc{fLI0#RTP)3riDun$JMDQ>y4m-dNST-^CxK*}(Ipo>4$~G)VK2ZF?%R>4S zv{u^27JcKmk~SK+uA z-z-cHVMs5HO;A4eY4#woV~R8$qeu?J%d!CEBGcI zbDB8eHh#ZPjIJ7j*WpWhbCK~Ust$Q1F{WDL5yV~FU{j6LsihGMGmv2~448QA1#mls zB$t-&4Xi#f9RGPMv*^~eJkJ|v;_Zaw@3S+5oa0b{qfyT<9ln{y$RUtsdh&&N3;@N@tDg!fa;{G;#fwjhQXB%;&c(@Mt6c1K} z7Jnm;z^7nxOQ_ZYb+8AnCxknN;k|&&$FU=^WAm`p;6aXUhLBt;GSnAo$(Cad8>KB-OOIHRSd?C;FYE2l>m3k07l{jVR8^HDmCllpIGU&ogws_B+fu|qldmW^4 zB^H9vwb*Jx*}yOwdhTB+=?|!Kp_PJ6*^2nK@-By?tv3T=(R@hPabx0qv5zPLkpZ@_ zAn^_a&LR0o{QDSK@6B_Gf11GFvXNu~AwVEc;gf?&eDX|^jI|Mtz*G5+dqLrqe=9^; z!gG|0O~Z$08U6+Tz72HLB$tp`01ze)*dU~TMbR-ddYzEPMB~(H+vRjJJ~v=*3T(xd zmtcm8=q1}ZNZa%UnOQ#Z6b< z-t0_(Ic-Ph!$w)}hlJqOIXrvX{j7=oi+ZL*7WPEAw;-^E!)OkF6#)B<=r&whZIR&k+&w?CQYkK(-kAAqeN82slEPDpRSs+YOh&<8dnBZ6?vB%?N zOLjKQGCaRkdfAd+vcN95Rk_jy8o!QEeHP@U2*s*pGBRT&`g&)%IvBbTHHW=uI^KnT z-YY2!2(FyRUW6jiQn+2m_?QKAwWdXIV-YU0w&NV$@|0<)I~6gmI=Xdk7245%0zU46 zEdG$k@V>&@wy?}6x zZ-|P<-P$~TDJBqpU88*WzGO&HuANSt(oP1NLi;e&<#O?%zZJjQdXokJC{t^*{?O#yFvZdV$^&>VUg9~{$**8 zb!xl&^DGvDTV`10HeT82H`Zb_%IzAY>%_LY0$|T_T-RTCfiiP0YvB>7HSFQx8npKQ zI|Q&TYvfB>8gdPH#=OdHYfeiYLA?4pu|oS`cvl8DLl(}39!S2qmt(Jbf9)+|wK)dQ zC-ZIYbOttSyQ?zhW@-Ai*|5S|^dT=_?4gcBZwUyPImDMV`ujAa141T@Dm!^*4K}o$ zN3h_1j4x@DxisIEL$fpZMrfbY-d+anpcOZn%(?rckioVt&G(^*JUiSx*o2M`m`BCl z$V4+{V*cSrQ;|=_D6%b`lDFl}rQE>rn?48tlqDnISO;I$Opwu~!>VA)!=h3EgkUqJ z$Wrz>squ*(>}X;C@XfY9Z^>q(+?97! z>GQu?|1q)k7>44%zTrl^YD!G<3m*c!xDARQhgi4DZF*0zo4v(x3PSk4vEh2&3S)W} zQxi@)waS-`&rcCNh62qQAsuR}Vk)6Pi|TK!Mr?Bn%=IYbJ4-toH~fRs@jNE`+#Bln zI4r*ZEz!BQdCN>pDjokNWQ{WBCf695nS_!TYm9m^MDrQ}hXMjI%T%|vWhQ__7<;fo z+Mc~tCe4C?dz?i4ziv(KwMvnK<&s*J$-gCt&Fg%{0usfcm@7CtLIDNhR}mKrRO`#d z>j5ZjPrea&3M6kM@FYmyM&NN2uv;bQWs$2mI^Zm8M9-VnwNo-)5D_#8HVuGNs3W@N zr4Fwh$cFCFjbxR~5)7XeUZCI#`{UUCa1t=vl?l2!lShDf92(6t;SvZU9RPx5tQ&I&$SX3uGzhnE_kI@14MeRR~B(Su*JGaj}|sj<{G|-HTIv zo)S%&G(1G7&9p$yK(m-8{=1o=O-!^}>?ua|iP=`bWzQUgb}-MF*x@=~2__grS8qr} zML>r+#t2=)t{X-4tbiL{D&=#Gn}Yme+;C9I$BoqlR9**(MmaoOZD)9bn<8LKmo%cb z2~i`$18$_?ljJvQyx{A|rAcBq0~9KeI!r6I5b{Y;s_BQo*@kE+CY0*LWYf04k!L#O z{B?>}Pz61d5Pts%U5BXmH(bZV_;Ih{`S+H~vp2D~jLMz7#77RkCANbvUQtQfS=R@m?HN5fg zIStX`;^NS{5>2aos6@=3uko?P#k@@4$sQ`9tYPI-GHckki!o)`nhMMpwx$Y_g;@*B z@FKj0Xn}$E`F18yUbKlBtB|*A!6aDgrzOEMgJ*`FLSCe0E<7y8k0G4x+Lk@o?kc3r zq}W>0%)@Ij@3@NxHXB}-v$CbIo$^a$77MYXOWlZUm?va;*JCXAx<83c^+%BBUeesK zfEtXQ5@d}=oCPhpvz$wiB&Otj*zUoqknOj3qGy0`+bqajCQgwryF(^i;N-ch797Pslwf*elUUt~hhzk1yGH4mIvgHl9ti8LtDd(O?$gO1GpHwP=oTrADEAPHbNd z3?WK+eVPFOj>ms|8X!4`js4w6A^z(DJ4=oPY8#wW_GDYQ;LBQ49GF16+UCd3Lm~{D z5#RDXC#ipAhI&;6W0lyTduQ7WIz`1L+4Pⅇ1p+pdQ)u;Sc{UHl6K@KMEPq0RP}} zcW9eGC%`PR0pcnn@u!~6DYRbuflN_FQfwZ)8C>JMyWju~!_1>*x|qHtU$FUZH-7>h57?Mb+3(=d+f z^xM;q&T7FcCqDlcTxs8=q#ai6iOzWSEVwC+;TcaqfmuT!V)tlGGbZeNhngeaaI*k(59_e0?Pb^Gs3(3;5rf7WWDDS6GrBjYKHCj1N!E2LVqkaxRR)(E( zOG1_hKE`h(T@nJgv3dxS(J$N9AJ}Hjo_nhu%bRebId+;1yf^#rI$VGJ4j!&8+3$6@ z#CYI*b&7*^!wj%<;X&(2Ny3TTw`}_|`3HMB;Kv$Yf%FfC6eht)Z%=Ru09^iBMeSq@}&pqr_ zqX_j-yi|?7o~c|ks*iq1svKi*4Sb!mh6hyJE6{$U2v%1&(Xleuc4nCeTAU>=L%l|C zZ^$v+N71d4y`_v1%VN7!Wdo%f# z7Pb%XOZunI1^-i5%K!8o^h)%IIzK~yN_gLd`RlI**XiNScYa7LVC@p}9HxAUqL%H1 z`XYYrE^JRMmp!8sVnR?C@Xr(i4;=69v}ixR_`NKqh_^*kN&imKUu~V>SftM*^qKfT zlAodXHT;2Gd@&(=7thN113CCCp5{+X?;7%PZgsb^(ri(oYck~@OW(TDM_0T8Mv7cU z|A_u2|2u!tD{hhgqCb)TqEExXyA02xq=-&)3zaaiPwJ!53+66RC@oaMLDa>*?M`}s zk{!KNmK8DC0!9-#`J%gd;9RHs%v39CvyS=4(>sx8a0*J&h49#v^Ue{wwWfj!DJw92}DUG z)QobyluNJlDXkgBnhD^^D7%LfxUIH$FMizCdtcjn8~VzZie@GW`6A#XK{$tm5HZyZ zgM3;tiIKc(t$k)PQ2V^U_j&*M=|g7EoPGAkT5GSp*52zw+{)#d3o80sV325!m9Oy5 z=ohE1=0CZB^|HbmXDJ7Tvea3MMQxd+$~1ANeF>E|3_5Mw$0IPzQnkng$+PAWfg}7u zx~I}v%9gfUY%`(r#VAFiR{l*)nGNrzvqs!aP-o<0&_=NeZy9G-CzN~zq%oPs(95>` zYnqwgR^3beI5e}LOn0AZYxIQKuUh!KV<+y2x;hKxZ)vvqOqnYY^_D6zNp%pERL3_x zk)NJ(8PtjU&}zQcnaP^}auPIby%XrcJ`{FE_)jL4wa!vWIVaONYnLa7qJ2-ISD8i` z%FR}7n%TH&^8jj}-ba=t>?!nLpq5;bL|ZUVd&j~_9K8Q`D#q%D>1%c0h~oi@w)i&5 zJ%GRBd|Jl_?l4@PK!LnhIVJT*fvtF3*j|9rm@XZ6bxUFQad+ox0D_%0A7{-Gn1+2d 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�JhjeX~FdYcGA@_0J}{@M@@mFG(j4>V>;w} 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≪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 z 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�ggG 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 ie1wA4?^Yn9m_%khyPj;a-~ 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�|h-|zj*;OI+c?*30G=$_$! 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 Date: Fri, 8 Jan 2021 16:19:09 +0800 Subject: [PATCH 266/705] Release v3.8 --- CHANGELOG.md | 2 +- bot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbc9a029b9..fe8852c300 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.8.0-dev8 +# v3.8.0 ### Added diff --git a/bot.py b/bot.py index eff4000aca..4641e2dfc2 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.0-dev8" +__version__ = "3.8.0" import asyncio From bb812252eaa9dc6dbedbcb3049a76d8086288dcd Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Fri, 8 Jan 2021 16:20:47 +0800 Subject: [PATCH 267/705] Linting & Changelog --- CHANGELOG.md | 1 + core/thread.py | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe8852c300..5db65bcb35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Sending files in threads (non-images) now work. ([GH #2926](https://github.com/kyb3r/modmail/issues/2926)) - Deleting messages no longer shows a false error. ([GH #2910](https://github.com/kyb3r/modmail/issues/2910), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2910#issuecomment-753557313)) - Display an error on [Lottie](https://airbnb.io/lottie/#/) stickers, instead of failing the send. +- `?perms get` now shows role/user names. ([PR #2927](https://github.com/kyb3r/modmail/pull/2927)) ### Internal diff --git a/core/thread.py b/core/thread.py index aed4275abc..75dbda5739 100644 --- a/core/thread.py +++ b/core/thread.py @@ -898,11 +898,14 @@ async def send( if is_image_url(url, convert_size=False) ] images.extend(image_urls) - images.extend(( - str(i.image_url) if isinstance(i.image_url, discord.Asset) else i.image_url, - f"{i.name} Sticker", - True - ) for i in message.stickers) + images.extend( + ( + str(i.image_url) if isinstance(i.image_url, discord.Asset) else i.image_url, + f"{i.name} Sticker", + True, + ) + for i in message.stickers + ) embedded_image = False @@ -912,13 +915,15 @@ async def send( additional_count = 1 for url, filename, is_sticker in images: - if not prioritize_uploads or ((url is None or is_image_url(url)) and not embedded_image and filename): + if not prioritize_uploads or ( + (url is None or is_image_url(url)) and not embedded_image and filename + ): if url is not None: embed.set_image(url=url) if filename: if is_sticker: if url is None: - description = 'Unable to retrieve sticker image' + description = "Unable to retrieve sticker image" else: description = "\u200b" embed.add_field(name=filename, value=description) From 68fa13aabe1e2b7a821ed1e85f79f596e38c471a Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 10 Jan 2021 22:23:25 +0800 Subject: [PATCH 268/705] Fix bug when sending multiple images at once. --- core/thread.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/thread.py b/core/thread.py index 75dbda5739..fcaeb025f1 100644 --- a/core/thread.py +++ b/core/thread.py @@ -915,9 +915,9 @@ async def send( additional_count = 1 for url, filename, is_sticker in images: - if not prioritize_uploads or ( - (url is None or is_image_url(url)) and not embedded_image and filename - ): + if ( + not prioritize_uploads or ((url is None or is_image_url(url)) and filename) + ) and not embedded_image: if url is not None: embed.set_image(url=url) if filename: @@ -930,7 +930,7 @@ async def send( else: embed.add_field(name="Image", value=f"[{filename}]({url})") embedded_image = True - elif filename is not None: + else: if note: color = self.bot.main_color elif from_mod: @@ -940,11 +940,11 @@ async def send( img_embed = discord.Embed(color=color) - if url is None: + if url is not None: img_embed.set_image(url=url) img_embed.url = url - - img_embed.title = filename + if filename is not None: + img_embed.title = filename img_embed.set_footer(text=f"Additional Image Upload ({additional_count})") img_embed.timestamp = message.created_at additional_images.append(destination.send(embed=img_embed)) From 8d72b79cec09ec93d8f1e8b49358907f69801761 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 10 Jan 2021 22:25:43 +0800 Subject: [PATCH 269/705] Fix error when reacting on confirm thread creation message. --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index fcaeb025f1..9baa0c921c 100644 --- a/core/thread.py +++ b/core/thread.py @@ -658,7 +658,7 @@ async def delete_message( await asyncio.gather(*tasks) async def find_linked_message_from_dm(self, message, either_direction=False): - if either_direction and message.embeds: + if either_direction and message.embeds and message.embeds[0].author.url: compare_url = message.embeds[0].author.url compare_id = compare_url.split("#")[-1] else: From d19adcfab8588af2fd325d2122064e4d27885caf Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Mon, 11 Jan 2021 16:52:37 +0800 Subject: [PATCH 270/705] Update changelog --- CHANGELOG.md | 8 ++++++++ bot.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5db65bcb35..4407575641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.8.1 + +### Fixed + +- Additional image uploads now render properly. ([PR #2933](https://github.com/kyb3r/modmail/pull/2933))) +- `confirm_thread_creation` no longer raises unnecessary errors. ([GH #2931](https://github.com/kyb3r/modmail/issues/2931), [PR #2933](https://github.com/kyb3r/modmail/pull/2933)) + + # v3.8.0 ### Added diff --git a/bot.py b/bot.py index 4641e2dfc2..3b2d228505 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.0" +__version__ = "3.8.1" import asyncio From 80010ca5704f22f711060f65f97e2de50eecb62f Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Mon, 11 Jan 2021 16:56:31 +0800 Subject: [PATCH 271/705] Autotriggers no longer sends attachments back. resolves #2932 --- CHANGELOG.md | 1 + core/models.py | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4407575641..cf57a18a7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Additional image uploads now render properly. ([PR #2933](https://github.com/kyb3r/modmail/pull/2933))) - `confirm_thread_creation` no longer raises unnecessary errors. ([GH #2931](https://github.com/kyb3r/modmail/issues/2931), [PR #2933](https://github.com/kyb3r/modmail/pull/2933)) +- Autotriggers no longer sends attachments back. ([GH #2932](https://github.com/kyb3r/modmail/issues/2932)) # v3.8.0 diff --git a/core/models.py b/core/models.py index 66965a6d88..2f71f0f202 100644 --- a/core/models.py +++ b/core/models.py @@ -227,6 +227,7 @@ class DummyMessage: """ def __init__(self, message): + message.attachments = [] self._message = message def __getattr__(self, name: str): From 2efd4a50b857ca90af045ef0b22bf9521bd655b4 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Wed, 13 Jan 2021 19:33:55 +0800 Subject: [PATCH 272/705] Fix `logs` command without argument in thread channel when the recipient is not cached. --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 29a3c79df4..ee109420af 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -680,7 +680,7 @@ async def logs(self, ctx, *, user: User = None): thread = ctx.thread if not thread: raise commands.MissingRequiredArgument(SimpleNamespace(name="member")) - user = thread.recipient + user = thread.recipient or await self.bot.fetch_user(thread.id) default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png" icon_url = getattr(user, "avatar_url", default_avatar) From 232accba33a700b48cda451980774fc7fe188cc5 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Wed, 13 Jan 2021 19:44:18 +0800 Subject: [PATCH 273/705] Fix error raised when recipient is not cached and reacts to reactions in DM channel. --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 3b2d228505..54006ad8fc 100644 --- a/bot.py +++ b/bot.py @@ -1153,7 +1153,7 @@ async def on_typing(self, channel, user, _): async def handle_reaction_events(self, payload): user = self.get_user(payload.user_id) - if user.bot: + if user is None or user.bot: return channel = self.get_channel(payload.channel_id) From cc170010782d7436f2198efddb01c08d5e010e7b Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 14 Jan 2021 15:20:59 +0800 Subject: [PATCH 274/705] Fixed bug with update notifiations --- bot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index 3b2d228505..0986880004 100644 --- a/bot.py +++ b/bot.py @@ -1519,7 +1519,7 @@ async def autoupdate(self): ) logger.info("Bot has been updated.") channel = self.log_channel - if self.bot.config["update_notifications"]: + if self.config["update_notifications"]: await channel.send(embed=embed) else: try: @@ -1548,7 +1548,7 @@ async def autoupdate(self): embed.set_footer( text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" ) - if self.bot.config["update_notifications"]: + if self.config["update_notifications"]: await channel.send(embed=embed) else: embed = discord.Embed( @@ -1559,7 +1559,7 @@ async def autoupdate(self): embed.set_footer( text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" ) - if self.bot.config["update_notifications"]: + if self.config["update_notifications"]: await channel.send(embed=embed) await self.logout() From d00b562a8f34d4943272cc3e499b1c7c10f57e62 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 14 Jan 2021 15:26:51 +0800 Subject: [PATCH 275/705] Retry with diff name if channel cant be created resolves #2934 --- CHANGELOG.md | 10 ++++++++-- bot.py | 2 +- core/thread.py | 33 +++++++++++++++++++++------------ core/utils.py | 5 ++++- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf57a18a7f..ad59acb814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.8.2 + +### Fixed + +- Retry with `null-discrim` if channel could not be created. ([GH #2934](https://github.com/kyb3r/modmail/issues/2934)) +- Fix update notifications. + # v3.8.1 ### Fixed -- Additional image uploads now render properly. ([PR #2933](https://github.com/kyb3r/modmail/pull/2933))) +- Additional image uploads now render properly. ([PR #2933](https://github.com/kyb3r/modmail/pull/2933)) - `confirm_thread_creation` no longer raises unnecessary errors. ([GH #2931](https://github.com/kyb3r/modmail/issues/2931), [PR #2933](https://github.com/kyb3r/modmail/pull/2933)) - Autotriggers no longer sends attachments back. ([GH #2932](https://github.com/kyb3r/modmail/issues/2932)) - # v3.8.0 ### Added diff --git a/bot.py b/bot.py index 0986880004..bd9f7eff1e 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.1" +__version__ = "3.8.2" import asyncio diff --git a/core/thread.py b/core/thread.py index 9baa0c921c..17eaaa34dc 100644 --- a/core/thread.py +++ b/core/thread.py @@ -125,18 +125,27 @@ async def setup(self, *, creator=None, category=None, initial_message=None): overwrites=overwrites, reason="Creating a thread channel.", ) - except discord.HTTPException as e: # Failed to create due to missing perms. - logger.critical("An error occurred while creating a thread.", exc_info=True) - self.manager.cache.pop(self.id) - - embed = discord.Embed(color=self.bot.error_color) - embed.title = "Error while trying to create a thread." - embed.description = str(e) - embed.add_field(name="Recipient", value=recipient.mention) - - if self.bot.log_channel is not None: - await self.bot.log_channel.send(embed=embed) - return + except discord.HTTPException as e: + # try again but null-discrim (name could be banned) + try: + channel = await self.bot.modmail_guild.create_text_channel( + name=format_channel_name(recipient, self.bot.modmail_guild, force_null=True), + category=category, + overwrites=overwrites, + reason="Creating a thread channel.", + ) + except discord.HTTPException as e: # Failed to create due to missing perms. + logger.critical("An error occurred while creating a thread.", exc_info=True) + self.manager.cache.pop(self.id) + + embed = discord.Embed(color=self.bot.error_color) + embed.title = "Error while trying to create a thread." + embed.description = str(e) + embed.add_field(name="Recipient", value=recipient.mention) + + if self.bot.log_channel is not None: + await self.bot.log_channel.send(embed=embed) + return self._channel = channel diff --git a/core/utils.py b/core/utils.py index 6803b97d1e..b34d253baf 100644 --- a/core/utils.py +++ b/core/utils.py @@ -339,9 +339,12 @@ def escape_code_block(text): return re.sub(r"```", "`\u200b``", text) -def format_channel_name(author, guild, exclude_channel=None): +def format_channel_name(author, guild, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names""" name = author.name.lower() + if force_null: + name = "null" + name = new_name = ( "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" ) + f"-{author.discriminator}" From 0ab4eafff7cdea072225a893896714037a8ecd7e Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 14 Jan 2021 15:31:19 +0800 Subject: [PATCH 276/705] Retrieve user from Discord API if user has left the server, #2935 #2936 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad59acb814..bf81e46645 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Retry with `null-discrim` if channel could not be created. ([GH #2934](https://github.com/kyb3r/modmail/issues/2934)) - Fix update notifications. +- Retrieve user from Discord API if user has left the server, resolving issues in `?block`. ([GH #2935](https://github.com/kyb3r/modmail/issues/2935), [PR #2936](https://github.com/kyb3r/modmail/pull/2936)) # v3.8.1 From 9a8f61e7b1272472861562634eb19c278e3e13f3 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 14 Jan 2021 15:32:44 +0800 Subject: [PATCH 277/705] IDs in `` commands work now. --- CHANGELOG.md | 1 + core/utils.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf81e46645..e32f44d20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Retry with `null-discrim` if channel could not be created. ([GH #2934](https://github.com/kyb3r/modmail/issues/2934)) - Fix update notifications. - Retrieve user from Discord API if user has left the server, resolving issues in `?block`. ([GH #2935](https://github.com/kyb3r/modmail/issues/2935), [PR #2936](https://github.com/kyb3r/modmail/pull/2936)) +- IDs in `` commands work now. # v3.8.1 diff --git a/core/utils.py b/core/utils.py index b34d253baf..5f88c21e80 100644 --- a/core/utils.py +++ b/core/utils.py @@ -47,7 +47,7 @@ def strtobool(val): raise -class User(commands.IDConverter): +class User(commands.MemberConverter): """ A custom discord.py `Converter` that supports `Member`, `User`, and string ID's. From a56f9479272bc6ce2a9e202663dfda9f89896ae4 Mon Sep 17 00:00:00 2001 From: Ayam Dobhal Date: Sun, 24 Jan 2021 19:04:12 +0530 Subject: [PATCH 278/705] update version in discord version error string --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index fc0a607068..37148cb2bc 100644 --- a/bot.py +++ b/bot.py @@ -1590,7 +1590,7 @@ def main(): # check discord version if discord.__version__ != "1.6.0": logger.error( - "Dependencies are not updated, run pipenv install. discord.py version expected 1.5.2, recieved %s", + "Dependencies are not updated, run pipenv install. discord.py version expected 1.6.0, recieved %s", discord.__version__, ) sys.exit(0) From 8b893bd12fed422811d7b784ee2a9a5b6da811aa Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Mon, 1 Feb 2021 16:09:04 +0800 Subject: [PATCH 279/705] Hotfix: Corrupted data no longer saved to thread cache --- CHANGELOG.md | 8 ++++++++ core/thread.py | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e32f44d20f..d1d6209f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.8.3 + +This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 where users were not properly cached. + +### Fixed + +- Corrupted data is no longer saved to thread cache. + # v3.8.2 ### Fixed diff --git a/core/thread.py b/core/thread.py index 17eaaa34dc..ca6d255c6a 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1127,7 +1127,9 @@ async def find( ) if channel: thread = Thread(self, recipient or recipient_id, channel) - self.cache[recipient_id] = thread + if thread.recipient: + # only save if data is valid + self.cache[recipient_id] = thread thread.ready = True return thread From 308d6694156c1e182332b15fe1ec044f6bb5388e Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Mon, 1 Feb 2021 16:10:35 +0800 Subject: [PATCH 280/705] Bump version --- README.md | 2 +- bot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5741f1db6e..74e37838dc 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 37148cb2bc..447d41c6ec 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.2" +__version__ = "3.8.3" import asyncio From d81e67b9c3fe3efdbcfe98134aa4df48eed0711b Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Tue, 2 Feb 2021 20:00:00 +0800 Subject: [PATCH 281/705] 3.8.4 - Another fix attempt --- CHANGELOG.md | 2 +- bot.py | 2 +- core/thread.py | 10 +++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1d6209f17..ebf7ecaa3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.8.3 +# v3.8.4 This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 where users were not properly cached. diff --git a/bot.py b/bot.py index 447d41c6ec..aa19d7b3d1 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.3" +__version__ = "3.8.4" import asyncio diff --git a/core/thread.py b/core/thread.py index ca6d255c6a..18acc88c7a 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1092,7 +1092,7 @@ async def find( ) -> typing.Optional[Thread]: """Finds a thread from cache or from discord channel topics.""" if recipient is None and channel is not None: - thread = self._find_from_channel(channel) + thread = await self._find_from_channel(channel) if thread is None: user_id, thread = next( ((k, v) for k, v in self.cache.items() if v.channel == channel), (-1, None) @@ -1133,7 +1133,7 @@ async def find( thread.ready = True return thread - def _find_from_channel(self, channel): + async def _find_from_channel(self, channel): """ Tries to find a thread from a channel channel topic, if channel topic doesnt exist for some reason, falls back to @@ -1151,7 +1151,11 @@ def _find_from_channel(self, channel): if user_id in self.cache: return self.cache[user_id] - recipient = self.bot.get_user(user_id) + try: + recipient = self.bot.get_user(user_id) or await self.bot.fetch_user(user_id) + except discord.NotFound: + recipient = None + if recipient is None: self.cache[user_id] = thread = Thread(self, user_id, channel) else: From 7b2e63d1dac132162dc4a9e4c9c62dcc604b839a Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Tue, 2 Feb 2021 20:06:30 +0800 Subject: [PATCH 282/705] Improved cache saving methods --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 18acc88c7a..d534ef352e 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1157,7 +1157,7 @@ async def _find_from_channel(self, channel): recipient = None if recipient is None: - self.cache[user_id] = thread = Thread(self, user_id, channel) + thread = Thread(self, user_id, channel) else: self.cache[user_id] = thread = Thread(self, recipient, channel) thread.ready = True From 4054c510f8694372173ff99eb48cde43c359490a Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 2 Feb 2021 21:24:40 +0800 Subject: [PATCH 283/705] Ability to disable mention on thread creation. --- cogs/utility.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 65b3ef00f5..a89442464a 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -674,20 +674,41 @@ async def ping(self, ctx): @commands.command() @checks.has_permissions(PermissionLevel.ADMINISTRATOR) - async def mention(self, ctx, *mention: Union[discord.Role, discord.Member]): + async def mention(self, ctx, *mention: Union[discord.Role, discord.Member, str]): """ Change what the bot mentions at the start of each thread. Type only `{prefix}mention` to retrieve your current "mention" message. + `{prefix}mention disable` to disable mention. + `{prefix}mention reset` to reset it to default value. """ - # TODO: ability to disable mention. current = self.bot.config["mention"] - if not mention: embed = discord.Embed( title="Current mention:", color=self.bot.main_color, description=str(current) ) + elif ( + len(mention) == 1 + and isinstance(mention[0], str) + and mention[0] in ["disable", "reset"] + ): + option = mention[0] + if option == "disable": + embed = discord.Embed( + description=f"Disabled mention on thread creation.", + color=self.bot.main_color, + ) + self.bot.config["mention"] = None + else: + embed = discord.Embed( + description="`mention` had been reset to default.", color=self.bot.main_color, + ) + self.bot.config.remove("mention") + await self.bot.config.update() else: + for m in mention: + if not isinstance(m, (discord.Role, discord.Member)): + raise commands.BadArgument(f'Role or Member "{m}" not found.') mention = " ".join(i.mention for i in mention) embed = discord.Embed( title="Changed mention!", From 15a38bcfc11958291c24f36d3d9cbde44d032e3d Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 2 Feb 2021 22:08:35 +0800 Subject: [PATCH 284/705] Update thread move message in case `mention` was set to disable/None. --- cogs/modmail.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index ee109420af..fee8e0b5fe 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -341,7 +341,11 @@ async def move(self, ctx, *, arguments): if self.bot.config["thread_move_notify_mods"]: mention = self.bot.config["mention"] - await thread.channel.send(f"{mention}, thread has been moved.") + if mention is not None: + msg = f"{mention}, thread has been moved." + else: + msg = "Thread has been moved." + await thread.channel.send(msg) sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) From 0bfb02e01256f3c0a8b5b4ab872aa6a72e1a95b3 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 2 Feb 2021 22:16:43 +0800 Subject: [PATCH 285/705] Formatting... --- cogs/utility.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index a89442464a..0428f079d9 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -695,8 +695,7 @@ async def mention(self, ctx, *mention: Union[discord.Role, discord.Member, str]) option = mention[0] if option == "disable": embed = discord.Embed( - description=f"Disabled mention on thread creation.", - color=self.bot.main_color, + description=f"Disabled mention on thread creation.", color=self.bot.main_color, ) self.bot.config["mention"] = None else: From 270483fd65898b46433b7e4052476c276f1c590f Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Wed, 3 Feb 2021 08:26:19 +0800 Subject: [PATCH 286/705] Apply suggestions from code review Co-authored-by: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> --- cogs/utility.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 0428f079d9..f4c490b846 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -690,9 +690,9 @@ async def mention(self, ctx, *mention: Union[discord.Role, discord.Member, str]) elif ( len(mention) == 1 and isinstance(mention[0], str) - and mention[0] in ["disable", "reset"] + and mention[0].lower() in ["disable", "reset"] ): - option = mention[0] + option = mention[0].lower() if option == "disable": embed = discord.Embed( description=f"Disabled mention on thread creation.", color=self.bot.main_color, @@ -700,7 +700,7 @@ async def mention(self, ctx, *mention: Union[discord.Role, discord.Member, str]) self.bot.config["mention"] = None else: embed = discord.Embed( - description="`mention` had been reset to default.", color=self.bot.main_color, + description="`mention` is reset to default.", color=self.bot.main_color, ) self.bot.config.remove("mention") await self.bot.config.update() From c5a48f0cf9e28131ea36e8307bb35e7ee3bc2e45 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 28 Feb 2021 21:56:08 +0800 Subject: [PATCH 287/705] Fix typo in 'config_help.json' (#2957) --- core/config_help.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config_help.json b/core/config_help.json index e6bf3730ab..271e726346 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -706,7 +706,7 @@ "`{prefix}config set confirm_thread_creation yes`" ], "notes": [ - "See also: `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny``" + "See also: `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny`" ] }, "confirm_thread_creation_title": { From 049508fd944b0fbbbb57b8001044ca1a652a6f04 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 28 Feb 2021 14:59:15 +0100 Subject: [PATCH 288/705] Update README.md (#2955) fix a sentence which said to join the old deleted plugin server --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 74e37838dc..b5dfc9b4aa 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ You can find a list of third-party plugins using the `?plugins registry` comman To develop your own, check out the [plugins documentation](https://github.com/kyb3r/modmail/wiki/Plugins). -Plugins requests and support is available in our [Modmail Plugins Server](https://discord.gg/4JE4XSW). +Plugins requests and support are available in our [Modmail Support Server](https://discord.gg/j5e9p8w). ## Contributing From 907b10d466b5df16d6438c6735088c4d65cdf098 Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Sun, 7 Mar 2021 22:53:56 +1000 Subject: [PATCH 289/705] Add msglink command to get DM message URLs. --- cogs/modmail.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cogs/modmail.py b/cogs/modmail.py index ee109420af..2392916fea 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -601,6 +601,18 @@ async def sfw(self, ctx): sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) + @commands.command() + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def loglink(self, ctx, message_id: int): + """Retrieves the link to a message in the current thread.""" + message = await ctx.thread.recipient.fetch_message(message_id) + if not message: + embed = discord.Embed(color=self.bot.main_color, description="Message no longer exists.") + else: + embed = discord.Embed(color=self.bot.main_color, description=message.jump_url) + await ctx.send(embed=embed) + @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() From 5482bed00fab2da73c1fae694271acd682967dca Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Sun, 7 Mar 2021 22:54:16 +1000 Subject: [PATCH 290/705] Add DM channel ID to genesis message footer. --- core/thread.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index d534ef352e..98f67ca897 100644 --- a/core/thread.py +++ b/core/thread.py @@ -300,7 +300,11 @@ def _format_info_embed(self, user, log_url, log_count, color): # embed.add_field(name='Mention', value=user.mention) # embed.add_field(name='Registered', value=created + days(created)) - footer = "User ID: " + str(user.id) + if user.dm_channel: + footer = f"User ID: {user.id} • DM ID: {user.dm_channel}" + else: + footer = f"User ID: {user.id}" + embed.set_author(name=str(user), icon_url=user.avatar_url, url=log_url) # embed.set_thumbnail(url=avi) From 784aa4f950b2b6fe9e275860c03fa961ff1abd84 Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Sun, 7 Mar 2021 23:07:54 +1000 Subject: [PATCH 291/705] Amend typo and black formatting. --- cogs/modmail.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 2392916fea..d9965243be 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -604,11 +604,13 @@ async def sfw(self, ctx): @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() - async def loglink(self, ctx, message_id: int): + async def msglink(self, ctx, message_id: int): """Retrieves the link to a message in the current thread.""" message = await ctx.thread.recipient.fetch_message(message_id) if not message: - embed = discord.Embed(color=self.bot.main_color, description="Message no longer exists.") + embed = discord.Embed( + color=self.bot.main_color, description="Message no longer exists." + ) else: embed = discord.Embed(color=self.bot.main_color, description=message.jump_url) await ctx.send(embed=embed) From e0956c48061ed164af3ae3953589f9cba1e56cb7 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 7 Mar 2021 23:11:20 +0800 Subject: [PATCH 292/705] Improve messages --- cogs/modmail.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index d9965243be..f0ee2815c8 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -606,13 +606,16 @@ async def sfw(self, ctx): @checks.thread_only() async def msglink(self, ctx, message_id: int): """Retrieves the link to a message in the current thread.""" - message = await ctx.thread.recipient.fetch_message(message_id) - if not message: + try: + message = await ctx.thread.recipient.fetch_message(message_id) + except discord.NotFound: embed = discord.Embed( - color=self.bot.main_color, description="Message no longer exists." + color=self.bot.error_color, description="Message not found or no longer exists." ) else: - embed = discord.Embed(color=self.bot.main_color, description=message.jump_url) + embed = discord.Embed( + color=self.bot.main_color, description=message.jump_url + ) await ctx.send(embed=embed) @commands.command() From 9d9a609b1f8a521161bf483eb5a8e7ab7f5594e4 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 7 Mar 2021 23:14:00 +0800 Subject: [PATCH 293/705] Changelog update --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebf7ecaa3e..da576ec027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.8.5 + +This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 where users were not properly cached. + +### Added + +- `?msglink `, allows you to obtain channel + message ID for T&S reports. ([GH #2963](https://github.com/kyb3r/modmail/issues/2963), [PR #2964](https://github.com/kyb3r/modmail/pull/2964)) + +### Fixed + +- Non-master/development branch deployments no longer cause erros to be raised. + # v3.8.4 This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 where users were not properly cached. From 41d5593d0370bece803628cb79bfd1a54809277d Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 7 Mar 2021 23:14:49 +0800 Subject: [PATCH 294/705] Non-master/development branch deployments no longer cause erros to be raised. --- CHANGELOG.md | 4 +--- core/changelog.py | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da576ec027..83603ac880 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,15 +8,13 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v3.8.5 -This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 where users were not properly cached. - ### Added - `?msglink `, allows you to obtain channel + message ID for T&S reports. ([GH #2963](https://github.com/kyb3r/modmail/issues/2963), [PR #2964](https://github.com/kyb3r/modmail/pull/2964)) ### Fixed -- Non-master/development branch deployments no longer cause erros to be raised. +- Non-master/development branch deployments no longer cause errors to be raised. # v3.8.4 diff --git a/core/changelog.py b/core/changelog.py index ada9fe6984..878a19b26c 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -180,6 +180,9 @@ async def from_url(cls, bot, url: str = "") -> "Changelog": if not branch or err: branch = "master" if not bot.version.is_prerelease else "development" + if branch not in ("master", "development"): + branch = "master" + url = url or f"https://raw.githubusercontent.com/kyb3r/modmail/{branch}/CHANGELOG.md" async with await bot.session.get(url) as resp: From 3c42c22e34ebb5d439a0af36553db027f66b0a24 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 7 Mar 2021 23:16:12 +0800 Subject: [PATCH 295/705] Update changelog --- CHANGELOG.md | 1 + bot.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83603ac880..0ceeeeedf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added - `?msglink `, allows you to obtain channel + message ID for T&S reports. ([GH #2963](https://github.com/kyb3r/modmail/issues/2963), [PR #2964](https://github.com/kyb3r/modmail/pull/2964)) +- `?mention disable/reset`, disables or resets mention on thread creation. ([PR #2951](https://github.com/kyb3r/modmail/pull/2951)) ### Fixed diff --git a/bot.py b/bot.py index aa19d7b3d1..bc68584f58 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.4" +__version__ = "3.8.5" import asyncio From baa7e5fb677e35433586efe0cd63e97d95aa55c4 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 7 Mar 2021 23:44:25 +0800 Subject: [PATCH 296/705] Fix bug where autotriggers are in dm context, resolve #2961 --- CHANGELOG.md | 1 + bot.py | 3 ++- cogs/modmail.py | 4 +--- cogs/utility.py | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ceeeeedf0..0af5009464 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed - Non-master/development branch deployments no longer cause errors to be raised. +- Autotriggers now can search for roles/channels in guild context. ([GH #2961](https://github.com/kyb3r/modmail/issues/2961)) # v3.8.4 diff --git a/bot.py b/bot.py index bc68584f58..1b474e40dd 100644 --- a/bot.py +++ b/bot.py @@ -939,6 +939,7 @@ async def get_contexts(self, message, *, cls=commands.Context): async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context): message.author = self.modmail_guild.me message.channel = channel + message.guild = channel.guild view = StringView(message.content) ctx = cls(prefix=self.prefix, view=view, bot=self, message=message) @@ -967,7 +968,7 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) ctxs = [] aliases = normalize_alias(alias) if not aliases: - logger.warning("Alias %s is invalid as called in automove.", invoker) + logger.warning("Alias %s is invalid as called in autotrigger.", invoker) for alias in aliases: view = StringView(invoked_prefix + alias) diff --git a/cogs/modmail.py b/cogs/modmail.py index 9a659a1934..cbc6e4c2a8 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -617,9 +617,7 @@ async def msglink(self, ctx, message_id: int): color=self.bot.error_color, description="Message not found or no longer exists." ) else: - embed = discord.Embed( - color=self.bot.main_color, description=message.jump_url - ) + embed = discord.Embed(color=self.bot.main_color, description=message.jump_url) await ctx.send(embed=embed) @commands.command() diff --git a/cogs/utility.py b/cogs/utility.py index f4c490b846..8663e70e73 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1798,7 +1798,6 @@ async def autotrigger_edit(self, ctx, keyword, *, command): split_cmd = command.split(" ") for n in range(1, len(split_cmd) + 1): if self.bot.get_command(" ".join(split_cmd[0:n])): - print(self.bot.get_command(" ".join(split_cmd[0:n]))) valid = True break From d24501bc2550de890b5389b8debc000bccad13b1 Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Mon, 8 Mar 2021 02:28:01 +1000 Subject: [PATCH 297/705] Use the ID attribute of DM Channel. Originally used the channel instance by mistake, causing the `__str__` to be used instead of the intended ID. --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 98f67ca897..cd2797ac67 100644 --- a/core/thread.py +++ b/core/thread.py @@ -301,7 +301,7 @@ def _format_info_embed(self, user, log_url, log_count, color): # embed.add_field(name='Registered', value=created + days(created)) if user.dm_channel: - footer = f"User ID: {user.id} • DM ID: {user.dm_channel}" + footer = f"User ID: {user.id} • DM ID: {user.dm_channel.id}" else: footer = f"User ID: {user.id}" From 93b027000b3b775806ffb13c8fe189ea9ffe819e Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Thu, 11 Mar 2021 21:59:45 +0800 Subject: [PATCH 298/705] Confirm thread creation when user opens a thread using react to contact. --- cogs/modmail.py | 7 ++++++- core/thread.py | 15 ++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index cbc6e4c2a8..29552b7ca0 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1027,7 +1027,12 @@ async def contact( await ctx.channel.send(embed=embed, delete_after=3) else: - thread = await self.bot.threads.create(user, creator=ctx.author, category=category) + thread = await self.bot.threads.create( + recipient=user, + creator=ctx.author, + category=category, + manual_trigger=manual_trigger, + ) if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): logger.info("Contacting user %s when Modmail DM is disabled.", user) diff --git a/core/thread.py b/core/thread.py index 98f67ca897..e08ff3e5a9 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1175,6 +1175,7 @@ async def create( message: discord.Message = None, creator: typing.Union[discord.Member, discord.User] = None, category: discord.CategoryChannel = None, + manual_trigger: bool = True, ) -> Thread: """Creates a Modmail thread""" @@ -1215,8 +1216,12 @@ async def create( self.bot.config.set("fallback_category_id", category.id) await self.bot.config.update() - if message and self.bot.config["confirm_thread_creation"]: - confirm = await message.channel.send( + if (message or not manual_trigger) and self.bot.config["confirm_thread_creation"]: + if not manual_trigger: + destination = recipient + else: + destination = message.channel + confirm = await destination.send( embed=discord.Embed( title=self.bot.config["confirm_thread_creation_title"], description=self.bot.config["confirm_thread_response"], @@ -1231,7 +1236,7 @@ async def create( try: r, _ = await self.bot.wait_for( "reaction_add", - check=lambda r, u: u.id == message.author.id + check=lambda r, u: u.id == recipient.id and r.message.id == confirm.id and r.message.channel.id == confirm.channel.id and str(r.emoji) in (accept_emoji, deny_emoji), @@ -1243,7 +1248,7 @@ async def create( await confirm.remove_reaction(accept_emoji, self.bot.user) await asyncio.sleep(0.2) await confirm.remove_reaction(deny_emoji, self.bot.user) - await message.channel.send( + await destination.send( embed=discord.Embed( title="Cancelled", description="Timed out", color=self.bot.error_color ) @@ -1257,7 +1262,7 @@ async def create( await confirm.remove_reaction(accept_emoji, self.bot.user) await asyncio.sleep(0.2) await confirm.remove_reaction(deny_emoji, self.bot.user) - await message.channel.send( + await destination.send( embed=discord.Embed(title="Cancelled", color=self.bot.error_color) ) del self.cache[recipient.id] From df41d314f6c1ec7200454c47df0b5d3063b8f2a2 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Thu, 11 Mar 2021 22:30:08 +0800 Subject: [PATCH 299/705] Block new thread from react to contact when Modmail DM is disabled (new or all). --- bot.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index 1b474e40dd..06e5a62483 100644 --- a/bot.py +++ b/bot.py @@ -1238,6 +1238,26 @@ async def on_raw_reaction_add(self, payload): if not member.bot: message = await channel.fetch_message(payload.message_id) await message.remove_reaction(payload.emoji, member) + await message.add_reaction(emoji_fmt) # bot adds as well + + if self.config["dm_disabled"] in ( + DMDisabled.NEW_THREADS, + DMDisabled.ALL_THREADS, + ): + embed = discord.Embed( + title=self.config["disabled_new_thread_title"], + color=self.error_color, + description=self.config["disabled_new_thread_response"], + ) + embed.set_footer( + text=self.config["disabled_new_thread_footer"], + icon_url=self.guild.icon_url, + ) + logger.info( + "A new thread using react to contact was blocked from %s due to disabled Modmail.", + message.author, + ) + return await member.send(embed=embed) ctx = await self.get_context(message) ctx.author = member @@ -1245,8 +1265,6 @@ async def on_raw_reaction_add(self, payload): self.get_command("contact"), user=member, manual_trigger=False ) - await message.add_reaction(emoji_fmt) # bot adds as well - async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: await self.handle_reaction_events(payload) From fd6dfb7deeec7bf8463434c8c6d71bd984bdb644 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Thu, 11 Mar 2021 22:39:34 +0800 Subject: [PATCH 300/705] Bot will not attempt to find for linked message when the recipient reacts to reactions on confirm thread creation message. --- bot.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bot.py b/bot.py index 06e5a62483..9a33922283 100644 --- a/bot.py +++ b/bot.py @@ -1188,6 +1188,14 @@ async def handle_reaction_events(self, payload): # the reacted message is the corresponding thread creation embed # closing thread return await thread.close(closer=user) + if ( + message.author == self.user + and message.embeds + and self.config.get("confirm_thread_creation") + and message.embeds[0].title == self.config["confirm_thread_creation_title"] + and message.embeds[0].description == self.config["confirm_thread_response"] + ): + return if not thread.recipient.dm_channel: await thread.recipient.create_dm() try: From ccc8e6f89ca202e2950d692c18be57cb735cb58b Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Thu, 11 Mar 2021 23:03:48 +0800 Subject: [PATCH 301/705] Fix previous commit. --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 9a33922283..dd1008ae54 100644 --- a/bot.py +++ b/bot.py @@ -1263,7 +1263,7 @@ async def on_raw_reaction_add(self, payload): ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", - message.author, + member, ) return await member.send(embed=embed) From 69a272e6734fd38e50323bafebe748b823bb5cce Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 13 Mar 2021 11:03:42 +0800 Subject: [PATCH 302/705] Fix a few bad refs and typos --- bot.py | 4 ++-- cogs/modmail.py | 1 - cogs/plugins.py | 14 +++++++------- cogs/utility.py | 1 - core/config.py | 2 +- core/models.py | 3 +-- core/thread.py | 2 +- core/utils.py | 3 ++- 8 files changed, 14 insertions(+), 16 deletions(-) diff --git a/bot.py b/bot.py index 1b474e40dd..3112895225 100644 --- a/bot.py +++ b/bot.py @@ -46,7 +46,7 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import human_join, normalize_alias, truncate +from core.utils import normalize_alias, truncate logger = getLogger(__name__) @@ -1591,7 +1591,7 @@ def main(): # check discord version if discord.__version__ != "1.6.0": logger.error( - "Dependencies are not updated, run pipenv install. discord.py version expected 1.6.0, recieved %s", + "Dependencies are not updated, run pipenv install. discord.py version expected 1.6.0, received %s", discord.__version__, ) sys.exit(0) diff --git a/cogs/modmail.py b/cogs/modmail.py index cbc6e4c2a8..64d6a2475c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1,5 +1,4 @@ import asyncio -from operator import truediv import re from datetime import datetime from itertools import zip_longest diff --git a/cogs/plugins.py b/cogs/plugins.py index ce21551831..1f7aa869d7 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -178,14 +178,14 @@ async def download_plugin(self, plugin, force=False): if raw == "Not Found": raise InvalidPluginError("Plugin not found") else: - raise InvalidPluginError("Invalid download recieved, non-bytes object") + raise InvalidPluginError("Invalid download received, non-bytes object") - plugin_io = io.BytesIO(raw) - if not plugin.cache_path.parent.exists(): - plugin.cache_path.parent.mkdir(parents=True) + plugin_io = io.BytesIO(raw) + if not plugin.cache_path.parent.exists(): + plugin.cache_path.parent.mkdir(parents=True) - with plugin.cache_path.open("wb") as f: - f.write(raw) + with plugin.cache_path.open("wb") as f: + f.write(raw) with zipfile.ZipFile(plugin_io) as zipf: for info in zipf.infolist(): @@ -253,7 +253,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): description="Plugins are disabled, enable them by setting `ENABLE_PLUGINS=true`", color=self.bot.main_color, ) - await ctx.send(embed=em) + await ctx.send(embed=embed) return if not self._ready_event.is_set(): diff --git a/cogs/utility.py b/cogs/utility.py index 8663e70e73..8ce7af5b69 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -3,7 +3,6 @@ import os import random import re -from sys import stdout import traceback from contextlib import redirect_stdout from datetime import datetime diff --git a/core/config.py b/core/config.py index 2c88b10d14..14197e112e 100644 --- a/core/config.py +++ b/core/config.py @@ -14,7 +14,7 @@ from core._color_data import ALL_COLORS from core.models import DMDisabled, InvalidConfigError, Default, getLogger from core.time import UserFriendlyTimeSync -from core.utils import strtobool, tryint +from core.utils import strtobool logger = getLogger(__name__) load_dotenv() diff --git a/core/models.py b/core/models.py index 2f71f0f202..24236e6279 100644 --- a/core/models.py +++ b/core/models.py @@ -190,14 +190,13 @@ def get_value(self, key, args, kwds): except KeyError: return "{" + key + "}" else: - return Formatter.get_value(key, args, kwds) + return super().get_value(key, args, kwds) class SimilarCategoryConverter(commands.CategoryChannelConverter): async def convert(self, ctx, argument): bot = ctx.bot guild = ctx.guild - result = None try: return await super().convert(ctx, argument) diff --git a/core/thread.py b/core/thread.py index 98f67ca897..069d2eb8e0 100644 --- a/core/thread.py +++ b/core/thread.py @@ -2,9 +2,9 @@ import copy import io import re +import time import typing from datetime import datetime, timedelta -import time from types import SimpleNamespace import isodate diff --git a/core/utils.py b/core/utils.py index 5f88c21e80..8f4b152ff5 100644 --- a/core/utils.py +++ b/core/utils.py @@ -30,6 +30,7 @@ "escape_code_block", "format_channel_name", "tryint", + "match_title", ] @@ -222,7 +223,7 @@ def cleanup_code(content: str) -> str: def match_title(text: str) -> int: """ - Matches a title in the foramt of "Title: XXXX" + Matches a title in the format of "Title: XXXX" Parameters ---------- From 695baa511df5a1b8de6b5860927e228cb9cbb32c Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 13 Mar 2021 11:34:49 +0800 Subject: [PATCH 303/705] Add local plugins --- .gitignore | 2 -- cogs/plugins.py | 80 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 463016ca95..37094114b7 100644 --- a/.gitignore +++ b/.gitignore @@ -131,8 +131,6 @@ node_modules/ # Modmail config.json -plugins/ -!plugins/registry.json temp/ test.py stack.yml diff --git a/cogs/plugins.py b/cogs/plugins.py index 1f7aa869d7..48de189bc2 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -31,16 +31,28 @@ class InvalidPluginError(commands.BadArgument): class Plugin: - def __init__(self, user, repo, name, branch=None): - self.user = user - self.repo = repo - self.name = name - self.branch = branch if branch is not None else "master" - self.url = f"https://github.com/{user}/{repo}/archive/{self.branch}.zip" - self.link = f"https://github.com/{user}/{repo}/tree/{self.branch}/{name}" + def __init__(self, user, repo=None, name=None, branch=None): + if repo is None: + self.user = "@local" + self.repo = "@local" + self.name = user + self.local = True + self.branch = "@local" + self.url = f"@local/{user}" + self.link = f"@local/{user}" + else: + self.user = user + self.repo = repo + self.name = name + self.local = False + self.branch = branch if branch is not None else "master" + self.url = f"https://github.com/{user}/{repo}/archive/{self.branch}.zip" + self.link = f"https://github.com/{user}/{repo}/tree/{self.branch}/{name}" @property def path(self): + if self.local: + return PurePath("plugins") / "@local" / self.name return PurePath("plugins") / self.user / self.repo / f"{self.name}-{self.branch}" @property @@ -49,6 +61,8 @@ def abs_path(self): @property def cache_path(self): + if self.local: + raise ValueError("No cache path for local plugins!") return ( Path(__file__).absolute().parent.parent / "temp" @@ -58,9 +72,13 @@ def cache_path(self): @property def ext_string(self): + if self.local: + return f"plugins.@local.{self.name}.{self.name}" return f"plugins.{self.user}.{self.repo}.{self.name}-{self.branch}.{self.name}" def __str__(self): + if self.local: + return f"@local/{self.name}" return f"{self.user}/{self.repo}/{self.name}@{self.branch}" def __lt__(self, other): @@ -68,10 +86,13 @@ def __lt__(self, other): @classmethod def from_string(cls, s, strict=False): - if not strict: - m = match(r"^(.+?)/(.+?)/(.+?)(?:@(.+?))?$", s) - else: - m = match(r"^(.+?)/(.+?)/(.+?)@(.+?)$", s) + m = match(r"^@local/(.+)$", s) + if m is None: + if not strict: + m = match(r"^(.+?)/(.+?)/(.+?)(?:@(.+?))?$", s) + else: + m = match(r"^(.+?)/(.+?)/(.+?)@(.+?)$", s) + if m is not None: return Plugin(*m.groups()) raise InvalidPluginError("Cannot decipher %s.", s) # pylint: disable=raising-format-tuple @@ -155,6 +176,9 @@ async def download_plugin(self, plugin, force=False): if plugin.abs_path.exists() and not force: return + if plugin.local: + raise InvalidPluginError(f"Local plugin {plugin} not found!") + plugin.abs_path.mkdir(parents=True, exist_ok=True) if plugin.cache_path.exists() and not force: @@ -290,7 +314,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): embed = discord.Embed( description="Invalid plugin name, double check the plugin name " "or use one of the following formats: " - "username/repo/plugin, username/repo/plugin@branch.", + "username/repo/plugin, username/repo/plugin@branch, @local/plugin.", color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -314,7 +338,8 @@ async def plugins_add(self, ctx, *, plugin_name: str): Install a new plugin for the bot. `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, - or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`). + or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) + or `@local/name` for local plugins. """ plugin = await self.parse_user_input(ctx, plugin_name, check_version=True) @@ -395,7 +420,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): Remove an installed plugin of the bot. `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference - to a GitHub hosted plugin (in the format `user/repo/name[@branch]`). + to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `@local/name` for local plugins. """ plugin = await self.parse_user_input(ctx, plugin_name) if plugin is None: @@ -416,17 +441,18 @@ async def plugins_remove(self, ctx, *, plugin_name: str): self.bot.config["plugins"].remove(str(plugin)) await self.bot.config.update() - shutil.rmtree( - plugin.abs_path, - onerror=lambda *args: logger.warning( - "Failed to remove plugin files %s: %s", plugin, str(args[2]) - ), - ) - try: - plugin.abs_path.parent.rmdir() - plugin.abs_path.parent.parent.rmdir() - except OSError: - pass # dir not empty + if not plugin.local: + shutil.rmtree( + plugin.abs_path, + onerror=lambda *args: logger.warning( + "Failed to remove plugin files %s: %s", plugin, str(args[2]) + ), + ) + try: + plugin.abs_path.parent.rmdir() + plugin.abs_path.parent.parent.rmdir() + except OSError: + pass # dir not empty embed = discord.Embed( description="The plugin is successfully uninstalled.", color=self.bot.main_color @@ -477,7 +503,7 @@ async def plugins_update(self, ctx, *, plugin_name: str = None): Update a plugin for the bot. `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference - to a GitHub hosted plugin (in the format `user/repo/name[@branch]`). + to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `@local/name` for local plugins. To update all plugins, do `{prefix}plugins update`. """ @@ -514,7 +540,7 @@ async def plugins_reset(self, ctx): shutil.rmtree(cache_path) for entry in os.scandir(Path(__file__).absolute().parent.parent / "plugins"): - if entry.is_dir(): + if entry.is_dir() and entry.name != "@local": shutil.rmtree(entry.path) logger.warning("Removing %s.", entry.name) From 51460971a6be32d4c9b2d7d4015536abe22d754f Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 13 Mar 2021 11:37:19 +0800 Subject: [PATCH 304/705] Add local plugin dir --- plugins/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 plugins/.gitignore diff --git a/plugins/.gitignore b/plugins/.gitignore new file mode 100644 index 0000000000..4522f5eb88 --- /dev/null +++ b/plugins/.gitignore @@ -0,0 +1,4 @@ +* +!registry.json +!@local/ +!.gitignore \ No newline at end of file From d6ba02e66aee2235a85c2c1f5cbebe5a14a3b1af Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 13 Mar 2021 11:44:24 +0800 Subject: [PATCH 305/705] Add local plugins --- .dockerignore | 1 + .gitignore | 3 +++ plugins/.gitignore | 4 ---- plugins/@local/.gitignore | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-) delete mode 100644 plugins/.gitignore create mode 100644 plugins/@local/.gitignore diff --git a/.dockerignore b/.dockerignore index bae84fb2e4..99fd4a241b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -133,6 +133,7 @@ node_modules/ config.json plugins/ !plugins/registry.json +!plugins/@local/ temp/ test.py diff --git a/.gitignore b/.gitignore index 37094114b7..635e3160e8 100644 --- a/.gitignore +++ b/.gitignore @@ -130,6 +130,9 @@ package-lock.json node_modules/ # Modmail +plugins/* +!plugins/registry.json +!plugins/@local config.json temp/ test.py diff --git a/plugins/.gitignore b/plugins/.gitignore deleted file mode 100644 index 4522f5eb88..0000000000 --- a/plugins/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!registry.json -!@local/ -!.gitignore \ No newline at end of file diff --git a/plugins/@local/.gitignore b/plugins/@local/.gitignore new file mode 100644 index 0000000000..c96a04f008 --- /dev/null +++ b/plugins/@local/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file From b6b9e6c7a4c0bb76141cf1d193f4a980a8e259ef Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 13 Mar 2021 12:04:37 +0800 Subject: [PATCH 306/705] Updated version, deps, and plugins code --- CHANGELOG.md | 8 ++++++++ bot.py | 2 +- cogs/plugins.py | 26 ++++++++++++++++---------- pyproject.toml | 4 ++-- requirements.min.txt | 14 +++----------- 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0af5009464..c065153e2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. + +# v3.8.6 + +### Added + +- Ability to install local plugins without relying on git / external sources + - Simply add your extension to plugins/@local, and use `?plugin add local/plugin-name` + # v3.8.5 ### Added diff --git a/bot.py b/bot.py index 3112895225..5efa4d521a 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.5" +__version__ = "3.8.6" import asyncio diff --git a/cogs/plugins.py b/cogs/plugins.py index 48de189bc2..94a3f425c0 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -86,7 +86,7 @@ def __lt__(self, other): @classmethod def from_string(cls, s, strict=False): - m = match(r"^@local/(.+)$", s) + m = match(r"^@?local/(.+)$", s) if m is None: if not strict: m = match(r"^(.+?)/(.+?)/(.+?)(?:@(.+?))?$", s) @@ -173,7 +173,7 @@ async def initial_load_plugins(self): await self.bot.config.update() async def download_plugin(self, plugin, force=False): - if plugin.abs_path.exists() and not force: + if plugin.abs_path.exists() and (not force or plugin.local): return if plugin.local: @@ -314,7 +314,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): embed = discord.Embed( description="Invalid plugin name, double check the plugin name " "or use one of the following formats: " - "username/repo/plugin, username/repo/plugin@branch, @local/plugin.", + "username/repo/plugin-name, username/repo/plugin-name@branch, local/plugin-name.", color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -339,7 +339,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) - or `@local/name` for local plugins. + or `local/name` for local plugins. """ plugin = await self.parse_user_input(ctx, plugin_name, check_version=True) @@ -360,10 +360,16 @@ async def plugins_add(self, ctx, *, plugin_name: str): ) return await ctx.send(embed=embed) - embed = discord.Embed( - description=f"Starting to download plugin from {plugin.link}...", - color=self.bot.main_color, - ) + if plugin.local: + embed = discord.Embed( + description=f"Starting to load local plugin from {plugin.link}...", + color=self.bot.main_color, + ) + else: + embed = discord.Embed( + description=f"Starting to download plugin from {plugin.link}...", + color=self.bot.main_color, + ) msg = await ctx.send(embed=embed) try: @@ -420,7 +426,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): Remove an installed plugin of the bot. `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference - to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `@local/name` for local plugins. + to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `local/name` for local plugins. """ plugin = await self.parse_user_input(ctx, plugin_name) if plugin is None: @@ -503,7 +509,7 @@ async def plugins_update(self, ctx, *, plugin_name: str = None): Update a plugin for the bot. `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference - to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `@local/name` for local plugins. + to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `local/name` for local plugins. To update all plugins, do `{prefix}plugins update`. """ diff --git a/pyproject.toml b/pyproject.toml index e7c56eb749..60b86fdbc4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.6.0' +version = '3.8.6' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ @@ -36,7 +36,7 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "./discord.py-1.5.2.tar.gz" +"discord.py" = "discord.py==1.6.0" uvloop = {version = ">=0.12.0", markers = "sys_platform != 'win32'"} python-dotenv = ">=0.10.3" parsedatetime = "^2.6" diff --git a/requirements.min.txt b/requirements.min.txt index cf1b4bdd26..d756599661 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -1,24 +1,16 @@ -# Generated as of June, 2020 +# Generated as of March, 2021 # This is the bare minimum requirements.txt for running Modmail. # To install requirements.txt run: pip install -r requirements.min.txt aiohttp==3.6.2 -async-timeout==3.0.1 -attrs==19.3.0 -chardet==3.0.4 -./discord.py-1.5.2.tar.gz +discord.py==1.6.0 dnspython==1.16.0 emoji==0.5.4 -future==0.18.2 -idna==2.9 isodate==0.6.0 motor==2.1.0 -multidict==4.7.6 natural==0.2.0 parsedatetime==2.6 pymongo==3.10.1 python-dateutil==2.8.1 python-dotenv==0.14.0 -six==1.15.0 -websockets==8.1 -yarl==1.4.2 +websockets==8.1 \ No newline at end of file From bf1668a491205eeb0a4ef4a797bfe5bca8b4ea57 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 13 Mar 2021 12:06:29 +0800 Subject: [PATCH 307/705] Forgot to finish sentence --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c065153e2e..6be578b8d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added - Ability to install local plugins without relying on git / external sources - - Simply add your extension to plugins/@local, and use `?plugin add local/plugin-name` + - Simply add your extension to plugins/@local, and use `?plugin add local/plugin-name` to load the plugin as normal +- Updated deps for requirements.min.txt and pyproject.toml # v3.8.5 From dee522888bc97b28f968c365ea07ef719e7afef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9D=A5sora?= <60399731+6days9weeks@users.noreply.github.com> Date: Mon, 15 Mar 2021 17:18:09 +0900 Subject: [PATCH 308/705] new plugin A little plugin I was working on --- plugins/registry.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 609345c395..11ee857335 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -204,5 +204,13 @@ "title": "Countdowns", "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" + }, + "action": { + "repository": "6days9weeks/modmail-plugins", + "branch": "master", + "description": "Have fun with others by hugging them or giving them pats~!!", + "title": "Action", + "icon_url": "https://media.discordapp.net/attachments/720733784970100776/820933433579798528/689105042212388965.png", + "thumbnail_url": "https://data.whicdn.com/images/58526601/original.gif" } } From e42546a7c041e3575f7920da955b72e34e05538a Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Fri, 19 Mar 2021 20:18:00 +0800 Subject: [PATCH 309/705] Potentially breaking: improved plugin events --- CHANGELOG.md | 9 +++++++++ bot.py | 2 +- core/thread.py | 7 ++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6be578b8d2..ca9c0ae183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.0 + +### Breaking + +- `on_thread_initiate` and `on_thread_ready` events now have `thread, creator, category, initial_message` as additional arguments. + +### Internal + +- `thread.reply` now returns (msg_to_user, msg_to_thread). Can be useful in plugins. # v3.8.6 diff --git a/bot.py b/bot.py index 5efa4d521a..ce91a3d326 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.6" +__version__ = "3.9.0" import asyncio diff --git a/core/thread.py b/core/thread.py index 069d2eb8e0..a647219e71 100644 --- a/core/thread.py +++ b/core/thread.py @@ -105,7 +105,7 @@ def cancelled(self, flag: bool): async def setup(self, *, creator=None, category=None, initial_message=None): """Create the thread channel and other io related initialisation tasks""" - self.bot.dispatch("thread_initiate", self) + self.bot.dispatch("thread_initiate", self, creator, category, initial_message) recipient = self.recipient # in case it creates a channel outside of category @@ -258,7 +258,7 @@ async def activate_auto_triggers(): activate_auto_triggers(), send_persistent_notes(), ) - self.bot.dispatch("thread_ready", self) + self.bot.dispatch("thread_ready", self, creator, category, initial_message) def _format_info_embed(self, user, log_url, log_count, color): """Get information about a member of a server @@ -753,7 +753,7 @@ async def reply( tasks = [] try: - await self.send( + user_msg = await self.send( message, destination=self.recipient, from_mod=True, @@ -809,6 +809,7 @@ async def reply( await asyncio.gather(*tasks) self.bot.dispatch("thread_reply", self, True, message, anonymous, plain) + return (user_msg, msg) # sent_to_user, sent_to_thread_channel async def send( self, From dd23edfe4872c77f6975cda1c862e52322322b5f Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Fri, 19 Mar 2021 20:30:53 +0800 Subject: [PATCH 310/705] Fix bug where cancelled still attempts to start thread --- cogs/modmail.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cogs/modmail.py b/cogs/modmail.py index 7ec111cee5..bd89571193 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1032,6 +1032,9 @@ async def contact( category=category, manual_trigger=manual_trigger, ) + if thread.cancelled: + return + if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): logger.info("Contacting user %s when Modmail DM is disabled.", user) From 9d4813d25e9d0d6cc2ac70d14dd63ebac043aea6 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Fri, 19 Mar 2021 20:35:58 +0800 Subject: [PATCH 311/705] Changelog & Ghost errors are no longer raised when threads are created using non-organic methods. --- CHANGELOG.md | 6 ++++++ core/models.py | 3 ++- core/thread.py | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca9c0ae183..d6d796246e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `on_thread_initiate` and `on_thread_ready` events now have `thread, creator, category, initial_message` as additional arguments. +### Fixed + +- `confirm_thread_creation` now properly works when a user opens a thread using react to contact. ([GH #2930](https://github.com/kyb3r/modmail/issues/2930), [PR #2971](https://github.com/kyb3r/modmail/pull/2971)) +- `?disable all/new` now disables react to contact threads. ([GH #2969](https://github.com/kyb3r/modmail/issues/2969), [PR #2971](https://github.com/kyb3r/modmail/pull/2971)) +- Ghost errors are no longer raised when threads are created using non-organic methods. + ### Internal - `thread.reply` now returns (msg_to_user, msg_to_thread). Can be useful in plugins. diff --git a/core/models.py b/core/models.py index 24236e6279..81247d387d 100644 --- a/core/models.py +++ b/core/models.py @@ -226,7 +226,8 @@ class DummyMessage: """ def __init__(self, message): - message.attachments = [] + if message: + message.attachments = [] self._message = message def __getattr__(self, name: str): diff --git a/core/thread.py b/core/thread.py index 72ce5664d4..9fe23301e4 100644 --- a/core/thread.py +++ b/core/thread.py @@ -245,8 +245,8 @@ class Author: await self.bot.api.update_note_ids(ids) async def activate_auto_triggers(): - message = DummyMessage(copy.copy(initial_message)) - if message: + if initial_message: + message = DummyMessage(copy.copy(initial_message)) try: return await self.bot.trigger_auto_triggers(message, channel) except RuntimeError: From 5efdbbe80e586838c3088f118fbe630ab85544f8 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Fri, 19 Mar 2021 21:12:50 +0800 Subject: [PATCH 312/705] Add reaciton menu plugin --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 11ee857335..86d424e228 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -212,5 +212,14 @@ "title": "Action", "icon_url": "https://media.discordapp.net/attachments/720733784970100776/820933433579798528/689105042212388965.png", "thumbnail_url": "https://data.whicdn.com/images/58526601/original.gif" + }, + "menu": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Adds reaction-based menus into thread creates. Check out `?configmenu`", + "title": "Menus", + "bot_version": "3.9.0", + "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", + "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" } } From b008d8a78fe94f2dde09c668cfc3bbb47982a7a4 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 21 Mar 2021 22:30:57 +0800 Subject: [PATCH 313/705] better run command, 3.9.1 --- CHANGELOG.md | 7 +++ bot.py | 115 ++++++++++++++++++++++++++++++++++++++----------- pyproject.toml | 2 +- 3 files changed, 98 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d796246e..c83219b367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.1 + +### Internal + +- `bot.run` now more gracefully handles closing, similar to how discord.py handles it. + - No longer displays `PrivilegedIntentsRequired` exception when exiting when presence intent is disabled. + # v3.9.0 ### Breaking diff --git a/bot.py b/bot.py index 28db42a453..24e7c717f7 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.0" +__version__ = "3.9.1" import asyncio @@ -6,6 +6,7 @@ import logging import os import re +import signal import sys import typing from datetime import datetime @@ -184,40 +185,104 @@ def db(self): async def get_prefix(self, message=None): return [self.prefix, f"<@{self.user.id}> ", f"<@!{self.user.id}> "] - def run(self, *args, **kwargs): + def run(self): + loop = self.loop + try: - self.loop.run_until_complete(self.start(self.token)) - except KeyboardInterrupt: + loop.add_signal_handler(signal.SIGINT, lambda: loop.stop()) + loop.add_signal_handler(signal.SIGTERM, lambda: loop.stop()) + except NotImplementedError: pass - except discord.LoginFailure: - logger.critical("Invalid token") - except discord.PrivilegedIntentsRequired: - intents = discord.Intents.default() - intents.members = True - # Try again with members intent - self._connection._intents = intents - logger.warning( - "Attempting to login with only the server members privileged intent. Some plugins might not work correctly." - ) + + async def runner(): try: - self.loop.run_until_complete(self.start(self.token)) + retry_intents = False + try: + await self.start(self.token) + except discord.PrivilegedIntentsRequired: + retry_intents = True + if retry_intents: + await self.http.close() + if self.ws is not None and self.ws.open: + await self.ws.close(code=1000) + self._ready.clear() + intents = discord.Intents.default() + intents.members = True + # Try again with members intent + self._connection._intents = intents + logger.warning( + "Attempting to login with only the server members privileged intent. Some plugins might not work correctly." + ) + await self.start(self.token) except discord.PrivilegedIntentsRequired: logger.critical( "Privileged intents are not explicitly granted in the discord developers dashboard." ) - except Exception: - logger.critical("Fatal exception", exc_info=True) - finally: - self.loop.run_until_complete(self.logout()) - for task in asyncio.all_tasks(self.loop): + except discord.LoginFailure: + logger.critical("Invalid token") + except Exception: + logger.critical("Fatal exception", exc_info=True) + finally: + if not self.is_closed(): + await self.close() + if self._session: + await self._session.close() + + def stop_loop_on_completion(f): + loop.stop() + + def _cancel_tasks(): + if sys.version_info < (3, 8): + task_retriever = asyncio.Task.all_tasks + else: + task_retriever = asyncio.all_tasks + + tasks = {t for t in task_retriever(loop=loop) if not t.done()} + + if not tasks: + return + + logger.info('Cleaning up after %d tasks.', len(tasks)) + for task in tasks: task.cancel() + + loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True)) + logger.info('All tasks finished cancelling.') + + for task in tasks: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler({ + 'message': 'Unhandled exception during Client.run shutdown.', + 'exception': task.exception(), + 'task': task + }) + + future = asyncio.ensure_future(runner(), loop=loop) + future.add_done_callback(stop_loop_on_completion) + try: + loop.run_forever() + except KeyboardInterrupt: + logger.info('Received signal to terminate bot and event loop.') + finally: + future.remove_done_callback(stop_loop_on_completion) + logger.info('Cleaning up tasks.') + try: - self.loop.run_until_complete(asyncio.gather(*asyncio.all_tasks(self.loop))) - except asyncio.CancelledError: - logger.debug("All pending tasks has been cancelled.") + _cancel_tasks() + if sys.version_info >= (3, 6): + loop.run_until_complete(loop.shutdown_asyncgens()) finally: - self.loop.run_until_complete(self.session.close()) - logger.error(" - Shutting down bot - ") + logger.info('Closing the event loop.') + loop.close() + + if not future.cancelled(): + try: + return future.result() + except KeyboardInterrupt: + # I am unsure why this gets raised here but suppress it anyway + return None @property def bot_owner_ids(self): diff --git a/pyproject.toml b/pyproject.toml index 60b86fdbc4..5171e27b5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.8.6' +version = '3.9.1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 380ea6ac04e4e285ef3b690cfa1db643ffdd1a4d Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Thu, 25 Mar 2021 16:46:51 +0100 Subject: [PATCH 314/705] add music plugin added music plugin on taki's request --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 86d424e228..65d91e3cf8 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -17,6 +17,15 @@ "icon_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png", "thumbnail_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png" }, + "Music": { + "repository": "Taaku18/modmail-plugins", + "branch": "master", + "description": "Play wonderfull jams through your modmail!", + "bot_version": "2.20.1", + "title": "Music", + "icon_url": "https://i.imgur.com/JmJPX5W.gif", + "thumbnail_url": "https://i.imgur.com/jrYL7F8.gif" + }, "media-only": { "repository": "lorenzo132/modmail-plugins", "branch": "master", From c434a1e70369ebfdc149779d56327b94757da068 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 26 Mar 2021 19:55:52 +0100 Subject: [PATCH 315/705] Update registry.json try to fix install issue --- plugins/registry.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 65d91e3cf8..515871e916 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -17,12 +17,12 @@ "icon_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png", "thumbnail_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png" }, - "Music": { + "music": { "repository": "Taaku18/modmail-plugins", "branch": "master", "description": "Play wonderfull jams through your modmail!", "bot_version": "2.20.1", - "title": "Music", + "title": "music", "icon_url": "https://i.imgur.com/JmJPX5W.gif", "thumbnail_url": "https://i.imgur.com/jrYL7F8.gif" }, From 68d8d887a83ba52f9f3c5a6c9ca1607d100b0563 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 28 Mar 2021 15:44:33 +0200 Subject: [PATCH 316/705] Update bot.py add hosting methods: screen and systemd --- bot.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bot.py b/bot.py index 28db42a453..9d2e3f7995 100644 --- a/bot.py +++ b/bot.py @@ -108,6 +108,12 @@ def hosting_method(self) -> HostingMethod: if os.environ.get("pm_id"): return HostingMethod.PM2 + if os.environ.get("INVOCATION_ID"): + return HostingMethod.SYSTEMD + + if os.environ.get("TERM"): + return HostingMethod.SCREEN + return HostingMethod.OTHER def startup(self): From 9fedb5b3a597d3852746e925e627111612a0bca0 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 28 Mar 2021 15:45:24 +0200 Subject: [PATCH 317/705] Update models.py add hosting methods: screen and systemd --- core/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/models.py b/core/models.py index 81247d387d..37355a488a 100644 --- a/core/models.py +++ b/core/models.py @@ -277,3 +277,5 @@ class HostingMethod(IntEnum): HEROKU = 0 PM2 = 1 OTHER = 2 + SYSTEMD = 3 + SCREEN = 4 From e3d1ab8817fc3c638e8ea969471dad726b645ef2 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:23:50 +0800 Subject: [PATCH 318/705] Force update dev? Weird history --- CHANGELOG.md | 7 +++ bot.py | 119 ++++++++++++++++++++++++++++++++++++++----------- pyproject.toml | 2 +- 3 files changed, 101 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d796246e..c83219b367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.1 + +### Internal + +- `bot.run` now more gracefully handles closing, similar to how discord.py handles it. + - No longer displays `PrivilegedIntentsRequired` exception when exiting when presence intent is disabled. + # v3.9.0 ### Breaking diff --git a/bot.py b/bot.py index 9d2e3f7995..d55971cdf8 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.0" +__version__ = "3.9.1" import asyncio @@ -6,6 +6,7 @@ import logging import os import re +import signal import sys import typing from datetime import datetime @@ -190,40 +191,106 @@ def db(self): async def get_prefix(self, message=None): return [self.prefix, f"<@{self.user.id}> ", f"<@!{self.user.id}> "] - def run(self, *args, **kwargs): + def run(self): + loop = self.loop + try: - self.loop.run_until_complete(self.start(self.token)) - except KeyboardInterrupt: + loop.add_signal_handler(signal.SIGINT, lambda: loop.stop()) + loop.add_signal_handler(signal.SIGTERM, lambda: loop.stop()) + except NotImplementedError: pass - except discord.LoginFailure: - logger.critical("Invalid token") - except discord.PrivilegedIntentsRequired: - intents = discord.Intents.default() - intents.members = True - # Try again with members intent - self._connection._intents = intents - logger.warning( - "Attempting to login with only the server members privileged intent. Some plugins might not work correctly." - ) + + async def runner(): try: - self.loop.run_until_complete(self.start(self.token)) + retry_intents = False + try: + await self.start(self.token) + except discord.PrivilegedIntentsRequired: + retry_intents = True + if retry_intents: + await self.http.close() + if self.ws is not None and self.ws.open: + await self.ws.close(code=1000) + self._ready.clear() + intents = discord.Intents.default() + intents.members = True + # Try again with members intent + self._connection._intents = intents + logger.warning( + "Attempting to login with only the server members privileged intent. Some plugins might not work correctly." + ) + await self.start(self.token) except discord.PrivilegedIntentsRequired: logger.critical( "Privileged intents are not explicitly granted in the discord developers dashboard." ) - except Exception: - logger.critical("Fatal exception", exc_info=True) - finally: - self.loop.run_until_complete(self.logout()) - for task in asyncio.all_tasks(self.loop): + except discord.LoginFailure: + logger.critical("Invalid token") + except Exception: + logger.critical("Fatal exception", exc_info=True) + finally: + if not self.is_closed(): + await self.close() + if self._session: + await self._session.close() + + def stop_loop_on_completion(f): + loop.stop() + + def _cancel_tasks(): + if sys.version_info < (3, 8): + task_retriever = asyncio.Task.all_tasks + else: + task_retriever = asyncio.all_tasks + + tasks = {t for t in task_retriever(loop=loop) if not t.done()} + + if not tasks: + return + + logger.info("Cleaning up after %d tasks.", len(tasks)) + for task in tasks: task.cancel() + + loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True)) + logger.info("All tasks finished cancelling.") + + for task in tasks: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler( + { + "message": "Unhandled exception during Client.run shutdown.", + "exception": task.exception(), + "task": task, + } + ) + + future = asyncio.ensure_future(runner(), loop=loop) + future.add_done_callback(stop_loop_on_completion) + try: + loop.run_forever() + except KeyboardInterrupt: + logger.info("Received signal to terminate bot and event loop.") + finally: + future.remove_done_callback(stop_loop_on_completion) + logger.info("Cleaning up tasks.") + try: - self.loop.run_until_complete(asyncio.gather(*asyncio.all_tasks(self.loop))) - except asyncio.CancelledError: - logger.debug("All pending tasks has been cancelled.") + _cancel_tasks() + if sys.version_info >= (3, 6): + loop.run_until_complete(loop.shutdown_asyncgens()) finally: - self.loop.run_until_complete(self.session.close()) - logger.error(" - Shutting down bot - ") + logger.info("Closing the event loop.") + loop.close() + + if not future.cancelled(): + try: + return future.result() + except KeyboardInterrupt: + # I am unsure why this gets raised here but suppress it anyway + return None @property def bot_owner_ids(self): @@ -1576,7 +1643,7 @@ async def autoupdate(self): elif res != "Already up to date.": logger.info("Bot has been updated.") channel = self.update_channel - if self.hosting_method == HostingMethod.PM2: + if self.hosting_method in (HostingMethod.PM2, HostingMethod.SYSTEMD): embed = discord.Embed(title="Bot has been updated", color=self.main_color) embed.set_footer( text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" diff --git a/pyproject.toml b/pyproject.toml index 60b86fdbc4..5171e27b5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.8.6' +version = '3.9.1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From b6e2dada58773bcc0f9c6724bec8fa16c4e1e7f3 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:31:51 +0800 Subject: [PATCH 319/705] Add docker hostingmethod --- CHANGELOG.md | 6 ++++++ Dockerfile | 1 + bot.py | 10 ++++++++++ core/models.py | 7 ++++--- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c83219b367..86292f94a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.2 + +### Improved + +- Additional HostingMethods (i.e. DOCKER, PM2, SCREEN). Autoupdates are now disabled on all docker instances. ([GH #2977](https://github.com/kyb3r/modmail/issues/2977), [PR #2988](https://github.com/kyb3r/modmail/pull/2988)) + # v3.9.1 ### Internal diff --git a/Dockerfile b/Dockerfile index f616ef29f3..8165e06a53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ FROM python:3.7-alpine +ENV USING_DOCKER yes WORKDIR /modmailbot COPY . /modmailbot RUN export PIP_NO_CACHE_DIR=false \ diff --git a/bot.py b/bot.py index d55971cdf8..8fe8b6d8da 100644 --- a/bot.py +++ b/bot.py @@ -112,6 +112,12 @@ def hosting_method(self) -> HostingMethod: if os.environ.get("INVOCATION_ID"): return HostingMethod.SYSTEMD + if os.environ.get("USING_DOCKER"): + return HostingMethod.DOCKER + + if os.environ.get("INVOCATION_ID"): + return HostingMethod.SYSTEMD + if os.environ.get("TERM"): return HostingMethod.SCREEN @@ -1671,6 +1677,10 @@ async def before_autoupdate(self): logger.warning("Autoupdates disabled.") self.autoupdate_loop.cancel() + if self.hosting_method == HostingMethod.DOCKER: + logger.warning("Autoupdates disabled as using Docker.") + self.autoupdate_loop.cancel() + if not self.config.get("github_token") and self.hosting_method == HostingMethod.HEROKU: logger.warning("GitHub access token not found.") logger.warning("Autoupdates disabled.") diff --git a/core/models.py b/core/models.py index 37355a488a..0238e051d4 100644 --- a/core/models.py +++ b/core/models.py @@ -276,6 +276,7 @@ class DMDisabled(IntEnum): class HostingMethod(IntEnum): HEROKU = 0 PM2 = 1 - OTHER = 2 - SYSTEMD = 3 - SCREEN = 4 + SYSTEMD = 2 + SCREEN = 3 + DOCKER = 4 + OTHER = 5 From de36b95b159f6797ceb1b40e7da22380ecdfcff3 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sat, 20 Mar 2021 00:02:32 +0100 Subject: [PATCH 320/705] Update config_help.json Change disabled to enabled, as it is enabled on a new bot creation --- core/config_help.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config_help.json b/core/config_help.json index 271e726346..e764c9255d 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -86,7 +86,7 @@ "thumbnail": "https://placehold.it/100/e74c3c?text=+" }, "user_typing": { - "default": "Disabled", + "default": "Enabled", "description": "When this is set to `yes`, whenever the recipient user starts to type in their DM channel, the moderator will see “{bot.user.display_name} is typing…” in the thread channel.", "examples": [ "`{prefix}config set user_typing yes`", From 31052354db1fe61224f5c2093946a9c9509a9cf4 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:33:16 +0800 Subject: [PATCH 321/705] Bump versions --- CHANGELOG.md | 4 ++++ bot.py | 2 +- pyproject.toml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86292f94a3..6d2ea15f89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Additional HostingMethods (i.e. DOCKER, PM2, SCREEN). Autoupdates are now disabled on all docker instances. ([GH #2977](https://github.com/kyb3r/modmail/issues/2977), [PR #2988](https://github.com/kyb3r/modmail/pull/2988)) +### Fixed + +- `user_typing` default in the config help is now correct. + # v3.9.1 ### Internal diff --git a/bot.py b/bot.py index 8fe8b6d8da..689832b73d 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.1" +__version__ = "3.9.2" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 5171e27b5e..3e4865bc8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.9.1' +version = '3.9.2' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From edf636498b9d29b706f79ec10930bc3ac2b73566 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:49:46 +0800 Subject: [PATCH 322/705] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b5dfc9b4aa..10f7baf737 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      From 20877d9ffbc87aacf3fa31a31670c8447333f621 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 31 Mar 2021 21:49:32 +0800 Subject: [PATCH 323/705] did i not commit this --- bot.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/bot.py b/bot.py index 689832b73d..d4ef7f250c 100644 --- a/bot.py +++ b/bot.py @@ -115,9 +115,6 @@ def hosting_method(self) -> HostingMethod: if os.environ.get("USING_DOCKER"): return HostingMethod.DOCKER - if os.environ.get("INVOCATION_ID"): - return HostingMethod.SYSTEMD - if os.environ.get("TERM"): return HostingMethod.SCREEN From fa6cf626fea876630f2dfad5cfa2bb019e2c8bef Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 4 Apr 2021 04:22:33 +0800 Subject: [PATCH 324/705] Update `mention` command. --- cogs/utility.py | 45 +++++++++++++++++++++++++++++++------------ core/config_help.json | 3 ++- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 8ce7af5b69..51ed2b476d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -673,41 +673,62 @@ async def ping(self, ctx): @commands.command() @checks.has_permissions(PermissionLevel.ADMINISTRATOR) - async def mention(self, ctx, *mention: Union[discord.Role, discord.Member, str]): + async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, str]): """ Change what the bot mentions at the start of each thread. - Type only `{prefix}mention` to retrieve your current "mention" message. - `{prefix}mention disable` to disable mention. - `{prefix}mention reset` to reset it to default value. + `user_or_role` may be a user ID, mention, name, role ID, mention, or name. + You can also set it to mention multiple users or roles, just separate the arguments with space. + + Examples: + - `{prefix}mention @user` + - `{prefix}mention @user @role` + - `{prefix}mention 984301093849028 388218663326449` + - `{prefix}mention everyone` + + Do not ping `@everyone` to set mention to everyone, use "everyone" or "all" instead. + + Notes: + - Type only `{prefix}mention` to retrieve your current "mention" message. + - `{prefix}mention disable` to disable mention. + - `{prefix}mention reset` to reset it to default value, which is "@here". """ current = self.bot.config["mention"] - if not mention: + if not user_or_role: embed = discord.Embed( title="Current mention:", color=self.bot.main_color, description=str(current) ) elif ( - len(mention) == 1 - and isinstance(mention[0], str) - and mention[0].lower() in ["disable", "reset"] + len(user_or_role) == 1 + and isinstance(user_or_role[0], str) + and user_or_role[0].lower() in ("disable", "reset", "all", "everyone") ): - option = mention[0].lower() + option = user_or_role[0].lower() if option == "disable": embed = discord.Embed( description=f"Disabled mention on thread creation.", color=self.bot.main_color, ) self.bot.config["mention"] = None - else: + elif option == "reset": embed = discord.Embed( description="`mention` is reset to default.", color=self.bot.main_color, ) self.bot.config.remove("mention") + else: + embed = discord.Embed( + title="Changed mention!", + description=f'On thread creation the bot now says "@everyone".', + color=self.bot.main_color, + ) + self.bot.config["mention"] = "@everyone" await self.bot.config.update() else: - for m in mention: + for m in user_or_role: if not isinstance(m, (discord.Role, discord.Member)): raise commands.BadArgument(f'Role or Member "{m}" not found.') - mention = " ".join(i.mention for i in mention) + mention = " ".join( + i.mention if i is not ctx.guild.default_role else str(i) for i in user_or_role + ) embed = discord.Embed( title="Changed mention!", description=f'On thread creation the bot now says "{mention}".', diff --git a/core/config_help.json b/core/config_help.json index e764c9255d..d430b9ee4c 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -52,7 +52,8 @@ "`{prefix}mention Yo~ Here's a new thread for ya!`" ], "notes": [ - "Unfortunately, it's not currently possible to disable mention. You do not have to include a mention." + "To disable mention, use command `{prefix}mention disable`.", + "See also: `{prefix}help mention`." ] }, "main_color": { From a4389b43192edf44547e6cc6b8e0a32b15bf9aa3 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 5 Apr 2021 10:39:57 -0400 Subject: [PATCH 325/705] Add Coolguy (Prime Servers) to SPONSORS --- SPONSORS.json | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/SPONSORS.json b/SPONSORS.json index fcabb119ac..98abe37d81 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -42,5 +42,33 @@ } ] } - } -] \ No newline at end of file + }, + { + "embed": { + "description": "Quality Hosting at Prices You Deserve!", + "color": 50195251 + "footer": { + "icon_url": "http://primeserversinc.com/images/Prime_Logo_P_Sassy.png", + "text": "Prime Servers, Inc." + }, + "thumbnail": { + "url": "http://primeserversinc.com/images/Prime_Logo_P_Sassy.png" + }, + "author": { + "name": "Prime Servers, Inc.", + "url": "https://primeserversinc.com", + "icon_url": "http://primeserversinc.com/images/Prime_Logo_P_Sassy.png" + }, + "fields": [ + { + "name": "Twitter", + "value": "[**Click Here**](https://twitter.com/PrimeServersInc)" + }, + { + "name": "Discord Server", + "value": "[**Click Here**](https://discord.gg/cYM6Urn)" + } + ] + } + }, +] From d77d47dfdecc0e20f9868c4e62ec4baee932e66d Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 5 Apr 2021 10:41:27 -0400 Subject: [PATCH 326/705] Small correction --- SPONSORS.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SPONSORS.json b/SPONSORS.json index 98abe37d81..a57ac2d60e 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -46,7 +46,7 @@ { "embed": { "description": "Quality Hosting at Prices You Deserve!", - "color": 50195251 + "color": 50195251, "footer": { "icon_url": "http://primeserversinc.com/images/Prime_Logo_P_Sassy.png", "text": "Prime Servers, Inc." @@ -70,5 +70,5 @@ } ] } - }, + } ] From b4ac84f78fd1cff8e1b83ce88660fa1242df1429 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 5 Apr 2021 10:42:25 -0400 Subject: [PATCH 327/705] Add Coolguy (Prime Servers) to SPONSORS --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 10f7baf737..19b9eed923 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,10 @@ Special thanks to our sponsors for supporting the project. + + + + Become a sponsor on [Patreon](https://patreon.com/kyber). From 4f52b685d1659d870bff2b0d8ad3bd6cc8c32698 Mon Sep 17 00:00:00 2001 From: Ralph Date: Tue, 6 Apr 2021 16:51:21 -0400 Subject: [PATCH 328/705] Update to HTTPS --- SPONSORS.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SPONSORS.json b/SPONSORS.json index a57ac2d60e..53034c57b3 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -48,16 +48,16 @@ "description": "Quality Hosting at Prices You Deserve!", "color": 50195251, "footer": { - "icon_url": "http://primeserversinc.com/images/Prime_Logo_P_Sassy.png", + "icon_url": "https://primeserversinc.com/images/Prime_Logo_P_Sassy.png", "text": "Prime Servers, Inc." }, "thumbnail": { - "url": "http://primeserversinc.com/images/Prime_Logo_P_Sassy.png" + "url": "https://primeserversinc.com/images/Prime_Logo_P_Sassy.png" }, "author": { "name": "Prime Servers, Inc.", "url": "https://primeserversinc.com", - "icon_url": "http://primeserversinc.com/images/Prime_Logo_P_Sassy.png" + "icon_url": "https://primeserversinc.com/images/Prime_Logo_P_Sassy.png" }, "fields": [ { From 4da97a7ecb5381f9568bef0e19c59df745f2b616 Mon Sep 17 00:00:00 2001 From: Ralph Date: Tue, 6 Apr 2021 16:51:45 -0400 Subject: [PATCH 329/705] Update to HTTPS --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 19b9eed923..a211cf22a0 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ Special thanks to our sponsors for supporting the project. - + From 23065593c2b03a4eb300411b90eb04ab1266871f Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Apr 2021 21:51:22 +0800 Subject: [PATCH 330/705] v3.9.3 add use_user_id_channel_name --- CHANGELOG.md | 13 +++++++++++++ bot.py | 2 +- cogs/modmail.py | 2 +- core/config.py | 2 ++ core/config_help.json | 11 +++++++++++ core/thread.py | 4 ++-- core/utils.py | 20 ++++++++++++++------ pyproject.toml | 2 +- 8 files changed, 45 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d2ea15f89..df4c140165 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.3 + +## Added + +- New config: ` use_user_id_channel_name`, when set to TRUE, channel names would get created with the recipient's ID instead of their name and discriminator. + - This is now an option to better suit the needs of servers in Server Discovery + +## Internal Change + +- Signature of `format_channel_name` in core/util.py changed to: + - `format_channel_name(bot, author, exclude_channel=None, force_null=False)` + + # v3.9.2 ### Improved diff --git a/bot.py b/bot.py index d4ef7f250c..994e956e11 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.2" +__version__ = "3.9.3" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index bd89571193..b5d48d61c2 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1490,7 +1490,7 @@ async def repair(self, ctx): if len(users) == 1: user = users.pop() name = format_channel_name( - user, self.bot.modmail_guild, exclude_channel=ctx.channel + self.bot, user, exclude_channel=ctx.channel ) recipient = self.bot.get_user(user.id) if user.id in self.bot.threads.cache: diff --git a/core/config.py b/core/config.py index 14197e112e..890b3690f1 100644 --- a/core/config.py +++ b/core/config.py @@ -50,6 +50,7 @@ class ConfigManager: "sent_emoji": "✅", "blocked_emoji": "🚫", "close_emoji": "🔒", + "use_user_id_channel_name": False, "recipient_thread_close": False, "thread_auto_close_silently": False, "thread_auto_close": isodate.Duration(), @@ -157,6 +158,7 @@ class ConfigManager: time_deltas = {"account_age", "guild_age", "thread_auto_close", "thread_cooldown"} booleans = { + "use_user_id_channel_name", "user_typing", "mod_typing", "reply_without_command", diff --git a/core/config_help.json b/core/config_help.json index e764c9255d..2aef03ccf6 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -96,6 +96,17 @@ "See also: `mod_typing`." ] }, + "use_user_id_channel_name": { + "default": "No", + "description": "When this is set to `yes`, new thread channels will be named with the recipient's ID instead of the recipient's name.", + "examples": [ + "`{prefix}config set use_user_id_channel_name yes`", + "`{prefix}config set use_user_id_channel_name no`" + ], + "notes": [ + "This config is suitable for servers in Server Discovery to comply with channel name restrictions." + ] + }, "mod_typing": { "default": "Disabled", "description": "When this is set to `yes`, whenever a moderator starts to type in the thread channel, the recipient user will see \"{bot.user.display_name} is typing…\" in their DM channel.", diff --git a/core/thread.py b/core/thread.py index 9fe23301e4..7798454958 100644 --- a/core/thread.py +++ b/core/thread.py @@ -120,7 +120,7 @@ async def setup(self, *, creator=None, category=None, initial_message=None): try: channel = await self.bot.modmail_guild.create_text_channel( - name=format_channel_name(recipient, self.bot.modmail_guild), + name=format_channel_name(self.bot, recipient), category=category, overwrites=overwrites, reason="Creating a thread channel.", @@ -129,7 +129,7 @@ async def setup(self, *, creator=None, category=None, initial_message=None): # try again but null-discrim (name could be banned) try: channel = await self.bot.modmail_guild.create_text_channel( - name=format_channel_name(recipient, self.bot.modmail_guild, force_null=True), + name=format_channel_name(self.bot, recipient, force_null=True), category=category, overwrites=overwrites, reason="Creating a thread channel.", diff --git a/core/utils.py b/core/utils.py index 8f4b152ff5..af47c8e2e6 100644 --- a/core/utils.py +++ b/core/utils.py @@ -340,15 +340,23 @@ def escape_code_block(text): return re.sub(r"```", "`\u200b``", text) -def format_channel_name(author, guild, exclude_channel=None, force_null=False): +def format_channel_name(bot, author, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names""" - name = author.name.lower() + guild = bot.modmail_guild + if force_null: - name = "null" + name = new_name = "null" + else: + if bot.config["use_user_id_channel_name"]: + name = new_name = str(author.id) + else: + name = author.name.lower() + if force_null: + name = "null" - name = new_name = ( - "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" - ) + f"-{author.discriminator}" + name = new_name = ( + "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" + ) + f"-{author.discriminator}" counter = 1 existed = set(c.name for c in guild.text_channels if c != exclude_channel) diff --git a/pyproject.toml b/pyproject.toml index 3e4865bc8c..b74dfad111 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.9.2' +version = '3.9.3' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From a0e580ccb5db20002bdc8c5d99b506d18d8bf3e2 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Apr 2021 22:25:18 +0800 Subject: [PATCH 331/705] black --- cogs/modmail.py | 4 +--- core/utils.py | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index b5d48d61c2..a45da27166 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1489,9 +1489,7 @@ async def repair(self, ctx): ) if len(users) == 1: user = users.pop() - name = format_channel_name( - self.bot, user, exclude_channel=ctx.channel - ) + name = format_channel_name(self.bot, user, exclude_channel=ctx.channel) recipient = self.bot.get_user(user.id) if user.id in self.bot.threads.cache: thread = self.bot.threads.cache[user.id] diff --git a/core/utils.py b/core/utils.py index af47c8e2e6..2dfb319a8e 100644 --- a/core/utils.py +++ b/core/utils.py @@ -355,7 +355,8 @@ def format_channel_name(bot, author, exclude_channel=None, force_null=False): name = "null" name = new_name = ( - "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" + "".join(l for l in name if l not in string.punctuation and l.isprintable()) + or "null" ) + f"-{author.discriminator}" counter = 1 From 3e4d9b019ce748eac1fb8db2aefec5f51c33c755 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 12 Apr 2021 14:56:43 +0800 Subject: [PATCH 332/705] Possibly fix emoji problem --- core/config.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/config.py b/core/config.py index 890b3690f1..30f364622d 100644 --- a/core/config.py +++ b/core/config.py @@ -47,9 +47,9 @@ class ConfigManager: # updates "update_notifications": True, # threads - "sent_emoji": "✅", - "blocked_emoji": "🚫", - "close_emoji": "🔒", + "sent_emoji": "\N{WHITE HEAVY CHECK MARK}", + "blocked_emoji": "\N{NO ENTRY SIGN}", + "close_emoji": "\N{LOCK}", "use_user_id_channel_name": False, "recipient_thread_close": False, "thread_auto_close_silently": False, @@ -93,13 +93,13 @@ class ConfigManager: "anon_tag": "Response", # react to contact "react_to_contact_message": None, - "react_to_contact_emoji": "\u2705", + "react_to_contact_emoji": "\N{WHITE HEAVY CHECK MARK}", # confirm thread creation "confirm_thread_creation": False, "confirm_thread_creation_title": "Confirm thread creation", "confirm_thread_response": "React to confirm thread creation which will directly contact the moderators", - "confirm_thread_creation_accept": "\u2705", - "confirm_thread_creation_deny": "\U0001F6AB", + "confirm_thread_creation_accept": "\N{WHITE HEAVY CHECK MARK}", + "confirm_thread_creation_deny": "\N{NO ENTRY SIGN}", # regex "use_regex_autotrigger": False, } From ac2e0c6e1423c485cebd3b50aeb44371102b1e42 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 13 Apr 2021 06:39:41 +0800 Subject: [PATCH 333/705] Cleaner code :D --- cogs/utility.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 51ed2b476d..7b39631dcd 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -701,7 +701,7 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, elif ( len(user_or_role) == 1 and isinstance(user_or_role[0], str) - and user_or_role[0].lower() in ("disable", "reset", "all", "everyone") + and user_or_role[0].lower() in ("disable", "reset") ): option = user_or_role[0].lower() if option == "disable": @@ -709,26 +709,24 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, description=f"Disabled mention on thread creation.", color=self.bot.main_color, ) self.bot.config["mention"] = None - elif option == "reset": + else: embed = discord.Embed( description="`mention` is reset to default.", color=self.bot.main_color, ) self.bot.config.remove("mention") - else: - embed = discord.Embed( - title="Changed mention!", - description=f'On thread creation the bot now says "@everyone".', - color=self.bot.main_color, - ) - self.bot.config["mention"] = "@everyone" await self.bot.config.update() else: + mention = [] + everyone = ("all", "everyone") for m in user_or_role: - if not isinstance(m, (discord.Role, discord.Member)): + if not isinstance(m, (discord.Role, discord.Member)) and m not in everyone: raise commands.BadArgument(f'Role or Member "{m}" not found.') - mention = " ".join( - i.mention if i is not ctx.guild.default_role else str(i) for i in user_or_role - ) + elif m == ctx.guild.default_role or m in everyone: + mention.append("@everyone") + continue + mention.append(m.mention) + + mention = " ".join(mention) embed = discord.Embed( title="Changed mention!", description=f'On thread creation the bot now says "{mention}".', From c74e5f4ccbf0695b545e5d362897230b24472002 Mon Sep 17 00:00:00 2001 From: codeinteger6 <44692189+codeinteger6@users.noreply.github.com> Date: Wed, 14 Apr 2021 13:25:19 +0600 Subject: [PATCH 334/705] Bump python runtime version Security update --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 67068f10fe..87665291b8 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.9.0 \ No newline at end of file +python-3.9.4 From 404decc10454eb9fe2315ae1fd04beed7dfcd3c6 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Sun, 25 Apr 2021 01:34:10 +0800 Subject: [PATCH 335/705] Update sponsors --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 10f7baf737..7a5da956f5 100644 --- a/README.md +++ b/README.md @@ -162,13 +162,19 @@ $ docker run --env-file .env kyb3rr/modmail Special thanks to our sponsors for supporting the project. +Kingdom Gaming Discord: +
      + + + +
      +
      +SirReddit: +
      - - - - +
      Become a sponsor on [Patreon](https://patreon.com/kyber). From 58e8944bdebe61d68cf0916228dd5a2ab0458e65 Mon Sep 17 00:00:00 2001 From: redstonedesigner Date: Sat, 24 Apr 2021 20:46:00 +0100 Subject: [PATCH 336/705] Add docker-compose configuration for self hosting Adds a docker-compose configuration file for running both the bot and logviewer with a shared mongo database in a single container stack. Exposes port 8000 and ensure the mongo database can not be accessed remotely. --- docker-compose.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000..7b4371b5c8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3.7" +services: + bot: + image: kyb3rr/modmail + env_file: + - .env + depends_on: + - mongo + logviewer: + image: kyb3rr/logviewer + depends_on: + - mongo + environment: + - MONGO_URI=mongodb://mongo + ports: + - 8000:8000 + mongo: + image: mongo From b145cf1ad9c0118f6d647372c3880b109f78086a Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 25 Apr 2021 21:22:31 +0800 Subject: [PATCH 337/705] Change Max Channel per Category to 49, fix fallback save logic --- core/thread.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/thread.py b/core/thread.py index 7798454958..530e063e54 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1205,16 +1205,16 @@ async def create( # Schedule thread setup for later cat = self.bot.main_category - if category is None and len(cat.channels) == 50: + if category is None and len(cat.channels) >= 49: fallback_id = self.bot.config["fallback_category_id"] if fallback_id: fallback = discord.utils.get(cat.guild.categories, id=int(fallback_id)) - if fallback and len(fallback.channels) != 50: + if fallback and len(fallback.channels) < 49: category = fallback if not category: category = await cat.clone(name="Fallback Modmail") - self.bot.config.set("fallback_category_id", category.id) + self.bot.config.set("fallback_category_id", str(category.id)) await self.bot.config.update() if (message or not manual_trigger) and self.bot.config["confirm_thread_creation"]: From b557a9bf16cfb37a78e1c932a30420cb1c551992 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 25 Apr 2021 21:37:23 +0800 Subject: [PATCH 338/705] There is now a proper message when trying to contact a bot. --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index a45da27166..87b9d91e57 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1014,7 +1014,7 @@ async def contact( embed = discord.Embed( color=self.bot.error_color, description="Cannot start a thread with a bot." ) - return await ctx.send(embed=embed, delete_afer=3) + return await ctx.send(embed=embed, delete_after=3) exists = await self.bot.threads.find(recipient=user) if exists: From ea52a8bf4079eee1293ebb2ccbef4dc45fe23416 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 25 Apr 2021 21:40:25 +0800 Subject: [PATCH 339/705] Changelog - v3.9.4 --- CHANGELOG.md | 20 ++++++++++++++++++-- bot.py | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df4c140165..ddb87eebc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,14 +6,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.4 + +## Fixed + +- Certain cases where fallback categories were not working as intended. ([GH #3002](https://github.com/kyb3r/modmail/issues/3002), [PR #3003](https://github.com/kyb3r/modmail/pull/3003)) +- There is now a proper message when trying to contact a bot.+ + +## Improved + +- `?mention` can now be disabled with `?mention disable`. ([PR #2993](https://github.com/kyb3r/modmail/pull/2993/files)) +- `?mention` now allows vague entries such as `everyone` or `all`. ([PR #2993](https://github.com/kyb3r/modmail/pull/2993/files)) + +## Internal + +- Change heroku python version to 3.9.4 [PR #3001](https://github.com/kyb3r/modmail/pull/3001) + # v3.9.3 ## Added -- New config: ` use_user_id_channel_name`, when set to TRUE, channel names would get created with the recipient's ID instead of their name and discriminator. +- New config: `use_user_id_channel_name`, when set to TRUE, channel names would get created with the recipient's ID instead of their name and discriminator. - This is now an option to better suit the needs of servers in Server Discovery -## Internal Change +## Internal - Signature of `format_channel_name` in core/util.py changed to: - `format_channel_name(bot, author, exclude_channel=None, force_null=False)` diff --git a/bot.py b/bot.py index 994e956e11..1b9a9f2c1f 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.3" +__version__ = "3.9.4" import asyncio From 5241e5469a8631d2e95e9a89329c8d6758efca14 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 25 Apr 2021 21:54:47 +0800 Subject: [PATCH 340/705] Fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddb87eebc3..de46a80f38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ## Fixed - Certain cases where fallback categories were not working as intended. ([GH #3002](https://github.com/kyb3r/modmail/issues/3002), [PR #3003](https://github.com/kyb3r/modmail/pull/3003)) -- There is now a proper message when trying to contact a bot.+ +- There is now a proper message when trying to contact a bot. ## Improved From 7ed1fcb8aafb83bc280a314643531c5c39ea72c2 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Sun, 25 Apr 2021 22:14:31 +0800 Subject: [PATCH 341/705] add fourjr claim --- CHANGELOG.md | 2 +- plugins/registry.json | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de46a80f38..12f1ddc9ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ## Internal -- Change heroku python version to 3.9.4 [PR #3001](https://github.com/kyb3r/modmail/pull/3001) +- Change heroku python version to 3.9.4 ([PR #3001](https://github.com/kyb3r/modmail/pull/3001)) # v3.9.3 diff --git a/plugins/registry.json b/plugins/registry.json index 515871e916..579c3e3eb0 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -230,5 +230,13 @@ "bot_version": "3.9.0", "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" + }, + "claim": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Allows supporters to claim thread by sending ?claim in the thread channel", + "title": "Claim Thread", + "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", + "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" } } From c1dcf7fb9264d8ebf6a658265a3a73ceb0dc4e77 Mon Sep 17 00:00:00 2001 From: redstonedesigner Date: Sun, 25 Apr 2021 15:46:49 +0100 Subject: [PATCH 342/705] Add volume for persistent data storage to Mongo --- docker-compose.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 7b4371b5c8..5d2061df6b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,3 +16,8 @@ services: - 8000:8000 mongo: image: mongo + volumes: + - mongodb:/data/db + +volumes: + mongodb: From 702486665202325687ba91eed961d2b066bb1de4 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 25 Apr 2021 20:49:11 +0200 Subject: [PATCH 343/705] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b74dfad111..ff08d3ee31 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.9.3' +version = '3.9.4' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From aec76a045571b65208b6e6203c72a16d5ef6c317 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 25 Apr 2021 20:49:44 +0200 Subject: [PATCH 344/705] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 457569b32e..ea07edb304 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      From 3717df646644159c5a0e713aa83bfcdbf768dcdb Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Tue, 27 Apr 2021 07:32:00 +0800 Subject: [PATCH 345/705] Update sponsors --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 457569b32e..ad07d59b1e 100644 --- a/README.md +++ b/README.md @@ -165,21 +165,29 @@ Special thanks to our sponsors for supporting the project. Kingdom Gaming Discord:
      - +

      SirReddit:
      - +
      - +
      +Prime Servers Inc: +
      - + + +
      +
      +Real Madrid: +
      + + - Become a sponsor on [Patreon](https://patreon.com/kyber). From b101530b72908098eb67e85bae82d1cff000fa6b Mon Sep 17 00:00:00 2001 From: Stephen <48072084+StephenDaDev@users.noreply.github.com> Date: Wed, 28 Apr 2021 07:58:49 -0400 Subject: [PATCH 346/705] Fix typo in config help. --- core/config_help.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config_help.json b/core/config_help.json index ff6be5cba1..ede81617ed 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -421,7 +421,7 @@ "default": "Thread Moved", "description": "The title of the message embed when a thread is moved.", "examples": [ - "`{prefix}config set thread_move_title Thread transferred to another channel!" + "`{prefix}config set thread_move_title Thread transferred to another channel!`" ], "notes": [ "See also: `thread_move_notify`, `thread_move_notify_mods`, `thread_move_response`." From 9bb615bba932887f4ab0474ceb4a5bde240a010b Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Wed, 28 Apr 2021 20:31:23 +0800 Subject: [PATCH 347/705] Update 'bot.py' and 'clients.py': - Fix return types, type hints, and unresolved references. --- bot.py | 7 +++++-- core/clients.py | 12 +++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index 1b9a9f2c1f..cce02ceff2 100644 --- a/bot.py +++ b/bot.py @@ -237,6 +237,7 @@ async def runner(): if self._session: await self._session.close() + # noinspection PyUnusedLocal def stop_loop_on_completion(f): loop.stop() @@ -811,7 +812,7 @@ async def is_blocked( *, channel: discord.TextChannel = None, send_message: bool = False, - ) -> typing.Tuple[bool, str]: + ) -> bool: member = self.guild.get_member(author.id) if member is None: @@ -892,7 +893,9 @@ async def get_thread_cooldown(self, author: discord.Member): return @staticmethod - async def add_reaction(msg, reaction: discord.Reaction) -> bool: + async def add_reaction( + msg, reaction: typing.Union[discord.Emoji, discord.Reaction, discord.PartialEmoji, str] + ) -> bool: if reaction != "disable": try: await msg.add_reaction(reaction) diff --git a/core/clients.py b/core/clients.py index db4e9936b4..f3b2248c67 100644 --- a/core/clients.py +++ b/core/clients.py @@ -68,7 +68,7 @@ class GitHub: def __init__(self, bot, access_token: str = "", username: str = "", **kwargs): self.bot = bot self.session = bot.session - self.headers: dict = None + self.headers: Optional[dict] = None self.access_token = access_token self.username = username self.avatar_url: str = kwargs.pop("avatar_url", "") @@ -319,7 +319,7 @@ async def get_config(self) -> dict: async def update_config(self, data: dict): return NotImplemented - async def edit_message(self, message_id: Union[int, str], new_content: str) -> None: + async def edit_message(self, message_id: Union[int, str], new_content: str): return NotImplemented async def append_log( @@ -359,6 +359,12 @@ async def edit_note(self, message_id: Union[int, str], message: str): def get_plugin_partition(self, cog): return NotImplemented + async def update_repository(self) -> dict: + return NotImplemented + + async def get_user_info(self) -> Optional[dict]: + return NotImplemented + class MongoDBClient(ApiClient): def __init__(self, bot): @@ -659,7 +665,7 @@ async def update_repository(self) -> dict: "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,}, } - async def get_user_info(self) -> dict: + async def get_user_info(self) -> Optional[dict]: try: user = await GitHub.login(self.bot) except InvalidConfigError: From 6b006129aa6fec35e893605b787b5d8afb6ade6f Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Thu, 29 Apr 2021 07:21:08 +0800 Subject: [PATCH 348/705] Update database after resetting/purging all plugins. --- cogs/plugins.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/plugins.py b/cogs/plugins.py index 94a3f425c0..bc664aef44 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -539,6 +539,7 @@ async def plugins_reset(self, ctx): except Exception: logger.error("Failed to unload plugin: %s.", ext) self.bot.config["plugins"].clear() + await self.bot.config.update() cache_path = Path(__file__).absolute().parent.parent / "temp" / "plugins-cache" if cache_path.exists(): From fbb45e37829c2f17d81e5036794d197d14d30992 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Fri, 30 Apr 2021 19:40:17 +0800 Subject: [PATCH 349/705] `plugin reset`, remove unloaded plugins from `self.loaded_plugins` --- cogs/plugins.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cogs/plugins.py b/cogs/plugins.py index bc664aef44..a01f4bc61c 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -538,6 +538,13 @@ async def plugins_reset(self, ctx): self.bot.unload_extension(ext) except Exception: logger.error("Failed to unload plugin: %s.", ext) + else: + if not self.loaded_plugins: + continue + plugin = next((p for p in self.loaded_plugins if p.ext_string == ext), None) + if plugin: + self.loaded_plugins.remove(plugin) + self.bot.config["plugins"].clear() await self.bot.config.update() From 039b4b91ae7dd9e86b6ff06f582483bab57ec1ea Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Tue, 4 May 2021 21:11:34 -0700 Subject: [PATCH 350/705] turn mentions into set --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 530e063e54..76516af8b3 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1061,7 +1061,7 @@ def get_notifications(self) -> str: self.bot.config["notification_squad"].pop(key) self.bot.loop.create_task(self.bot.config.update()) - return " ".join(mentions) + return " ".join(set(mentions)) async def set_title(self, title) -> None: user_id = match_user_id(self.channel.topic) From ef4b5b2f1a8fbea7e1e201bf8d4078bb4170395b Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 11 May 2021 21:05:51 +0800 Subject: [PATCH 351/705] Hopefully resolves #3022. --- core/thread.py | 58 ++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/core/thread.py b/core/thread.py index 530e063e54..8eccb04c02 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1115,16 +1115,16 @@ async def find( try: await thread.wait_until_ready() except asyncio.CancelledError: - logger.warning("Thread for %s cancelled, abort creating", recipient) + logger.warning("Thread for %s cancelled.", recipient) return thread else: - if not thread.channel or not self.bot.get_channel(thread.channel.id): + if not thread.cancelled and ( + not thread.channel or not self.bot.get_channel(thread.channel.id) + ): logger.warning( "Found existing thread for %s but the channel is invalid.", recipient_id ) - self.bot.loop.create_task( - thread.close(closer=self.bot.user, silent=True, delete_channel=False) - ) + await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: channel = discord.utils.get( @@ -1186,7 +1186,7 @@ async def create( try: await thread.wait_until_ready() except asyncio.CancelledError: - logger.warning("Thread for %s cancelled, abort creating", recipient) + logger.warning("Thread for %s cancelled, abort creating.", recipient) return thread else: if thread.channel and self.bot.get_channel(thread.channel.id): @@ -1195,9 +1195,7 @@ async def create( logger.warning( "Found an existing thread for %s, closing previous thread.", recipient ) - self.bot.loop.create_task( - thread.close(closer=self.bot.user, silent=True, delete_channel=False) - ) + await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = Thread(self, recipient) @@ -1231,9 +1229,11 @@ async def create( ) accept_emoji = self.bot.config["confirm_thread_creation_accept"] deny_emoji = self.bot.config["confirm_thread_creation_deny"] - await confirm.add_reaction(accept_emoji) - await asyncio.sleep(0.2) - await confirm.add_reaction(deny_emoji) + emojis = [accept_emoji, deny_emoji] + for emoji in emojis: + await confirm.add_reaction(emoji) + await asyncio.sleep(0.2) + try: r, _ = await self.bot.wait_for( "reaction_add", @@ -1245,29 +1245,31 @@ async def create( ) except asyncio.TimeoutError: thread.cancelled = True - - await confirm.remove_reaction(accept_emoji, self.bot.user) - await asyncio.sleep(0.2) - await confirm.remove_reaction(deny_emoji, self.bot.user) - await destination.send( - embed=discord.Embed( - title="Cancelled", description="Timed out", color=self.bot.error_color + self.bot.loop.create_task( + destination.send( + embed=discord.Embed( + title="Cancelled", description="Timed out", color=self.bot.error_color + ) ) ) - del self.cache[recipient.id] - return thread else: if str(r.emoji) == deny_emoji: thread.cancelled = True + self.bot.loop.create_task( + destination.send( + embed=discord.Embed(title="Cancelled", color=self.bot.error_color) + ) + ) - await confirm.remove_reaction(accept_emoji, self.bot.user) + async def remove_reactions(): + for emoji in emojis: + await confirm.remove_reaction(emoji, self.bot.user) await asyncio.sleep(0.2) - await confirm.remove_reaction(deny_emoji, self.bot.user) - await destination.send( - embed=discord.Embed(title="Cancelled", color=self.bot.error_color) - ) - del self.cache[recipient.id] - return thread + + self.bot.loop.create_task(remove_reactions()) + if thread.cancelled: + del self.cache[recipient.id] + return thread self.bot.loop.create_task( thread.setup(creator=creator, category=category, initial_message=message) From 08bc39b4c00b09a2502fbfdd1822021827668abc Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 11 May 2021 21:22:45 +0800 Subject: [PATCH 352/705] Improve contact and react to contact: - Checks if user is blocked when `?contact` command or react to contact is used. --- bot.py | 83 +++++++++++++++++++++++++------------------------ cogs/modmail.py | 37 +++++++++++++--------- 2 files changed, 65 insertions(+), 55 deletions(-) diff --git a/bot.py b/bot.py index 1b9a9f2c1f..ccececf8d6 100644 --- a/bot.py +++ b/bot.py @@ -1304,50 +1304,51 @@ async def handle_reaction_events(self, payload): except (discord.HTTPException, discord.InvalidArgument) as e: logger.warning("Failed to remove reaction: %s", e) - async def on_raw_reaction_add(self, payload): - await self.handle_reaction_events(payload) - + async def handle_react_to_contact(self, payload): react_message_id = tryint(self.config.get("react_to_contact_message")) react_message_emoji = self.config.get("react_to_contact_emoji") - if all((react_message_id, react_message_emoji)): - if payload.message_id == react_message_id: - if payload.emoji.is_unicode_emoji(): - emoji_fmt = payload.emoji.name - else: - emoji_fmt = f"<:{payload.emoji.name}:{payload.emoji.id}>" - - if emoji_fmt == react_message_emoji: - channel = self.get_channel(payload.channel_id) - member = channel.guild.get_member(payload.user_id) - if not member.bot: - message = await channel.fetch_message(payload.message_id) - await message.remove_reaction(payload.emoji, member) - await message.add_reaction(emoji_fmt) # bot adds as well - - if self.config["dm_disabled"] in ( - DMDisabled.NEW_THREADS, - DMDisabled.ALL_THREADS, - ): - embed = discord.Embed( - title=self.config["disabled_new_thread_title"], - color=self.error_color, - description=self.config["disabled_new_thread_response"], - ) - embed.set_footer( - text=self.config["disabled_new_thread_footer"], - icon_url=self.guild.icon_url, - ) - logger.info( - "A new thread using react to contact was blocked from %s due to disabled Modmail.", - member, - ) - return await member.send(embed=embed) + if ( + not all((react_message_id, react_message_emoji)) + or payload.message_id != react_message_id + ): + return + if payload.emoji.is_unicode_emoji(): + emoji_fmt = payload.emoji.name + else: + emoji_fmt = f"<:{payload.emoji.name}:{payload.emoji.id}>" - ctx = await self.get_context(message) - ctx.author = member - await ctx.invoke( - self.get_command("contact"), user=member, manual_trigger=False - ) + if emoji_fmt != react_message_emoji: + return + channel = self.get_channel(payload.channel_id) + member = channel.guild.get_member(payload.user_id) + if member.bot: + return + message = await channel.fetch_message(payload.message_id) + await message.remove_reaction(payload.emoji, member) + await message.add_reaction(emoji_fmt) # bot adds as well + + if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): + embed = discord.Embed( + title=self.config["disabled_new_thread_title"], + color=self.error_color, + description=self.config["disabled_new_thread_response"], + ) + embed.set_footer( + text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon_url, + ) + logger.info( + "A new thread using react to contact was blocked from %s due to disabled Modmail.", + member, + ) + return await member.send(embed=embed) + + ctx = await self.get_context(message) + await ctx.invoke(self.get_command("contact"), user=member, manual_trigger=False) + + async def on_raw_reaction_add(self, payload): + await asyncio.gather( + self.handle_reaction_events(payload), self.handle_react_to_contact(payload), + ) async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: diff --git a/cogs/modmail.py b/cogs/modmail.py index 87b9d91e57..08930aa946 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1002,7 +1002,7 @@ async def contact( `category`, if specified, may be a category ID, mention, or name. `user` may be a user ID, mention, or name. - `options` can be `silent` + `options` can be `silent` or `silently`. """ silent = False if isinstance(category, str): @@ -1018,19 +1018,28 @@ async def contact( exists = await self.bot.threads.find(recipient=user) if exists: - embed = discord.Embed( - color=self.bot.error_color, - description="A thread for this user already " - f"exists in {exists.channel.mention}.", - ) + desc = "A thread for this user already exists" + if exists.channel: + desc += f" in {exists.channel.mention}" + desc += "." + embed = discord.Embed(color=self.bot.error_color, description=desc) await ctx.channel.send(embed=embed, delete_after=3) else: + creator = ctx.author if manual_trigger else user + if await self.bot.is_blocked(user): + if not manual_trigger: # react to contact + return + + ref = f"{user.mention} is" if creator != user else "You are" + embed = discord.Embed( + color=self.bot.error_color, + description=f"{ref} currently blocked from contacting {self.bot.user.name}.", + ) + return await ctx.send(embed=embed) + thread = await self.bot.threads.create( - recipient=user, - creator=ctx.author, - category=category, - manual_trigger=manual_trigger, + recipient=user, creator=creator, category=category, manual_trigger=manual_trigger, ) if thread.cancelled: return @@ -1039,22 +1048,22 @@ async def contact( logger.info("Contacting user %s when Modmail DM is disabled.", user) if not silent and not self.bot.config.get("thread_contact_silently"): - if ctx.author.id == user.id: + if creator.id == user.id: description = "You have opened a Modmail thread." else: - description = f"{ctx.author.name} has opened a Modmail thread." + description = f"{creator.name} has opened a Modmail thread." em = discord.Embed( title="New Thread", description=description, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: em.timestamp = datetime.utcnow() - em.set_footer(icon_url=ctx.author.avatar_url) + em.set_footer(text=f"{creator}", icon_url=creator.avatar_url) await user.send(embed=em) embed = discord.Embed( title="Created Thread", - description=f"Thread started by {ctx.author.mention} for {user.mention}.", + description=f"Thread started by {creator.mention} for {user.mention}.", color=self.bot.main_color, ) await thread.wait_until_ready() From a6c24d952ce287bc842ddb864b26fff28bd22d3c Mon Sep 17 00:00:00 2001 From: codeinteger6 <44692189+codeinteger6@users.noreply.github.com> Date: Fri, 14 May 2021 16:12:26 +0600 Subject: [PATCH 353/705] Remove publish plugin --- plugins/registry.json | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 579c3e3eb0..b74ff1f989 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -187,15 +187,6 @@ "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" }, - "publish": { - "repository": "codeinteger6/modmail-plugins", - "branch": "master", - "description": "Publish messages sent in announcement channels.", - "bot_version": "3.5.0", - "title": "Publish", - "icon_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png", - "thumbnail_url": "https://user-images.githubusercontent.com/44692189/89184422-96de3600-d5ba-11ea-98ea-d096aa385ad5.png" - }, "translate": { "repository": "WebKide/modmail-plugins", "branch": "master", From 7073fcac2aaf1cea4cb493f450e4060d5a90362a Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Mon, 24 May 2021 15:39:30 +0800 Subject: [PATCH 354/705] Initial 3.9.5-dev1 --- CHANGELOG.md | 7 +++++++ README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12f1ddc9ef..bdb75a3ce6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.5-dev1 + +## Fixed + +- Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) +- Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/kyb3r/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/kyb3r/modmail/pull/3027)) + # v3.9.4 ## Fixed diff --git a/README.md b/README.md index ad07d59b1e..c150bae3c5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index ccececf8d6..eccdfd3868 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.4" +__version__ = "3.9.5-dev1" import asyncio diff --git a/pyproject.toml b/pyproject.toml index b74dfad111..a4d4002580 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.9.3' +version = '3.9.5-dev1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 204c5385a8d88c676d2cc7f85ce7255bdf04201d Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Mon, 31 May 2021 10:55:07 +0200 Subject: [PATCH 355/705] Update registry.json removal of profanity filter, trying to download will result in a infinite download loop and will stop any plugin from loading/break the usage of removing/adding new plugins --- plugins/registry.json | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index b74ff1f989..a9f565a013 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1,13 +1,4 @@ { - "profanity-filter": { - "repository": "kyb3r/modmail-plugins", - "branch": "master", - "description": "Checks for profanity in a message using machine learning and deletes it.", - "bot_version": "2.20.1", - "title": "Profanity Filter Plugin", - "icon_url": "https://i.imgur.com/951szZ3.jpg", - "thumbnail_url": "https://i.imgur.com/951szZ3.jpg" - }, "dragory-migrate": { "repository": "kyb3r/modmail-plugins", "branch": "master", From 5648289fa7546a090e24fa7855b3f82431cbedce Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 2 Jun 2021 21:23:05 +0800 Subject: [PATCH 356/705] Group conversation ALPHA #143 --- CHANGELOG.md | 6 ++- bot.py | 28 ++++++++--- cogs/modmail.py | 59 ++++++++++++++++++++-- core/thread.py | 128 ++++++++++++++++++++++++++++++++++-------------- core/utils.py | 26 +++++++++- 5 files changed, 197 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdb75a3ce6..c003f1db37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.9.5-dev1 +# v3.10.0-dev2 + +## Added + +- Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) ## Fixed diff --git a/bot.py b/bot.py index eccdfd3868..456e340218 100644 --- a/bot.py +++ b/bot.py @@ -964,6 +964,15 @@ async def process_dm_modmail(self, message: discord.Message) -> None: logger.error("Failed to send message:", exc_info=True) await self.add_reaction(message, blocked_emoji) else: + for user in thread.recipients: + # send to all other recipients + if user != message.author: + try: + await thread.send(message, user) + except Exception: + # silently ignore + logger.error("Failed to send message:", exc_info=True) + await self.add_reaction(message, sent_emoji) self.dispatch("thread_reply", thread, False, message, False, False) @@ -1224,9 +1233,10 @@ async def on_typing(self, channel, user, _): thread = await self.threads.find(channel=channel) if thread is not None and thread.recipient: - if await self.is_blocked(thread.recipient): - return - await thread.recipient.trigger_typing() + for user in thread.recipients: + if await self.is_blocked(user): + continue + await user.trigger_typing() async def handle_reaction_events(self, payload): user = self.get_user(payload.user_id) @@ -1286,20 +1296,22 @@ async def handle_reaction_events(self, payload): if not thread: return try: - _, linked_message = await thread.find_linked_messages( + _, *linked_message = await thread.find_linked_messages( message.id, either_direction=True ) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return - if self.config["transfer_reactions"] and linked_message is not None: + if self.config["transfer_reactions"] and linked_message is not [None]: if payload.event_type == "REACTION_ADD": - if await self.add_reaction(linked_message, reaction): - await self.add_reaction(message, reaction) + for msg in linked_message: + await self.add_reaction(msg, reaction) + await self.add_reaction(message, reaction) else: try: - await linked_message.remove_reaction(reaction, self.user) + for msg in linked_message: + await msg.remove_reaction(reaction, self.user) await message.remove_reaction(reaction, self.user) except (discord.HTTPException, discord.InvalidArgument) as e: logger.warning("Failed to remove reaction: %s", e) diff --git a/cogs/modmail.py b/cogs/modmail.py index 08930aa946..ef816a99c3 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -681,6 +681,48 @@ async def title(self, ctx, *, name: str): await ctx.message.pin() await self.bot.add_reaction(ctx.message, sent_emoji) + @commands.command(cooldown_after_parsing=True) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + @commands.cooldown(1, 600, BucketType.channel) + async def adduser(self, ctx, *, user: discord.Member): + """Adds a user to a modmail thread""" + + curr_thread = await self.bot.threads.find(recipient=user) + if curr_thread: + em = discord.Embed( + title="Error", + description=f"User is already in a thread: {curr_thread.channel.mention}.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + else: + em = discord.Embed( + title="New Thread (Group)", + description=f"{ctx.author.name} has added you to a Modmail thread.", + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url) + await user.send(embed=em) + + em = discord.Embed( + title="New User", + description=f"{ctx.author.name} has added {user.name} to the Modmail thread.", + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{user}", icon_url=user.avatar_url) + + for i in ctx.thread.recipients: + await i.send(embed=em) + + await ctx.thread.add_user(user) + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) async def logs(self, ctx, *, user: User = None): @@ -1463,15 +1505,19 @@ async def repair(self, ctx): and message.embeds[0].footer.text ): user_id = match_user_id(message.embeds[0].footer.text) + other_recipients = match_other_recipients(ctx.channel.topic) + for n, uid in enumerate(other_recipients): + other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + if user_id != -1: recipient = self.bot.get_user(user_id) if recipient is None: self.bot.threads.cache[user_id] = thread = Thread( - self.bot.threads, user_id, ctx.channel + self.bot.threads, user_id, ctx.channel, other_recipients ) else: self.bot.threads.cache[user_id] = thread = Thread( - self.bot.threads, recipient, ctx.channel + self.bot.threads, recipient, ctx.channel, other_recipients ) thread.ready = True logger.info( @@ -1516,13 +1562,18 @@ async def repair(self, ctx): await thread.channel.send(embed=embed) except discord.HTTPException: pass + + other_recipients = match_other_recipients(ctx.channel.topic) + for n, uid in enumerate(other_recipients): + other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + if recipient is None: self.bot.threads.cache[user.id] = thread = Thread( - self.bot.threads, user_id, ctx.channel + self.bot.threads, user_id, ctx.channel, other_recipients ) else: self.bot.threads.cache[user.id] = thread = Thread( - self.bot.threads, recipient, ctx.channel + self.bot.threads, recipient, ctx.channel, other_recipients ) thread.ready = True logger.info("Setting current channel's topic to User ID and created new thread.") diff --git a/core/thread.py b/core/thread.py index 8eccb04c02..5638acbe44 100644 --- a/core/thread.py +++ b/core/thread.py @@ -19,6 +19,7 @@ days, match_title, match_user_id, + match_other_recipients, truncate, format_channel_name, ) @@ -34,6 +35,7 @@ def __init__( manager: "ThreadManager", recipient: typing.Union[discord.Member, discord.User, int], channel: typing.Union[discord.DMChannel, discord.TextChannel] = None, + other_recipients: typing.List[typing.Union[discord.Member, discord.User]] = [], ): self.manager = manager self.bot = manager.bot @@ -45,6 +47,7 @@ def __init__( raise CommandError("Recipient cannot be a bot.") self._id = recipient.id self._recipient = recipient + self._other_recipients = other_recipients self._channel = channel self.genesis_message = None self._ready_event = asyncio.Event() @@ -54,7 +57,7 @@ def __init__( self._cancelled = False def __repr__(self): - return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id})' + return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipienets={len(self._other_recipients)})' async def wait_until_ready(self) -> None: """Blocks execution until the thread is fully set up.""" @@ -80,6 +83,10 @@ def channel(self) -> typing.Union[discord.TextChannel, discord.DMChannel]: def recipient(self) -> typing.Optional[typing.Union[discord.User, discord.Member]]: return self._recipient + @property + def recipients(self) -> typing.List[typing.Union[discord.User, discord.Member]]: + return [self._recipient] + self._other_recipients + @property def ready(self) -> bool: return self._ready_event.is_set() @@ -103,6 +110,23 @@ def cancelled(self, flag: bool): for i in self.wait_tasks: i.cancel() + @classmethod + async def from_channel( + cls, manager: "ThreadManager", channel: discord.TextChannel + ) -> "Thread": + recipient_id = match_user_id( + channel.topic + ) # there is a chance it grabs from another recipient's main thread + recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user( + recipient_id + ) + + other_recipients = match_other_recipients(channel.topic) + for n, uid in enumerate(other_recipients): + other_recipients[n] = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid) + + return cls(manager, recipient or recipient_id, channel, other_recipients) + async def setup(self, *, creator=None, category=None, initial_message=None): """Create the thread channel and other io related initialisation tasks""" self.bot.dispatch("thread_initiate", self, creator, category, initial_message) @@ -619,23 +643,30 @@ async def find_linked_messages( except ValueError: raise ValueError("Malformed thread message.") - async for msg in self.recipient.history(): - if either_direction: - if msg.id == joint_id: - return message1, msg + messages = [message1] + for user in self.recipients: + async for msg in user.history(): + if either_direction: + if msg.id == joint_id: + return message1, msg - if not (msg.embeds and msg.embeds[0].author.url): - continue - try: - if int(msg.embeds[0].author.url.split("#")[-1]) == joint_id: - return message1, msg - except ValueError: - continue - raise ValueError("DM message not found. Plain messages are not supported.") + if not (msg.embeds and msg.embeds[0].author.url): + continue + try: + if int(msg.embeds[0].author.url.split("#")[-1]) == joint_id: + messages.append(msg) + break + except ValueError: + continue + + if len(messages) > 1: + return messages + + raise ValueError("DM message not found.") async def edit_message(self, message_id: typing.Optional[int], message: str) -> None: try: - message1, message2 = await self.find_linked_messages(message_id) + message1, *message2 = await self.find_linked_messages(message_id) except ValueError: logger.warning("Failed to edit message.", exc_info=True) raise @@ -644,10 +675,11 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> embed1.description = message tasks = [self.bot.api.edit_message(message1.id, message), message1.edit(embed=embed1)] - if message2 is not None: - embed2 = message2.embeds[0] - embed2.description = message - tasks += [message2.edit(embed=embed2)] + if message2 is not [None]: + for m2 in message2: + embed2 = message2.embeds[0] + embed2.description = message + tasks += [m2.edit(embed=embed2)] elif message1.embeds[0].author.name.startswith("Persistent Note"): tasks += [self.bot.api.edit_note(message1.id, message)] @@ -657,14 +689,16 @@ async def delete_message( self, message: typing.Union[int, discord.Message] = None, note: bool = True ) -> None: if isinstance(message, discord.Message): - message1, message2 = await self.find_linked_messages(message1=message, note=note) + message1, *message2 = await self.find_linked_messages(message1=message, note=note) else: - message1, message2 = await self.find_linked_messages(message, note=note) + message1, *message2 = await self.find_linked_messages(message, note=note) + print(message1, message2) tasks = [] if not isinstance(message, discord.Message): tasks += [message1.delete()] - elif message2 is not None: - tasks += [message2.delete()] + elif message2 is not [None]: + for m2 in message2: + tasks += [m2.delete()] elif message1.embeds[0].author.name.startswith("Persistent Note"): tasks += [self.bot.api.delete_note(message1.id)] if tasks: @@ -750,16 +784,18 @@ async def reply( ) ) + user_msg_tasks = [] tasks = [] - try: - user_msg = await self.send( - message, - destination=self.recipient, - from_mod=True, - anonymous=anonymous, - plain=plain, + for user in self.recipients: + user_msg_tasks.append( + self.send( + message, destination=user, from_mod=True, anonymous=anonymous, plain=plain, + ) ) + + try: + user_msg = await asyncio.gather(*user_msg_tasks) except Exception as e: logger.error("Message delivery failed:", exc_info=True) if isinstance(e, discord.Forbidden): @@ -1063,9 +1099,23 @@ def get_notifications(self) -> str: return " ".join(mentions) - async def set_title(self, title) -> None: + async def set_title(self, title: str) -> None: + user_id = match_user_id(self.channel.topic) + ids = ",".join(i.id for i in self._other_recipients) + + await self.channel.edit( + topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}" + ) + + async def add_user(self, user: typing.Union[discord.Member, discord.User]) -> None: + title = match_title(self.channel.topic) user_id = match_user_id(self.channel.topic) - await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}") + self._other_recipients.append(user) + + ids = ",".join(str(i.id) for i in self._other_recipients) + await self.channel.edit( + topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}" + ) class ThreadManager: @@ -1127,11 +1177,13 @@ async def find( await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: - channel = discord.utils.get( - self.bot.modmail_guild.text_channels, topic=f"User ID: {recipient_id}" + channel = discord.utils.find( + lambda x: str(recipient_id) in x.topic if x.topic else False, + self.bot.modmail_guild.text_channels, ) + if channel: - thread = Thread(self, recipient or recipient_id, channel) + thread = await Thread.from_channel(self, channel) if thread.recipient: # only save if data is valid self.cache[recipient_id] = thread @@ -1161,10 +1213,14 @@ async def _find_from_channel(self, channel): except discord.NotFound: recipient = None + other_recipients = match_other_recipients(channel.topic) + for n, uid in enumerate(other_recipients): + other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + if recipient is None: - thread = Thread(self, user_id, channel) + thread = Thread(self, user_id, channel, other_recipients) else: - self.cache[user_id] = thread = Thread(self, recipient, channel) + self.cache[user_id] = thread = Thread(self, recipient, channel, other_recipients) thread.ready = True return thread diff --git a/core/utils.py b/core/utils.py index 2dfb319a8e..b95200cdfe 100644 --- a/core/utils.py +++ b/core/utils.py @@ -21,7 +21,9 @@ "human_join", "days", "cleanup_code", + "match_title", "match_user_id", + "match_other_recipients", "create_not_found_embed", "parse_alias", "normalize_alias", @@ -30,7 +32,6 @@ "escape_code_block", "format_channel_name", "tryint", - "match_title", ] @@ -217,6 +218,9 @@ def cleanup_code(content: str) -> str: return content.strip("` \n") +TOPIC_OTHER_RECIPIENTS_REGEX = re.compile( + r"Other Recipients:\s*((?:\d{17,21},*)+)", flags=re.IGNORECASE +) TOPIC_TITLE_REGEX = re.compile(r"\bTitle: (.*)\n(?:User ID: )\b", flags=re.IGNORECASE | re.DOTALL) TOPIC_UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) @@ -260,6 +264,26 @@ def match_user_id(text: str) -> int: return -1 +def match_other_recipients(text: str) -> int: + """ + Matches a title in the format of "Other Recipients: XXXX,XXXX" + + Parameters + ---------- + text : str + The text of the user ID. + + Returns + ------- + Optional[str] + The title if found + """ + match = TOPIC_OTHER_RECIPIENTS_REGEX.search(text) + if match is not None: + return list(map(int, match.group(1).split(","))) + return [] + + def create_not_found_embed(word, possibilities, name, n=2, cutoff=0.6) -> discord.Embed: # Single reference of Color.red() embed = discord.Embed( From 82047db09e2c726b61a3360507cf26f5c3a29474 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 2 Jun 2021 21:23:23 +0800 Subject: [PATCH 357/705] Remove debug --- cogs/utility.py | 1 - core/thread.py | 1 - 2 files changed, 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 7b39631dcd..4ac02b9073 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1780,7 +1780,6 @@ async def autotrigger_add(self, ctx, keyword, *, command): split_cmd = command.split(" ") for n in range(1, len(split_cmd) + 1): if self.bot.get_command(" ".join(split_cmd[0:n])): - print(self.bot.get_command(" ".join(split_cmd[0:n]))) valid = True break diff --git a/core/thread.py b/core/thread.py index 5638acbe44..5c1e596051 100644 --- a/core/thread.py +++ b/core/thread.py @@ -692,7 +692,6 @@ async def delete_message( message1, *message2 = await self.find_linked_messages(message1=message, note=note) else: message1, *message2 = await self.find_linked_messages(message, note=note) - print(message1, message2) tasks = [] if not isinstance(message, discord.Message): tasks += [message1.delete()] From f6b5bf73a0c603e9ade170c452bea1f1a5304785 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 2 Jun 2021 21:41:04 +0800 Subject: [PATCH 358/705] Push ver --- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c150bae3c5..9e662a7fb3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 456e340218..277050a627 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.5-dev1" +__version__ = "v3.10.0-dev2" import asyncio diff --git a/pyproject.toml b/pyproject.toml index a4d4002580..4e6959fe70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.9.5-dev1' +version = '3.10.0-dev2' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 975b15805df6fbe60b22855507de919b827208d5 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 3 Jun 2021 10:24:34 +0800 Subject: [PATCH 359/705] Fix closes for group conversations --- core/thread.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/core/thread.py b/core/thread.py index 5c1e596051..04c16661c7 100644 --- a/core/thread.py +++ b/core/thread.py @@ -502,22 +502,24 @@ async def _close( if self.bot.config["show_timestamp"]: embed.timestamp = datetime.utcnow() - if not message: - if self.id == closer.id: - message = self.bot.config["thread_self_close_response"] - else: - message = self.bot.config["thread_close_response"] - message = self.bot.formatter.format( message, closer=closer, loglink=log_url, logkey=log_data["key"] if log_data else None ) - embed.description = message footer = self.bot.config["thread_close_footer"] embed.set_footer(text=footer, icon_url=self.bot.guild.icon_url) - if not silent and self.recipient is not None: - tasks.append(self.recipient.send(embed=embed)) + if not silent: + for user in self.recipients: + if not message: + if user.id == closer.id: + message = self.bot.config["thread_self_close_response"] + else: + message = self.bot.config["thread_close_response"] + embed.description = message + + if user is not None: + tasks.append(user.send(embed=embed)) if delete_channel: tasks.append(self.channel.delete()) From e79432525fde5efe69550fa7d70bf01eb2be80d3 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Thu, 3 Jun 2021 10:41:27 +0800 Subject: [PATCH 360/705] Bump version --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c003f1db37..f83d08ca53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev2 +# v3.10.0-dev3 ## Added diff --git a/README.md b/README.md index 9e662a7fb3..9d90568bc8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 277050a627..07c654be3c 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "v3.10.0-dev2" +__version__ = "v3.10.0-dev3" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 4e6959fe70..f41c8484fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev2' +version = '3.10.0-dev3' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From e6d682bf49e95b63f67e7c8d5cd9161ddfe06642 Mon Sep 17 00:00:00 2001 From: Cyrus <54488650+RealCyGuy@users.noreply.github.com> Date: Sat, 5 Jun 2021 22:03:28 -0700 Subject: [PATCH 361/705] Update registry.json --- plugins/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index a9f565a013..36b106bbc8 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -154,7 +154,7 @@ "suggest": { "repository": "realcyguy/modmail-plugins", "branch": "master", - "description": "Send suggestions to a selected server! It even has moderation...", + "description": "Send suggestions to a selected server! It has accepting, denying, and moderation-ing.", "bot_version": "3.4.1", "title": "Suggest stuff.", "icon_url": "https://i.imgur.com/qtE7AH8.png", From 882c60e7e11fe591301fe7cf630b9577f6f09cde Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 9 Jun 2021 22:47:31 +0800 Subject: [PATCH 362/705] Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f83d08ca53..292a4f434f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) +### Internal + +- `thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. Potentially breaking if plugins depend on this behaviour. + ## Fixed - Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) From e48eed5ec8d9d577a1c0e4dcb6978739dd0d09b4 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 21 Jun 2021 05:21:42 +0800 Subject: [PATCH 363/705] Add solution to CERTIFICATE_VERIFY_FAILED --- core/clients.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/clients.py b/core/clients.py index db4e9936b4..1d4183eabb 100644 --- a/core/clients.py +++ b/core/clients.py @@ -407,14 +407,24 @@ async def setup_indexes(self): ) logger.debug("Successfully configured and verified database indexes.") - async def validate_database_connection(self): + async def validate_database_connection(self, *, ssl_retry=True): try: await self.db.command("buildinfo") except Exception as exc: logger.critical("Something went wrong while connecting to the database.") message = f"{type(exc).__name__}: {str(exc)}" logger.critical(message) - + if "CERTIFICATE_VERIFY_FAILED" in message and ssl_retry: + mongo_uri = self.bot.config["connection_uri"] + if mongo_uri is None: + mongo_uri = self.bot.config["mongo_uri"] + for _ in range(3): + logger.warning("FAILED TO VERIFY SSL CERTIFICATE, ATTEMPTING TO START WITHOUT SSL (UNSAFE).") + logger.warning("To fix this warning, check there's no proxies blocking SSL cert verification, " + "run \"Certificate.command\" on MacOS, " + "and check certifi is up to date \"pip3 install --upgrade certifi\".") + self.db = AsyncIOMotorClient(mongo_uri, tlsAllowInvalidCertificates=True).modmail_bot + return await self.validate_database_connection(ssl_retry=False) if "ServerSelectionTimeoutError" in message: logger.critical( "This may have been caused by not whitelisting " From 1a6ae31737016ee3d2c12a0dce2eb47ae40c60ab Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 26 Jun 2021 17:43:47 +0800 Subject: [PATCH 364/705] New issue forms --- .github/ISSUE_TEMPLATE/bug_report.md | 38 ---------------- .github/ISSUE_TEMPLATE/bug_report.yml | 51 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/command-request.md | 23 ---------- .github/ISSUE_TEMPLATE/config.yml | 5 +++ .github/ISSUE_TEMPLATE/feature_request.md | 23 ---------- .github/ISSUE_TEMPLATE/feature_request.yml | 46 +++++++++++++++++++ 6 files changed, 102 insertions(+), 84 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/command-request.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 28a29c07b5..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: "[BUG] bug report title here" -labels: 'maybe: bug' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**Bot Info** -Bot version (check with `@modmail about`): -Host method (Heroku, self-host, etc): - -**To Reproduce** -Steps to reproduce the behavior: -1. Who can reproduce (ex. anyone, owners)? -2. Where can it be reproduced (ex. in thread channels, recipient DM's)? -3. Done what to cause the error? -4. Any recently made changes to your bot? -5. Errored - -**Error Logs** -If your Modmail bot is online, type `@modmail debug hastebin` and include the link here. -If your Modmail bot is not online or the previous command did not generate a link, do the following: - -1. Select your *bot* application at https://dashboard.heroku.com -2. [Restart your bot](https://i.imgur.com/3FcrlKz.png) -3. Reproduce the error to populate the error logs -4. [Copy and paste the logs](https://i.imgur.com/TTrhitm.png) - -**Screenshots** -Add screenshots to help explain your problem. - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..77461f9d01 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,51 @@ +name: Bug Report +description: File a bug report +title: "[BUG]: your bug report title" +labels: "maybe: bug" +body: + - type: input + id: bot-info-version + attributes: + label: Bot Version + description: Check it with `@modmail about` + placeholder: eg. v3.9.4 + validations: + required: true + - type: dropdown + id: bot-info-hosting + attributes: + label: How are you hosting Modmail? + description: You can check it with `@modmail about` if you are unsure + options: + - Heroku + - Systemd + - PM2 + - Patreon + - Other + validations: + required: true + - type: input + id: logs + attributes: + label: Error logs + placeholder: https://hastebin.cc/placeholder + description: + "If your Modmail bot is online, type `@modmail debug hastebin` and include the link here. + If your Modmail bot is not online or the previous command did not generate a link, do the following: + + 1. Select your *bot* application at https://dashboard.heroku.com + 2. [Restart your bot](https://i.imgur.com/3FcrlKz.png) + 3. Reproduce the error to populate the error logs + 4. [Copy and paste the logs](https://i.imgur.com/TTrhitm.png)" + validations: + required: true + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: "[optional] You may add screenshots to further explain your problem." + - type: textarea + id: additional-info + attributes: + label: Additional Information + description: "[optional] You may provide additional context for us to better understand how this issue occured." \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/command-request.md b/.github/ISSUE_TEMPLATE/command-request.md deleted file mode 100644 index d3c1673a6b..0000000000 --- a/.github/ISSUE_TEMPLATE/command-request.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: Command request -about: Request a new command -title: "your title here" -labels: command-request -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Who will this benefit** -Does this feature apply to a great portion of users? - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..e9a2d9fcd4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Discord Server + url: https://discord.gg/etJNHCQ + about: Please ask hosting-related questions here before creating an issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 7cd7a506cd..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "your title here" -labels: feature-request -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Who will this benefit** -Does this feature apply to a great portion of users? - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000..87daea485a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,46 @@ +name: Feature Request +description: Suggest an idea for this project +title: "your feature request title" +labels: "feature-request" +body: + - type: textarea + id: problem-relation + attributes: + label: Is your feature request related to a problem? Please elaborate. + description: A clear and concise description of what the problem is. + placeholder: eg. I'm always frustrated when... + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + validations: + required: true + - type: checkboxes + id: complications + attributes: + label: Does your solution involve any of the following? + options: + - label: Logviewer + - label: New config option + - type: textarea + id: alternatives + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + validations: + required: true + - type: textarea + id: benefit + attributes: + label: Who will this benefit? + description: Does this feature apply to a great portion of users? + validations: + required: true + - type: textarea + id: additional-info + attributes: + label: Additional Information + description: "[optional] You may provide additional context or screenshots for us to better understand the need of the feature." From bbe4c00d5c2157c27dfb604e906a47d55887fe3e Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 26 Jun 2021 18:04:21 +0800 Subject: [PATCH 365/705] formatting --- .github/ISSUE_TEMPLATE/bug_report.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 77461f9d01..99779ab4f3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -27,15 +27,19 @@ body: - type: input id: logs attributes: - label: Error logs + label: Error Logs placeholder: https://hastebin.cc/placeholder description: "If your Modmail bot is online, type `@modmail debug hastebin` and include the link here. + If your Modmail bot is not online or the previous command did not generate a link, do the following: - 1. Select your *bot* application at https://dashboard.heroku.com - 2. [Restart your bot](https://i.imgur.com/3FcrlKz.png) - 3. Reproduce the error to populate the error logs + 1. Select your *bot* application at https://dashboard.heroku.com + + 2. [Restart your bot](https://i.imgur.com/3FcrlKz.png) + + 3. Reproduce the error to populate the error logs + 4. [Copy and paste the logs](https://i.imgur.com/TTrhitm.png)" validations: required: true @@ -48,4 +52,4 @@ body: id: additional-info attributes: label: Additional Information - description: "[optional] You may provide additional context for us to better understand how this issue occured." \ No newline at end of file + description: "[optional] You may provide additional context for us to better understand how this issue occured." From 5567071fbcd8eeabcd2044b8551b0210788ffb20 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Sat, 3 Jul 2021 06:08:31 +0800 Subject: [PATCH 366/705] Update SPONSORS.json --- SPONSORS.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SPONSORS.json b/SPONSORS.json index 53034c57b3..1f1ed56d37 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -46,7 +46,7 @@ { "embed": { "description": "Quality Hosting at Prices You Deserve!", - "color": 50195251, + "color": 3137203, "footer": { "icon_url": "https://primeserversinc.com/images/Prime_Logo_P_Sassy.png", "text": "Prime Servers, Inc." From a69d79e4db86a691957eff79bc7a99e0cb24e638 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 4 Jul 2021 18:20:51 +0800 Subject: [PATCH 367/705] fix issue template --- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 87daea485a..b6a4437f2d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,7 @@ name: Feature Request description: Suggest an idea for this project title: "your feature request title" -labels: "feature-request" +labels: "feature request" body: - type: textarea id: problem-relation From 04dc08b387f70d6e9df37bf6e059516678a91f02 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Wed, 7 Jul 2021 12:13:06 +0800 Subject: [PATCH 368/705] Update requirements system and removed poetry --- Pipfile | 40 +-- Pipfile.lock | 791 +++++++++++++++++++++---------------------- poetry.lock | 455 ------------------------- pyproject.toml | 38 --- requirements.min.txt | 16 - requirements.txt | 29 ++ runtime.txt | 1 - 7 files changed, 436 insertions(+), 934 deletions(-) delete mode 100644 poetry.lock delete mode 100644 requirements.min.txt create mode 100644 requirements.txt delete mode 100644 runtime.txt diff --git a/Pipfile b/Pipfile index f9621c3493..eeb21b15e7 100644 --- a/Pipfile +++ b/Pipfile @@ -3,31 +3,27 @@ name = "pypi" url = "https://pypi.org/simple" verify_ssl = true -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - [dev-packages] -black = "==19.10b0" -pylint = "*" -bandit = "==1.6.2" -flake8 = "*" +black = "==21.6b0" +pylint = "~=2.9.3" +bandit = "~=1.7.0" +flake8 = "~=3.9.2" [packages] -colorama = ">=0.4.0" -python-dateutil = ">=2.7.0" -emoji = ">=0.2" -uvloop = {version = ">=0.12.0",sys_platform = "!= 'win32'"} -motor = ">=2.0.0" -natural = "==0.2.0" -isodate = ">=0.6.0" -dnspython = "~=1.16.0" -parsedatetime = "==2.6" -aiohttp = ">=3.6.0,<3.7.0" -python-dotenv = ">=0.10.3" -pipenv = "*" -"discord.py" = "==1.6.0" +colorama = "~=0.4.4" +python-dateutil = "~=2.8.1" +emoji = "~=1.2.0" +uvloop = {version = ">=0.15.2",sys_platform = "!= 'win32'"} +motor = "~=2.4.0" +natural = "~=0.2.0" +isodate = "~=0.6.0" +parsedatetime = "~=2.6" +aiohttp = "==3.7.4.post0" +python-dotenv = ">=0.18.0" +"discord.py" = "==1.7.3" [scripts] bot = "python bot.py" + +[requires] +python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock index aaa491011e..cfaece3094 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,16 +1,13 @@ { "_meta": { "hash": { - "sha256": "bfe06c9fe1db25178b01413114093b26f0d32e9a90a031c048ff3ddc7b6644b7" + "sha256": "0700f9473d2588f168a63141ac5f44596d303e7a55db173968edddd0ace2e2ac" }, "pipfile-spec": 6, - "requires": {}, + "requires": { + "python_version": "3.9" + }, "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - }, { "name": "pypi", "url": "https://pypi.org/simple", @@ -21,29 +18,46 @@ "default": { "aiohttp": { "hashes": [ - "sha256:1a4160579ffbc1b69e88cb6ca8bb0fbd4947dfcbf9fb1e2a4fc4c7a4a986c1fe", - "sha256:206c0ccfcea46e1bddc91162449c20c72f308aebdcef4977420ef329c8fcc599", - "sha256:2ad493de47a8f926386fa6d256832de3095ba285f325db917c7deae0b54a9fc8", - "sha256:319b490a5e2beaf06891f6711856ea10591cfe84fe9f3e71a721aa8f20a0872a", - "sha256:470e4c90da36b601676fe50c49a60d34eb8c6593780930b1aa4eea6f508dfa37", - "sha256:60f4caa3b7f7a477f66ccdd158e06901e1d235d572283906276e3803f6b098f5", - "sha256:66d64486172b032db19ea8522328b19cfb78a3e1e5b62ab6a0567f93f073dea0", - "sha256:687461cd974722110d1763b45c5db4d2cdee8d50f57b00c43c7590d1dd77fc5c", - "sha256:698cd7bc3c7d1b82bb728bae835724a486a8c376647aec336aa21a60113c3645", - "sha256:797456399ffeef73172945708810f3277f794965eb6ec9bd3a0c007c0476be98", - "sha256:a885432d3cabc1287bcf88ea94e1826d3aec57fd5da4a586afae4591b061d40d", - "sha256:c506853ba52e516b264b106321c424d03f3ddef2813246432fa9d1cefd361c81", - "sha256:fb83326d8295e8840e4ba774edf346e87eca78ba8a89c55d2690352842c15ba5" + "sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe", + "sha256:0563c1b3826945eecd62186f3f5c7d31abb7391fedc893b7e2b26303b5a9f3fe", + "sha256:114b281e4d68302a324dd33abb04778e8557d88947875cbf4e842c2c01a030c5", + "sha256:14762875b22d0055f05d12abc7f7d61d5fd4fe4642ce1a249abdf8c700bf1fd8", + "sha256:15492a6368d985b76a2a5fdd2166cddfea5d24e69eefed4630cbaae5c81d89bd", + "sha256:17c073de315745a1510393a96e680d20af8e67e324f70b42accbd4cb3315c9fb", + "sha256:209b4a8ee987eccc91e2bd3ac36adee0e53a5970b8ac52c273f7f8fd4872c94c", + "sha256:230a8f7e24298dea47659251abc0fd8b3c4e38a664c59d4b89cca7f6c09c9e87", + "sha256:2e19413bf84934d651344783c9f5e22dee452e251cfd220ebadbed2d9931dbf0", + "sha256:393f389841e8f2dfc86f774ad22f00923fdee66d238af89b70ea314c4aefd290", + "sha256:3cf75f7cdc2397ed4442594b935a11ed5569961333d49b7539ea741be2cc79d5", + "sha256:3d78619672183be860b96ed96f533046ec97ca067fd46ac1f6a09cd9b7484287", + "sha256:40eced07f07a9e60e825554a31f923e8d3997cfc7fb31dbc1328c70826e04cde", + "sha256:493d3299ebe5f5a7c66b9819eacdcfbbaaf1a8e84911ddffcdc48888497afecf", + "sha256:4b302b45040890cea949ad092479e01ba25911a15e648429c7c5aae9650c67a8", + "sha256:515dfef7f869a0feb2afee66b957cc7bbe9ad0cdee45aec7fdc623f4ecd4fb16", + "sha256:547da6cacac20666422d4882cfcd51298d45f7ccb60a04ec27424d2f36ba3eaf", + "sha256:5df68496d19f849921f05f14f31bd6ef53ad4b00245da3195048c69934521809", + "sha256:64322071e046020e8797117b3658b9c2f80e3267daec409b350b6a7a05041213", + "sha256:7615dab56bb07bff74bc865307aeb89a8bfd9941d2ef9d817b9436da3a0ea54f", + "sha256:79ebfc238612123a713a457d92afb4096e2148be17df6c50fb9bf7a81c2f8013", + "sha256:7b18b97cf8ee5452fa5f4e3af95d01d84d86d32c5e2bfa260cf041749d66360b", + "sha256:932bb1ea39a54e9ea27fc9232163059a0b8855256f4052e776357ad9add6f1c9", + "sha256:a00bb73540af068ca7390e636c01cbc4f644961896fa9363154ff43fd37af2f5", + "sha256:a5ca29ee66f8343ed336816c553e82d6cade48a3ad702b9ffa6125d187e2dedb", + "sha256:af9aa9ef5ba1fd5b8c948bb11f44891968ab30356d65fd0cc6707d989cd521df", + "sha256:bb437315738aa441251214dad17428cafda9cdc9729499f1d6001748e1d432f4", + "sha256:bdb230b4943891321e06fc7def63c7aace16095be7d9cf3b1e01be2f10fba439", + "sha256:c6e9dcb4cb338d91a73f178d866d051efe7c62a7166653a91e7d9fb18274058f", + "sha256:cffe3ab27871bc3ea47df5d8f7013945712c46a3cc5a95b6bee15887f1675c22", + "sha256:d012ad7911653a906425d8473a1465caa9f8dea7fcf07b6d870397b774ea7c0f", + "sha256:d9e13b33afd39ddeb377eff2c1c4f00544e191e1d1dee5b6c51ddee8ea6f0cf5", + "sha256:e4b2b334e68b18ac9817d828ba44d8fcb391f6acb398bcc5062b14b2cbeac970", + "sha256:e54962802d4b8b18b6207d4a927032826af39395a3bd9196a5af43fc4e60b009", + "sha256:f705e12750171c0ab4ef2a3c76b9a4024a62c4103e3a55dd6f99265b9bc6fcfc", + "sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a", + "sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95" ], "index": "pypi", - "version": "==3.6.3" - }, - "appdirs": { - "hashes": [ - "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", - "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" - ], - "version": "==1.4.4" + "version": "==3.7.4.post0" }, "async-timeout": { "hashes": [ @@ -55,25 +69,19 @@ }, "attrs": { "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.3.0" - }, - "certifi": { - "hashes": [ - "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", - "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" + "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", + "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" ], - "version": "==2020.12.5" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==21.2.0" }, "chardet": { "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", + "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" ], - "version": "==3.0.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.0.0" }, "colorama": { "hashes": [ @@ -85,48 +93,27 @@ }, "discord.py": { "hashes": [ - "sha256:3df148daf6fbcc7ab5b11042368a3cd5f7b730b62f09fb5d3cbceff59bcfbb12", - "sha256:ba8be99ff1b8c616f7b6dcb700460d0222b29d4c11048e74366954c465fdd05f" + "sha256:462cd0fe307aef8b29cbfa8dd613e548ae4b2cb581d46da9ac0d46fb6ea19408", + "sha256:c6f64db136de0e18e090f6752ea68bdd4ab0a61b82dfe7acecefa22d6477bb0c" ], "index": "pypi", - "version": "==1.6.0" - }, - "distlib": { - "hashes": [ - "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb", - "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1" - ], - "version": "==0.3.1" - }, - "dnspython": { - "hashes": [ - "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", - "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d" - ], - "index": "pypi", - "version": "==1.16.0" + "version": "==1.7.3" }, "emoji": { "hashes": [ - "sha256:e42da4f8d648f8ef10691bc246f682a1ec6b18373abfd9be10ec0b398823bd11" + "sha256:496f432058567985838c13d67dde84ca081614a8286c0b9cdc7d63dfa89d51a3", + "sha256:6b19b65da8d6f30551eead1705539cc0eadcd9e33a6ecbc421a29b87f96287eb" ], "index": "pypi", - "version": "==0.6.0" - }, - "filelock": { - "hashes": [ - "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", - "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" - ], - "version": "==3.0.12" + "version": "==1.2.0" }, "idna": { "hashes": [ - "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16", - "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1" + "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", + "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3" ], - "markers": "python_version >= '3.4'", - "version": "==3.1" + "markers": "python_version >= '3.5'", + "version": "==3.2" }, "isodate": { "hashes": [ @@ -138,34 +125,54 @@ }, "motor": { "hashes": [ - "sha256:428d94750123d19fcd0a89b8671ff9b4656f205217bad9f44161748c64c5fc80", - "sha256:f1692b760d834707e3477996ce8d407af8cd61c1a2abedbf81c22ef14675e61a" + "sha256:1196db507142ef8f00d953efa2f37b39335ef2d72af6ce4fbccfd870b65c5e9f", + "sha256:839c11a43897dbec8e5ba0e87a9c9b877239803126877b2efa5cef89aa6b687a" ], "index": "pypi", - "version": "==2.3.0" + "version": "==2.4.0" }, "multidict": { "hashes": [ - "sha256:1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", - "sha256:275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", - "sha256:3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", - "sha256:4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", - "sha256:5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", - "sha256:51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", - "sha256:5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", - "sha256:6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", - "sha256:7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", - "sha256:9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", - "sha256:c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", - "sha256:d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", - "sha256:e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", - "sha256:f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", - "sha256:fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", - "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", - "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" + "sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a", + "sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93", + "sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632", + "sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656", + "sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79", + "sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7", + "sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d", + "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5", + "sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224", + "sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26", + "sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea", + "sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348", + "sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6", + "sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76", + "sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1", + "sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f", + "sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952", + "sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a", + "sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37", + "sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9", + "sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359", + "sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8", + "sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da", + "sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3", + "sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d", + "sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf", + "sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841", + "sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d", + "sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93", + "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f", + "sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647", + "sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635", + "sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456", + "sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda", + "sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5", + "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281", + "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80" ], - "markers": "python_version >= '3.5'", - "version": "==4.7.6" + "markers": "python_version >= '3.6'", + "version": "==5.1.0" }, "natural": { "hashes": [ @@ -182,82 +189,74 @@ "index": "pypi", "version": "==2.6" }, - "pipenv": { - "hashes": [ - "sha256:4ab2f60742184d851ac44b9e1d423afe71dc2ea7a68bde07eb890c8b4ce5a420", - "sha256:8253fe6f9cfb3791a54da8a0571f73c918cb3457dd908684c1800a13a06ec4c1" - ], - "index": "pypi", - "version": "==2020.11.15" - }, "pymongo": { "hashes": [ - "sha256:019ddf7ced8e42cc6c8c608927c799be8097237596c94ffe551f6ef70e55237e", - "sha256:047c325c4a96e7be7d11acf58639bcf71a81ca212d9c6590e3369bc28678647a", - "sha256:047cc2007b280672ddfdf2e7b862aad8d898f481f65bbc9067bfa4e420a019a9", - "sha256:061d59f525831c4051af0b6dbafa62b0b8b168d4ef5b6e3c46d0811b8499d100", - "sha256:082832a59da18efab4d9148cca396451bac99da9757f31767f706e828b5b8500", - "sha256:0a53a751d977ad02f1bd22ddb6288bb4816c4758f44a50225462aeeae9cbf6a0", - "sha256:1222025db539641071a1b67f6950f65a6342a39db5b454bf306abd6954f1ad8a", - "sha256:1580fad512c678b720784e5c9018621b1b3bd37fb5b1633e874738862d6435c7", - "sha256:202ea1d4edc8a5439fc179802d807b49e7e563207fea5610779e56674ac770c6", - "sha256:21d7b48567a1c80f9266e0ab61c1218a31279d911da345679188733e354f81cc", - "sha256:264843ce2af0640994a4331148ef5312989bc004678c457460758766c9b4decc", - "sha256:270a1f6a331eac3a393090af06df68297cb31a8b2df0bdcbd97dc613c5758e78", - "sha256:29a6840c2ac778010547cad5870f3db2e080ad7fad01197b07fff993c08692c8", - "sha256:3646c2286d889618d43e01d9810ac1fc17709d2b4dec61366df5edc8ba228b3e", - "sha256:36b9b98a39565a8f33803c81569442b35e749a72fb1aa7d0bcdb1a33052f8bcc", - "sha256:3ec8f8e106a1476659d8c020228b45614daabdbdb6c6454a843a1d4f77d13339", - "sha256:422069f2cebf58c9dd9e8040b4768f7be4f228c95bc4505e8fa8e7b4f7191ad8", - "sha256:44376a657717de8847d5d71a9305f3595c7e78c91ac77edbb87058d12ede87a6", - "sha256:45728e6aae3023afb5b2829586d1d2bfd9f0d71cfd7d3c924b71a5e9aef617a8", - "sha256:46792b71ab802d9caf1fc9d52e83399ef8e1a36e91eef4d827c06e36b8df2230", - "sha256:4942a5659ae927bb764a123a6409870ca5dd572d83b3bfb71412c9a191bbf792", - "sha256:4be4fe9d18523da98deeb0b554ac76e1dc1562ee879d62572b34dda8593efcc1", - "sha256:523804bd8fcb5255508052b50073a27c701b90a73ea46e29be46dad5fe01bde6", - "sha256:540dafd6f4a0590fc966465c726b80fa7c0804490c39786ef29236fe68c94401", - "sha256:5980509801cbd2942df31714d055d89863684b4de26829c349362e610a48694e", - "sha256:5ad7b96c27acd7e256b33f47cf3d23bd7dd902f9c033ae43f32ffcbc37bebafd", - "sha256:6122470dfa61d4909b75c98012c1577404ba4ab860d0095e0c6980560cb3711f", - "sha256:6175fd105da74a09adb38f93be96e1f64873294c906e5e722cbbc5bd10c44e3b", - "sha256:646d4d30c5aa7c0ddbfe9b990f0f77a88621024a21ad0b792bd9d58caa9611f0", - "sha256:6700e251c6396cc05d7460dc05ef8e19e60a7b53b62c007725b48e123aaa2b1c", - "sha256:6aac7e0e8de92f11a410eb68c24a2decbac6f094e82fd95d22546d0168e7a18b", - "sha256:6e7a6057481a644970e43475292e1c0af095ca39a20fe83781196bd6e6690a38", - "sha256:76579fcf77052b39796fe4a11818d1289dd48cffe15951b3403288fa163c29f6", - "sha256:7e69fa025a1db189443428f345fea5555d16413df6addc056e17bb8c9794b006", - "sha256:7f0c507e1f108790840d6c4b594019ebf595025c324c9f7e9c9b2b15b41f884e", - "sha256:813db97e9955b6b1b50b5cebd18cb148580603bb9b067ea4c5cc656b333bc906", - "sha256:82d5ded5834b6c92380847860eb28dcaf20b847a27cee5811c4aaceef87fd280", - "sha256:82f6e42ba40440a7e0a20bfe12465a3b62d65966a4c7ad1a21b36ffff88de6fe", - "sha256:8d669c720891781e7c82d412cad39f9730ef277e3957b48a3344dae47d3caa03", - "sha256:944ed467feb949e103555863fa934fb84216a096b0004ca364d3ddf9d18e2b9e", - "sha256:96c6aef7ffb0d37206c0342abb82d874fa8cdc344267277ec63f562b94335c22", - "sha256:9be785bd4e1ba0148fb00ca84e4dbfbd1c74df3af3a648559adc60b0782f34de", - "sha256:9d19843568df9d263dc92ae4cc2279879add8a26996473f9155590cac635b321", - "sha256:a118a1df7280ffab7fe0f3eab325868339ff1c4d5b8e0750db0f0a796da8f849", - "sha256:b4294ddf76452459433ecfa6a93258608b5e462c76ef15e4695ed5e2762f009f", - "sha256:b50af6701b4a5288b77fb4db44a363aa9485caf2c3e7a40c0373fd45e34440af", - "sha256:b875bb4b438931dce550e170bfb558597189b8d0160f4ac60f14a21955161699", - "sha256:b95d2c2829b5956bf54d9a22ffec911dea75abf0f0f7e0a8a57423434bfbde91", - "sha256:c046e09e886f4539f8626afba17fa8f2e6552731f9384e2827154e3e3b7fda4e", - "sha256:c1d1992bbdf363b22b5a9543ab7d7c6f27a1498826d50d91319b803ddcf1142e", - "sha256:c2b67881392a9e85aa108e75f62cdbe372d5a3f17ea5f8d3436dcf4662052f14", - "sha256:c6cf288c9e03195d8e12b72a6388b32f18a5e9c2545622417a963e428e1fe496", - "sha256:c812b6e53344e92f10f12235219fb769c491a4a87a02c9c3f93fe632e493bda8", - "sha256:cc421babc687dc52ce0fc19787b2404518ca749d9db59576100946ff886f38ed", - "sha256:ce53c00be204ec4428d3c1f3c478ae89d388efec575544c27f57b61e9fa4a7f2", - "sha256:ce9964c117cbe5cf6269f30a2b334d28675956e988b7dbd0b4f7370924afda2e", - "sha256:d6f82e86896a8db70e8ae8fa4b7556a0f188f1d8a6c53b2ba229889d55a59308", - "sha256:d9d3ae537f61011191b2fd6f8527b9f9f8a848b37d4c85a0f7bb28004c42b546", - "sha256:e565d1e4388765c135052717f15f9e0314f9d172062444c6b3fc0002e93ed04b", - "sha256:ed98683d8f01f1c46ef2d02469e04e9a8fe9a73a9741a4e6e66677a73b59bec8", - "sha256:ef18aa15b1aa18c42933deed5233b3284186e9ed85c25d2704ceff5099a3964c", - "sha256:fa741e9c805567239f845c7e9a016aff797f9bb02ff9bc8ccd2fbd9eafefedd4", - "sha256:fc4946acb6cdada08f60aca103b61334995523da65be5fe816ea8571c9967d46", - "sha256:fcc66d17a3363b7bd6d2655de8706e25a3cd1be2bd1b8e8d8a5c504a6ef893ae" - ], - "version": "==3.11.2" + "sha256:03be7ad107d252bb7325d4af6309fdd2c025d08854d35f0e7abc8bf048f4245e", + "sha256:071552b065e809d24c5653fcc14968cfd6fde4e279408640d5ac58e3353a3c5f", + "sha256:08b8723248730599c9803ae4c97b8f3f76c55219104303c88cb962a31e3bb5ee", + "sha256:08bda7b2c522ff9f1e554570da16298271ebb0c56ab9699446aacba249008988", + "sha256:0aaf4d44f1f819360f9432df538d54bbf850f18152f34e20337c01b828479171", + "sha256:0cabfc297f4cf921f15bc789a8fbfd7115eb9f813d3f47a74b609894bc66ab0d", + "sha256:13acf6164ead81c9fc2afa0e1ea6d6134352973ce2bb35496834fee057063c04", + "sha256:15b083d1b789b230e5ac284442d9ecb113c93f3785a6824f748befaab803b812", + "sha256:161fcd3281c42f644aa8dec7753cca2af03ce654e17d76da4f0dab34a12480ca", + "sha256:1a994a42f49dab5b6287e499be7d3d2751776486229980d8857ad53b8333d469", + "sha256:20d75ea11527331a2980ab04762a9d960bcfea9475c54bbeab777af880de61cd", + "sha256:225c61e08fe517aede7912937939e09adf086c8e6f7e40d4c85ad678c2c2aea3", + "sha256:3135dd574ef1286189f3f04a36c8b7a256376914f8cbbce66b94f13125ded858", + "sha256:3491c7de09e44eded16824cb58cf9b5cc1dc6f066a0bb7aa69929d02aa53b828", + "sha256:3551912f5c34d8dd7c32c6bb00ae04192af47f7b9f653608f107d19c1a21a194", + "sha256:38a7b5140a48fc91681cdb5cb95b7cd64640b43d19259fdd707fa9d5a715f2b2", + "sha256:3a3498a8326111221560e930f198b495ea6926937e249f475052ffc6893a6680", + "sha256:3bfc7689a1bacb9bcd2f2d5185d99507aa29f667a58dd8adaa43b5a348139e46", + "sha256:421d13523d11c57f57f257152bc4a6bb463aadf7a3918e9c96fefdd6be8dbfb8", + "sha256:424799c71ff435094e5fb823c40eebb4500f0e048133311e9c026467e8ccebac", + "sha256:474e21d0e07cd09679e357d1dac76e570dab86665e79a9d3354b10a279ac6fb3", + "sha256:4c7e8c8e1e1918dcf6a652ac4b9d87164587c26fd2ce5dd81e73a5ab3b3d492f", + "sha256:506a6dab4c7ffdcacdf0b8e70bd20eb2e77fa994519547c9d88d676400fcad58", + "sha256:510cd3bfabb63a07405b7b79fae63127e34c118b7531a2cbbafc7a24fd878594", + "sha256:517ba47ca04a55b1f50ee8df9fd97f6c37df5537d118fb2718952b8623860466", + "sha256:539d4cb1b16b57026999c53e5aab857fe706e70ae5310cc8c232479923f932e6", + "sha256:5c36428cc4f7fae56354db7f46677fd21222fc3cb1e8829549b851172033e043", + "sha256:5db59223ed1e634d842a053325f85f908359c6dac9c8ddce8ef145061fae7df8", + "sha256:5e606846c049ed40940524057bfdf1105af6066688c0e6a1a3ce2038589bae70", + "sha256:6060794aac9f7b0644b299f46a9c6cbc0bc470bd01572f4134df140afd41ded6", + "sha256:62c29bc36a6d9be68fe7b5aaf1e120b4aa66a958d1e146601fcd583eb12cae7b", + "sha256:73326b211e7410c8bd6a74500b1e3f392f39cf10862e243d00937e924f112c01", + "sha256:78f07961f4f214ea8e80be63cffd5cc158eb06cd922ffbf6c7155b11728f28f9", + "sha256:7c97554ea521f898753d9773891d0347ebfaddcc1dee2ad94850b163171bf1f1", + "sha256:8898f6699f740ca93a0879ed07d8e6db02d68af889d0ebb3d13ab017e6b1af1e", + "sha256:8a41fdc751dc4707a4fafb111c442411816a7c225ebb5cadb57599534b5d5372", + "sha256:8e0004b0393d72d76de94b4792a006cb960c1c65c7659930fbf9a81ce4341982", + "sha256:977b1d4f868986b4ba5d03c317fde4d3b66e687d74473130cd598e3103db34fa", + "sha256:9a4f6e0b01df820ba9ed0b4e618ca83a1c089e48d4f268d0e00dcd49893d4549", + "sha256:9b9298964389c180a063a9e8bac8a80ed42de11d04166b20249bfa0a489e0e0f", + "sha256:a08c8b322b671857c81f4c30cd3c8df2895fd3c0e9358714f39e0ef8fb327702", + "sha256:ad31f184dcd3271de26ab1f9c51574afb99e1b0e484ab1da3641256b723e4994", + "sha256:aff3656af2add93f290731a6b8930b23b35c0c09569150130a58192b3ec6fc61", + "sha256:b2f41261b648cf5dee425f37ff14f4ad151c2f24b827052b402637158fd056ef", + "sha256:b413117210fa6d92664c3d860571e8e8727c3e8f2ff197276c5d0cb365abd3ad", + "sha256:b7efc7e7049ef366777cfd35437c18a4166bb50a5606a1c840ee3b9624b54fc9", + "sha256:b8f94acd52e530a38f25e4d5bf7ddfdd4bea9193e718f58419def0d4406b58d3", + "sha256:d0a70151d7de8a3194cdc906bcc1a42e14594787c64b0c1c9c975e5a2af3e251", + "sha256:d360e5d5dd3d55bf5d1776964625018d85b937d1032bae1926dd52253decd0db", + "sha256:d4e62417e89b717a7bcd8576ac3108cd063225942cc91c5b37ff5465fdccd386", + "sha256:d65bac5f6724d9ea6f0b5a0f0e4952fbbf209adcf6b5583b54c54bd2fcd74dc0", + "sha256:e02beaab433fd1104b2804f909e694cfbdb6578020740a9051597adc1cd4e19f", + "sha256:e4b631688dfbdd61b5610e20b64b99d25771c6d52d9da73349342d2a0f11c46a", + "sha256:e4e9db78b71db2b1684ee4ecc3e32c4600f18cdf76e6b9ae03e338e52ee4b168", + "sha256:eb4d176394c37a76e8b0afe54b12d58614a67a60a7f8c0dd3a5afbb013c01092", + "sha256:f08665d3cc5abc2f770f472a9b5f720a9b3ab0b8b3bb97c7c1487515e5653d39", + "sha256:f3d851af3852f16ad4adc7ee054fd9c90a7a5063de94d815b7f6a88477b9f4c6", + "sha256:f4ba58157e8ae33ee86fadf9062c506e535afd904f07f9be32731f4410a23b7f", + "sha256:f664ed7613b8b18f0ce5696b146776266a038c19c5cd6efffa08ecc189b01b73", + "sha256:f947b359cc4769af8b49be7e37af01f05fcf15b401da2528021148e4a54426d1", + "sha256:fe4189846448df013cd9df11bba38ddf78043f8c290a9f06430732a7a8601cce", + "sha256:fea5cb1c63efe1399f0812532c7cf65458d38fd011be350bc5021dfcac39fba8", + "sha256:fedf0dee7a412ca6d1d6d92c158fe9cbaa8ea0cae90d268f9ccc0744de7a97d0", + "sha256:fffff7bfb6799a763d3742c59c6ee7ffadda21abed557637bc44ed1080876484" + ], + "version": "==3.11.4" }, "python-dateutil": { "hashes": [ @@ -269,73 +268,87 @@ }, "python-dotenv": { "hashes": [ - "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e", - "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0" + "sha256:dd8fe852847f4fbfadabf6183ddd4c824a9651f02d51714fa075c95561959c7d", + "sha256:effaac3c1e58d89b3ccb4d04a40dc7ad6e0275fda25fd75ae9d323e2465e202d" ], "index": "pypi", - "version": "==0.15.0" + "version": "==0.18.0" }, "six": { "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==1.15.0" - }, - "uvloop": { - "hashes": [ - "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", - "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", - "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", - "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", - "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", - "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", - "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", - "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", - "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362" + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "sys_platform != 'win32'", - "version": "==0.14.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" }, - "virtualenv": { + "typing-extensions": { "hashes": [ - "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c", - "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b" + "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", + "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", + "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.2" + "version": "==3.10.0.0" }, - "virtualenv-clone": { + "uvloop": { "hashes": [ - "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", - "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" + "sha256:114543c84e95df1b4ff546e6e3a27521580466a30127f12172a3278172ad68bc", + "sha256:19fa1d56c91341318ac5d417e7b61c56e9a41183946cc70c411341173de02c69", + "sha256:2bb0624a8a70834e54dde8feed62ed63b50bad7a1265c40d6403a2ac447bce01", + "sha256:42eda9f525a208fbc4f7cecd00fa15c57cc57646c76632b3ba2fe005004f051d", + "sha256:44cac8575bf168601424302045234d74e3561fbdbac39b2b54cc1d1d00b70760", + "sha256:6de130d0cb78985a5d080e323b86c5ecaf3af82f4890492c05981707852f983c", + "sha256:7ae39b11a5f4cec1432d706c21ecc62f9e04d116883178b09671aa29c46f7a47", + "sha256:90e56f17755e41b425ad19a08c41dc358fa7bf1226c0f8e54d4d02d556f7af7c", + "sha256:b45218c99795803fb8bdbc9435ff7f54e3a591b44cd4c121b02fa83affb61c7c", + "sha256:e5e5f855c9bf483ee6cd1eb9a179b740de80cb0ae2988e3fa22309b78e2ea0e7" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.5.4" + "index": "pypi", + "markers": "sys_platform != 'win32'", + "version": "==0.15.2" }, "yarl": { "hashes": [ - "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", - "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593", - "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2", - "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8", - "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d", - "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692", - "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02", - "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a", - "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8", - "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6", - "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511", - "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e", - "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a", - "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb", - "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f", - "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", - "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" + "sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e", + "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434", + "sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366", + "sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3", + "sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec", + "sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959", + "sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e", + "sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c", + "sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6", + "sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a", + "sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6", + "sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424", + "sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e", + "sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f", + "sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50", + "sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2", + "sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc", + "sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4", + "sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970", + "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10", + "sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0", + "sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406", + "sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896", + "sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643", + "sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721", + "sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478", + "sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724", + "sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e", + "sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8", + "sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96", + "sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25", + "sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76", + "sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2", + "sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2", + "sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c", + "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a", + "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71" ], - "markers": "python_version >= '3.5'", - "version": "==1.5.1" + "markers": "python_version >= '3.6'", + "version": "==1.6.3" } }, "develop": { @@ -348,110 +361,95 @@ }, "astroid": { "hashes": [ - "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", - "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" - ], - "markers": "python_version >= '3.5'", - "version": "==2.4.2" - }, - "attrs": { - "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" + "sha256:38b95085e9d92e2ca06cf8b35c12a74fa81da395a6f9e65803742e6509c05892", + "sha256:606b2911d10c3dcf35e58d2ee5c97360e8477d7b9f3efc3f24811c93e6fc2cd9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.3.0" + "markers": "python_version ~= '3.6'", + "version": "==2.6.2" }, "bandit": { "hashes": [ - "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952", - "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065" + "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07", + "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608" ], "index": "pypi", - "version": "==1.6.2" + "version": "==1.7.0" }, "black": { "hashes": [ - "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", - "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539" + "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04", + "sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7" ], "index": "pypi", - "version": "==19.10b0" + "version": "==21.6b0" }, "click": { "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" + "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a", + "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==7.1.2" - }, - "colorama": { - "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" - ], - "index": "pypi", - "version": "==0.4.4" + "markers": "python_version >= '3.6'", + "version": "==8.0.1" }, "flake8": { "hashes": [ - "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839", - "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b" + "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", + "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" ], "index": "pypi", - "version": "==3.8.4" + "version": "==3.9.2" }, "gitdb": { "hashes": [ - "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", - "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" + "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0", + "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005" ], "markers": "python_version >= '3.4'", - "version": "==4.0.5" + "version": "==4.0.7" }, "gitpython": { "hashes": [ - "sha256:42dbefd8d9e2576c496ed0059f3103dcef7125b9ce16f9d5f9c834aed44a1dac", - "sha256:867ec3dfb126aac0f8296b19fb63b8c4a399f32b4b6fafe84c4b10af5fa9f7b5" + "sha256:b838a895977b45ab6f0cc926a9045c8d1c44e2b653c1fcc39fe91f42c6e8f05b", + "sha256:fce760879cd2aebd2991b3542876dc5c4a909b30c9d69dfc488e504a8db37ee8" ], - "markers": "python_version >= '3.4'", - "version": "==3.1.12" + "markers": "python_version >= '3.6'", + "version": "==3.1.18" }, "isort": { "hashes": [ - "sha256:c729845434366216d320e936b8ad6f9d681aab72dc7cbc2d51bedc3582f3ad1e", - "sha256:fff4f0c04e1825522ce6949973e83110a6e907750cd92d128b0d14aaaadbffdc" + "sha256:83510593e07e433b77bd5bff0f6f607dbafa06d1a89022616f02d8b699cfcd56", + "sha256:8e2c107091cfec7286bc0f68a547d0ba4c094d460b732075b6fba674f1035c0c" ], - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==5.7.0" + "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", + "version": "==5.9.1" }, "lazy-object-proxy": { "hashes": [ - "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", - "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", - "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", - "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", - "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", - "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", - "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", - "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", - "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", - "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", - "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", - "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", - "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", - "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", - "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", - "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", - "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", - "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", - "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", - "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", - "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.4.3" + "sha256:17e0967ba374fc24141738c69736da90e94419338fd4c7c7bef01ee26b339653", + "sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61", + "sha256:22ddd618cefe54305df49e4c069fa65715be4ad0e78e8d252a33debf00f6ede2", + "sha256:24a5045889cc2729033b3e604d496c2b6f588c754f7a62027ad4437a7ecc4837", + "sha256:410283732af311b51b837894fa2f24f2c0039aa7f220135192b38fcc42bd43d3", + "sha256:4732c765372bd78a2d6b2150a6e99d00a78ec963375f236979c0626b97ed8e43", + "sha256:489000d368377571c6f982fba6497f2aa13c6d1facc40660963da62f5c379726", + "sha256:4f60460e9f1eb632584c9685bccea152f4ac2130e299784dbaf9fae9f49891b3", + "sha256:5743a5ab42ae40caa8421b320ebf3a998f89c85cdc8376d6b2e00bd12bd1b587", + "sha256:85fb7608121fd5621cc4377a8961d0b32ccf84a7285b4f1d21988b2eae2868e8", + "sha256:9698110e36e2df951c7c36b6729e96429c9c32b3331989ef19976592c5f3c77a", + "sha256:9d397bf41caad3f489e10774667310d73cb9c4258e9aed94b9ec734b34b495fd", + "sha256:b579f8acbf2bdd9ea200b1d5dea36abd93cabf56cf626ab9c744a432e15c815f", + "sha256:b865b01a2e7f96db0c5d12cfea590f98d8c5ba64ad222300d93ce6ff9138bcad", + "sha256:bf34e368e8dd976423396555078def5cfc3039ebc6fc06d1ae2c5a65eebbcde4", + "sha256:c6938967f8528b3668622a9ed3b31d145fab161a32f5891ea7b84f6b790be05b", + "sha256:d1c2676e3d840852a2de7c7d5d76407c772927addff8d742b9808fe0afccebdf", + "sha256:d7124f52f3bd259f510651450e18e0fd081ed82f3c08541dffc7b94b883aa981", + "sha256:d900d949b707778696fdf01036f58c9876a0d8bfe116e8d220cfd4b15f14e741", + "sha256:ebfd274dcd5133e0afae738e6d9da4323c3eb021b3e13052d8cbd0e457b1256e", + "sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93", + "sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.6.0" }, "mccabe": { "hashes": [ @@ -460,6 +458,13 @@ ], "version": "==0.6.1" }, + "mypy-extensions": { + "hashes": [ + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + ], + "version": "==0.4.3" + }, "pathspec": { "hashes": [ "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd", @@ -469,115 +474,132 @@ }, "pbr": { "hashes": [ - "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9", - "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00" + "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd", + "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4" ], "markers": "python_version >= '2.6'", - "version": "==5.5.1" + "version": "==5.6.0" }, "pycodestyle": { "hashes": [ - "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", - "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" + "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", + "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.6.0" + "version": "==2.7.0" }, "pyflakes": { "hashes": [ - "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", - "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" + "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", + "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.2.0" + "version": "==2.3.1" }, "pylint": { "hashes": [ - "sha256:bb4a908c9dadbc3aac18860550e870f58e1a02c9f2c204fdf5693d73be061210", - "sha256:bfe68f020f8a0fece830a22dd4d5dddb4ecc6137db04face4c3420a46a52239f" + "sha256:23a1dc8b30459d78e9ff25942c61bb936108ccbe29dd9e71c01dc8274961709a", + "sha256:5d46330e6b8886c31b5e3aba5ff48c10f4aa5e76cbf9002c6544306221e63fbc" ], "index": "pypi", - "version": "==2.6.0" + "version": "==2.9.3" }, "pyyaml": { "hashes": [ - "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", - "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", - "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", - "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e", - "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", - "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", - "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", - "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", - "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", - "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", - "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", - "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", - "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" - ], - "version": "==5.3.1" + "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", + "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", + "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", + "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", + "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", + "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", + "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", + "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", + "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", + "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", + "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", + "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", + "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", + "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", + "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", + "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", + "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", + "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", + "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", + "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", + "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", + "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", + "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==5.4.1" }, "regex": { "hashes": [ - "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538", - "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4", - "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc", - "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa", - "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444", - "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1", - "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af", - "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8", - "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9", - "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88", - "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba", - "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364", - "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e", - "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7", - "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0", - "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31", - "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683", - "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee", - "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b", - "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884", - "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c", - "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e", - "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562", - "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85", - "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c", - "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6", - "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d", - "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b", - "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70", - "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b", - "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b", - "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f", - "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0", - "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5", - "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5", - "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f", - "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e", - "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512", - "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d", - "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917", - "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f" - ], - "version": "==2020.11.13" + "sha256:0eb2c6e0fcec5e0f1d3bcc1133556563222a2ffd2211945d7b1480c1b1a42a6f", + "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad", + "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a", + "sha256:1c78780bf46d620ff4fff40728f98b8afd8b8e35c3efd638c7df67be2d5cddbf", + "sha256:2366fe0479ca0e9afa534174faa2beae87847d208d457d200183f28c74eaea59", + "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d", + "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895", + "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4", + "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3", + "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222", + "sha256:422dec1e7cbb2efbbe50e3f1de36b82906def93ed48da12d1714cabcd993d7f0", + "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c", + "sha256:4f64fc59fd5b10557f6cd0937e1597af022ad9b27d454e182485f1db3008f417", + "sha256:564a4c8a29435d1f2256ba247a0315325ea63335508ad8ed938a4f14c4116a5d", + "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d", + "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761", + "sha256:59c00bb8dd8775473cbfb967925ad2c3ecc8886b3b2d0c90a8e2707e06c743f0", + "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026", + "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854", + "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb", + "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d", + "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068", + "sha256:89e5528803566af4df368df2d6f503c84fbfb8249e6631c7b025fe23e6bd0cde", + "sha256:99d8ab206a5270c1002bfcf25c51bf329ca951e5a169f3b43214fdda1f0b5f0d", + "sha256:9a854b916806c7e3b40e6616ac9e85d3cdb7649d9e6590653deb5b341a736cec", + "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa", + "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd", + "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b", + "sha256:cbe23b323988a04c3e5b0c387fe3f8f363bf06c0680daf775875d979e376bd26", + "sha256:ccb3d2190476d00414aab36cca453e4596e8f70a206e2aa8db3d495a109153d2", + "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f", + "sha256:db2b7df831c3187a37f3bb80ec095f249fa276dbe09abd3d35297fc250385694", + "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0", + "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407", + "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874", + "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035", + "sha256:ed693137a9187052fc46eedfafdcb74e09917166362af4cc4fddc3b31560e93d", + "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c", + "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5", + "sha256:f9392a4555f3e4cb45310a65b403d86b589adc773898c25a39184b1ba4db8985", + "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58" + ], + "version": "==2021.7.6" }, "six": { "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==1.15.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" }, "smmap": { "hashes": [ - "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", - "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" + "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182", + "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==3.0.4" + "markers": "python_version >= '3.5'", + "version": "==4.0.0" }, "stevedore": { "hashes": [ @@ -592,44 +614,9 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, - "typed-ast": { - "hashes": [ - "sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1", - "sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d", - "sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6", - "sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd", - "sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37", - "sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151", - "sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07", - "sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440", - "sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70", - "sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496", - "sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea", - "sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400", - "sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc", - "sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606", - "sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc", - "sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581", - "sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412", - "sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a", - "sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2", - "sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787", - "sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f", - "sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937", - "sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64", - "sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487", - "sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b", - "sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41", - "sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a", - "sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3", - "sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166", - "sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10" - ], - "version": "==1.4.2" - }, "wrapt": { "hashes": [ "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 4aa8248546..0000000000 --- a/poetry.lock +++ /dev/null @@ -1,455 +0,0 @@ -[[package]] -category = "main" -description = "Async http client/server framework (asyncio)" -name = "aiohttp" -optional = false -python-versions = ">=3.5.3" -version = "3.6.2" - -[package.dependencies] -async-timeout = ">=3.0,<4.0" -attrs = ">=17.3.0" -chardet = ">=2.0,<4.0" -multidict = ">=4.5,<5.0" -yarl = ">=1.0,<2.0" - -[[package]] -category = "dev" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -name = "appdirs" -optional = false -python-versions = "*" -version = "1.4.4" - -[[package]] -category = "dev" -description = "An abstract syntax tree for Python with inference support." -name = "astroid" -optional = false -python-versions = ">=3.5" -version = "2.4.1" - -[package.dependencies] -lazy-object-proxy = ">=1.4.0,<1.5.0" -six = ">=1.12,<2.0" -wrapt = ">=1.11,<2.0" - -[package.dependencies.typed-ast] -python = "<3.8" -version = ">=1.4.0,<1.5" - -[[package]] -category = "main" -description = "Timeout context manager for asyncio programs" -name = "async-timeout" -optional = false -python-versions = ">=3.5.3" -version = "3.0.1" - -[[package]] -category = "main" -description = "Classes Without Boilerplate" -name = "attrs" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "19.3.0" - -[[package]] -category = "dev" -description = "Security oriented static analyser for python code." -name = "bandit" -optional = false -python-versions = "*" -version = "1.6.2" - -[package.dependencies] -GitPython = ">=1.0.1" -PyYAML = ">=3.13" -colorama = ">=0.3.9" -six = ">=1.10.0" -stevedore = ">=1.20.0" - -[[package]] -category = "dev" -description = "The uncompromising code formatter." -name = "black" -optional = false -python-versions = ">=3.6" -version = "19.10b0" - -[package.dependencies] -appdirs = "*" -attrs = ">=18.1.0" -click = ">=6.5" -pathspec = ">=0.6,<1" -regex = "*" -toml = ">=0.9.4" -typed-ast = ">=1.4.0" - -[[package]] -category = "main" -description = "Universal encoding detector for Python 2 and 3" -name = "chardet" -optional = false -python-versions = "*" -version = "3.0.4" - -[[package]] -category = "dev" -description = "Composable command line interface toolkit" -name = "click" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "7.1.2" - -[[package]] -category = "main" -description = "Cross-platform colored terminal text." -name = "colorama" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.4.3" - -[[package]] -category = "main" -description = "A Python wrapper for the Discord API" -name = "discord.py" -optional = false -python-versions = ">=3.5.3" -version = "1.3.3" - -[package.dependencies] -aiohttp = ">=3.6.0,<3.7.0" -websockets = ">=6.0,<7.0 || >7.0,<8.0 || >8.0,<8.0.1 || >8.0.1,<9.0" - -[[package]] -category = "main" -description = "DNS toolkit" -name = "dnspython" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.16.0" - -[[package]] -category = "main" -description = "Emoji for Python" -name = "emoji" -optional = false -python-versions = "*" -version = "0.5.4" - -[[package]] -category = "main" -description = "Backport of the concurrent.futures package from Python 3.2" -name = "futures" -optional = true -python-versions = "*" -version = "3.1.1" - -[[package]] -category = "dev" -description = "Git Object Database" -name = "gitdb" -optional = false -python-versions = ">=3.4" -version = "4.0.5" - -[package.dependencies] -smmap = ">=3.0.1,<4" - -[[package]] -category = "dev" -description = "Python Git Library" -name = "gitpython" -optional = false -python-versions = ">=3.4" -version = "3.1.3" - -[package.dependencies] -gitdb = ">=4.0.1,<5" - -[[package]] -category = "main" -description = "Internationalized Domain Names in Applications (IDNA)" -name = "idna" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.9" - -[[package]] -category = "main" -description = "An ISO 8601 date/time/duration parser and formatter" -name = "isodate" -optional = false -python-versions = "*" -version = "0.6.0" - -[package.dependencies] -six = "*" - -[[package]] -category = "dev" -description = "A Python utility / library to sort Python imports." -name = "isort" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "4.3.21" - -[[package]] -category = "dev" -description = "A fast and thorough lazy object proxy." -name = "lazy-object-proxy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.4.3" - -[[package]] -category = "dev" -description = "McCabe checker, plugin for flake8" -name = "mccabe" -optional = false -python-versions = "*" -version = "0.6.1" - -[[package]] -category = "main" -description = "Non-blocking MongoDB driver for Tornado or asyncio" -name = "motor" -optional = true -python-versions = "*" -version = "2.1.0" - -[package.dependencies] -futures = "*" -pymongo = ">=3.10,<4" - -[[package]] -category = "main" -description = "multidict implementation" -name = "multidict" -optional = false -python-versions = ">=3.5" -version = "4.7.6" - -[[package]] -category = "main" -description = "Convert data to their natural (human-readable) format" -name = "natural" -optional = false -python-versions = "*" -version = "0.2.0" - -[package.dependencies] -six = "*" - -[[package]] -category = "main" -description = "Parse human-readable date/time text." -name = "parsedatetime" -optional = false -python-versions = "*" -version = "2.6" - -[[package]] -category = "dev" -description = "Utility library for gitignore style pattern matching of file paths." -name = "pathspec" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.8.0" - -[[package]] -category = "dev" -description = "Python Build Reasonableness" -name = "pbr" -optional = false -python-versions = "*" -version = "5.4.5" - -[[package]] -category = "dev" -description = "python code static checker" -name = "pylint" -optional = false -python-versions = ">=3.5.*" -version = "2.5.2" - -[package.dependencies] -astroid = ">=2.4.0,<=2.5" -colorama = "*" -isort = ">=4.2.5,<5" -mccabe = ">=0.6,<0.7" -toml = ">=0.7.1" - -[[package]] -category = "main" -description = "Python driver for MongoDB " -name = "pymongo" -optional = true -python-versions = "*" -version = "3.10.1" - -[[package]] -category = "main" -description = "Extensions to the standard Python datetime module" -name = "python-dateutil" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -version = "2.8.1" - -[package.dependencies] -six = ">=1.5" - -[[package]] -category = "main" -description = "Add .env support to your django/flask apps in development and deployments" -name = "python-dotenv" -optional = false -python-versions = "*" -version = "0.10.5" - -[[package]] -category = "dev" -description = "YAML parser and emitter for Python" -name = "pyyaml" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "5.3.1" - -[[package]] -category = "dev" -description = "Alternative regular expression module, to replace re." -name = "regex" -optional = false -python-versions = "*" -version = "2020.6.7" - -[[package]] -category = "main" -description = "Python 2 and 3 compatibility utilities" -name = "six" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.15.0" - -[[package]] -category = "dev" -description = "A pure Python implementation of a sliding window memory map manager" -name = "smmap" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.0.4" - -[[package]] -category = "dev" -description = "Manage dynamic plugins for Python applications" -name = "stevedore" -optional = false -python-versions = ">=3.6" -version = "2.0.0" - -[package.dependencies] -pbr = ">=2.0.0,<2.1.0 || >2.1.0" - -[[package]] -category = "dev" -description = "Python Library for Tom's Obvious, Minimal Language" -name = "toml" -optional = false -python-versions = "*" -version = "0.10.1" - -[[package]] -category = "dev" -description = "a fork of Python 2 and 3 ast modules with type comment support" -name = "typed-ast" -optional = false -python-versions = "*" -version = "1.4.1" - -[[package]] -category = "main" -description = "Fast implementation of asyncio event loop on top of libuv" -name = "uvloop" -optional = false -python-versions = "*" -version = "0.14.0" - -[[package]] -category = "main" -description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -name = "websockets" -optional = false -python-versions = ">=3.6.1" -version = "8.1" - -[[package]] -category = "dev" -description = "Module for decorators, wrappers and monkey patching." -name = "wrapt" -optional = false -python-versions = "*" -version = "1.12.1" - -[[package]] -category = "main" -description = "Yet another URL library" -name = "yarl" -optional = false -python-versions = ">=3.5" -version = "1.4.2" - -[package.dependencies] -idna = ">=2.0" -multidict = ">=4.0" - -[extras] -mongodb = ["motor"] - -[metadata] -content-hash = "68d5c15e62c4bf5f65fd3b0a9a2586b15557f724c3de5b756534bacd52cbfe40" -python-versions = "^3.7" - -[metadata.hashes] -aiohttp = ["1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", "259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", "2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", "32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", "344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", "460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", "4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", "50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", "6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", "65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", "ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", "b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965"] -appdirs = ["7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", "a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"] -astroid = ["4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1", "d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38"] -async-timeout = ["0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"] -attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] -bandit = ["336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952", "41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"] -black = ["1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", "c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"] -chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] -click = ["d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"] -colorama = ["7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", "e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"] -"discord.py" = ["406871b06d86c3dc49fba63238519f28628dac946fef8a0e22988ff58ec05580", "ad00e34c72d2faa8db2157b651d05f3c415d7d05078e7e41dc9e8dc240051beb"] -dnspython = ["36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", "f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"] -emoji = ["60652d3a2dcee5b8af8acb097c31776fb6d808027aeb7221830f72cdafefc174"] -futures = ["3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b", "51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd", "c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f"] -gitdb = ["91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"] -gitpython = ["e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a", "ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac"] -idna = ["7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", "a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"] -isodate = ["2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", "aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"] -isort = ["54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", "6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"] -lazy-object-proxy = ["0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", "194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", "1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", "4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", "48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", "5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", "59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", "8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", "9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", "9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", "97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", "9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", "a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", "a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", "ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", "cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", "d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", "d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", "eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", "efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"] -mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] -motor = ["599719bc6dcddc3b9ea4e09659fb0073d5fadcc24735999b2902f48cef33f909", "756c587985d166166e644ccd36fb8b586fb987eb42fc0fc60cce9a3d76d809b4", "97b4fc0a00a84df30f866d18693c503eef46c7642f75218a2c44d74d835be38a"] -multidict = ["1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", "275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", "3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", "4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", "5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", "51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", "5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", "6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", "7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", "9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", "c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", "d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", "e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", "f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", "fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", "fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d"] -natural = ["18c83662d2d33fd7e6eee4e3b0d7366e1ce86225664e3127a2aaf0a3233f7df2"] -parsedatetime = ["4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455", "cb96edd7016872f58479e35879294258c71437195760746faffedb692aef000b"] -pathspec = ["7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", "da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"] -pbr = ["07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c", "579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"] -pylint = ["b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c", "dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b"] -pymongo = ["01b4e10027aef5bb9ecefbc26f5df3368ce34aef81df43850f701e716e3fe16d", "0fc5aa1b1acf7f61af46fe0414e6a4d0c234b339db4c03a63da48599acf1cbfc", "1396eb7151e0558b1f817e4b9d7697d5599e5c40d839a9f7270bd90af994ad82", "18e84a3ec5e73adcb4187b8e5541b2ad61d716026ed9863267e650300d8bea33", "19adf2848b80cb349b9891cc854581bbf24c338be9a3260e73159bdeb2264464", "20ee0475aa2ba437b0a14806f125d696f90a8433d820fb558fdd6f052acde103", "26798795097bdeb571f13942beef7e0b60125397811c75b7aa9214d89880dd1d", "26e707a4eb851ec27bb969b5f1413b9b2eac28fe34271fa72329100317ea7c73", "2a3c7ad01553b27ec553688a1e6445e7f40355fb37d925c11fcb50b504e367f8", "2f07b27dbf303ea53f4147a7922ce91a26b34a0011131471d8aaf73151fdee9a", "316f0cf543013d0c085e15a2c8abe0db70f93c9722c0f99b6f3318ff69477d70", "31d11a600eea0c60de22c8bdcb58cda63c762891facdcb74248c36713240987f", "334ef3ffd0df87ea83a0054454336159f8ad9c1b389e19c0032d9cb8410660e6", "358ba4693c01022d507b96a980ded855a32dbdccc3c9331d0667be5e967f30ed", "3a6568bc53103df260f5c7d2da36dffc5202b9a36c85540bba1836a774943794", "444bf2f44264578c4085bb04493bfed0e5c1b4fe7c2704504d769f955cc78fe4", "47a00b22c52ee59dffc2aad02d0bbfb20c26ec5b8de8900492bf13ad6901cf35", "4c067db43b331fc709080d441cb2e157114fec60749667d12186cc3fc8e7a951", "4c092310f804a5d45a1bcaa4191d6d016c457b6ed3982a622c35f729ff1c7f6b", "53b711b33134e292ef8499835a3df10909c58df53a2a0308f598c432e9a62892", "568d6bee70652d8a5af1cd3eec48b4ca1696fb1773b80719ebbd2925b72cb8f6", "56fa55032782b7f8e0bf6956420d11e2d4e9860598dfe9c504edec53af0fc372", "5a2c492680c61b440272341294172fa3b3751797b1ab983533a770e4fb0a67ac", "61235cc39b5b2f593086d1d38f3fc130b2d125bd8fc8621d35bc5b6bdeb92bd2", "619ac9aaf681434b4d4718d1b31aa2f0fce64f2b3f8435688fcbdc0c818b6c54", "6238ac1f483494011abde5286282afdfacd8926659e222ba9b74c67008d3a58c", "63752a72ca4d4e1386278bd43d14232f51718b409e7ac86bcf8810826b531113", "6fdc5ccb43864065d40dd838437952e9e3da9821b7eac605ba46ada77f846bdf", "7abc3a6825a346fa4621a6f63e3b662bbb9e0f6ffc32d30a459d695f20fb1a8b", "7aef381bb9ae8a3821abd7f9d4d93978dbd99072b48522e181baeffcd95b56ae", "80df3caf251fe61a3f0c9614adc6e2bfcffd1cd3345280896766712fb4b4d6d7", "95f970f34b59987dee6f360d2e7d30e181d58957b85dff929eee4423739bd151", "993257f6ca3cde55332af1f62af3e04ca89ce63c08b56a387cdd46136c72f2fa", "9c0a57390549affc2b5dda24a38de03a5c7cbc58750cd161ff5d106c3c6eec80", "a0794e987d55d2f719cc95fcf980fc62d12b80e287e6a761c4be14c60bd9fecc", "a3b98121e68bf370dd8ea09df67e916f93ea95b52fc010902312168c4d1aff5d", "a60756d55f0887023b3899e6c2923ba5f0042fb11b1d17810b4e07395404f33e", "a676bd2fbc2309092b9bbb0083d35718b5420af3a42135ebb1e4c3633f56604d", "a732838c78554c1257ff2492f5c8c4c7312d0aecd7f732149e255f3749edd5ee", "ad3dc88dfe61f0f1f9b99c6bc833ea2f45203a937a18f0d2faa57c6952656012", "ae65d65fde4135ef423a2608587c9ef585a3551fc2e4e431e7c7e527047581be", "b070a4f064a9edb70f921bfdc270725cff7a78c22036dd37a767c51393fb956f", "b6da85949aa91e9f8c521681344bd2e163de894a5492337fba8b05c409225a4f", "bbf47110765b2a999803a7de457567389253f8670f7daafb98e059c899ce9764", "bd9c1e6f92b4888ae3ef7ae23262c513b962f09f3fb3b48581dde5df7d7a860a", "c06b3f998d2d7160db58db69adfb807d2ec307e883e2f17f6b87a1ef6c723f11", "c318fb70542be16d3d4063cde6010b1e4d328993a793529c15a619251f517c39", "c4aef42e5fa4c9d5a99f751fb79caa880dac7eaf8a65121549318b984676a1b7", "c9ca545e93a9c2a3bdaa2e6e21f7a43267ff0813e8055adf2b591c13164c0c57", "da2c3220eb55c4239dd8b982e213da0b79023cac59fe54ca09365f2bc7e4ad32", "dd8055da300535eefd446b30995c0813cc4394873c9509323762a93e97c04c03", "e2b46e092ea54b732d98c476720386ff2ccd126de1e52076b470b117bff7e409", "e334c4f39a2863a239d38b5829e442a87f241a92da9941861ee6ec5d6380b7fe", "e5c54f04ca42bbb5153aec5d4f2e3d9f81e316945220ac318abd4083308143f5", "f4d06764a06b137e48db6d569dc95614d9d225c89842c885669ee8abc9f28c7a", "f96333f9d2517c752c20a35ff95de5fc2763ac8cdb1653df0f6f45d281620606"] -python-dateutil = ["73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"] -python-dotenv = ["440c7c23d53b7d352f9c94d6f70860242c2f071cf5c029dd661ccb22d64ae42b", "f254bfd0c970d64ccbb6c9ebef3667ab301a71473569c991253a481f1c98dddc"] -pyyaml = ["06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", "240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", "4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", "69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", "73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", "74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", "7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", "95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", "b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", "cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", "d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"] -regex = ["150125da109fccdcc8fec3b0b386b2a5d6ca7cff076f8b622486d1ca868b0c10", "163bc0805e46acfa098dfc8c0b07f371577d505f603e48afc425ff475cdac3a5", "20c513893ff80bdbe4b4ce11ea2e93d49481f05b270595d82af69ffc402010a6", "21fc17cb868c4264f0813f992f46f9ae6fc8c309d4741091de4153bd1f6a6176", "2c928bc8e0c453d73dffa3193a6e37ee752ea36df0dd4601e21024d98274dfad", "2d9beca70e36f9c60d679e108c5fe49f3d4da79d13a13f91e5e759443bd954f9", "5735f26cacdb50b3d6d35ebf8fdeb504bd8b381e2d079d2d9f12ce534fc14ecd", "6edc5c190248d3b612f2cca45448cf8ebc3621d41afcd1c5708853cbb1dbb3b3", "7606dba82435429641efe4fbc580574942f89cf2b9c5c1f8bc1eab2bacbf7e8b", "8d1ee3796795e609ef7a3a5a35eaf4728038d986aa12c06b3fd1b92ee81911f4", "8d9bb2d90e23c51aacbc58c1a11320f49b335cd67a91986cdbebcc3e843e4de8", "97d414c41f19fd2362e493810caa8445c05e0a2d63a14081c972aad66284a8d2", "9e37502817225ee99d91d8418f5119e98c380b00e772d06915690c05290f32ee", "af7209b2fcc79ee2b0ad4ea080d70bb748450ec4f282cc9e864861e469b1072e", "c0849b0864ff451f04c8afb5fc28e9ed592262e03debdd227cf0f53e04a55dcd", "c4ac9215650688e78dea29b46adbdafb7b85058eebe92ef6ea848e14466c915f", "dcda6d4e1bbfc939b177c237aee41c9678eaaf71df482688f8986e8251e12345", "dd8501b8d9ea1aba53c4bc7d47bc72933f9b4213d534cf400f16c1431f51c8ba", "ec0e509ed1877ff1cbc6f0864689bb60384a303502c4d72d9a635f8a4676fd3f", "f6c8c3f56fef719180464855346e6e80971b86dfd9e5a0e356664b5baca53072", "ffd4f80602490a309064cf2b203e220d581c51660e01055c64bf5da450485ee6"] -six = ["30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"] -smmap = ["54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"] -stevedore = ["001e90cd704be6470d46cc9076434e2d0d566c1379187e7013eb296d3a6032d9", "471c920412265cc809540ae6fb01f3f02aba89c79bbc7091372f4745a50f9691"] -toml = ["926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", "bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"] -typed-ast = ["0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", "0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", "249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", "24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", "269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", "4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", "498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", "4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", "6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", "715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", "73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", "8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", "8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", "aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", "bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", "c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", "d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", "d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", "d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", "fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", "fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"] -uvloop = ["08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd", "123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e", "4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09", "4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726", "afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891", "b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7", "bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5", "e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"] -websockets = ["0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", "1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", "20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", "295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", "2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", "3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", "3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", "3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", "4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", "5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", "5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", "751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", "7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", "965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", "9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", "9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", "c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", "c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", "ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", "d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", "e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", "f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"] -wrapt = ["b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"] -yarl = ["0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", "0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", "2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", "25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", "26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", "308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", "3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", "58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", "5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", "6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", "944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", "a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", "a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", "c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", "c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", "d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", "e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2"] diff --git a/pyproject.toml b/pyproject.toml index ff08d3ee31..a920956e85 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,41 +18,3 @@ exclude = ''' )/ ) ''' - -[tool.poetry] -name = 'Modmail' -version = '3.9.4' -description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." -license = 'AGPL-3.0-only' -authors = [ - 'kyb3r ', - '4jr ', - 'Taki ' -] -readme = 'README.md' -repository = 'https://github.com/kyb3r/modmail' -homepage = 'https://github.com/kyb3r/modmail' -keywords = ['discord', 'modmail'] - -[tool.poetry.dependencies] -python = "^3.7" -"discord.py" = "discord.py==1.6.0" -uvloop = {version = ">=0.12.0", markers = "sys_platform != 'win32'"} -python-dotenv = ">=0.10.3" -parsedatetime = "^2.6" -dnspython = "^1.16" -isodate = "^0.6.0" -natural = "^0.2.0" -motor = {version = "^2.1", optional = true} -emoji = "^0.5.4" -python-dateutil = "^2.8" -colorama = "^0.4.3" -aiohttp = ">=3.6.0,<3.7.0" - -[tool.poetry.dev-dependencies] -black = {version = "=19.10b0", allow-prereleases = true} -pylint = "^2.4" -bandit = "^1.6" - -[tool.poetry.extras] -mongodb = ["motor"] diff --git a/requirements.min.txt b/requirements.min.txt deleted file mode 100644 index d756599661..0000000000 --- a/requirements.min.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Generated as of March, 2021 -# This is the bare minimum requirements.txt for running Modmail. -# To install requirements.txt run: pip install -r requirements.min.txt - -aiohttp==3.6.2 -discord.py==1.6.0 -dnspython==1.16.0 -emoji==0.5.4 -isodate==0.6.0 -motor==2.1.0 -natural==0.2.0 -parsedatetime==2.6 -pymongo==3.10.1 -python-dateutil==2.8.1 -python-dotenv==0.14.0 -websockets==8.1 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..7e1360e73e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,29 @@ +# +# These requirements were autogenerated by pipenv +# To regenerate from the project's Pipfile, run: +# +# pipenv lock --requirements +# + +-i https://pypi.org/simple +aiohttp==3.7.4.post0 +async-timeout==3.0.1; python_full_version >= '3.5.3' +attrs==21.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +colorama==0.4.4 +discord.py==1.7.3 +emoji==1.2.0 +idna==3.2; python_version >= '3.5' +isodate==0.6.0 +motor==2.4.0 +multidict==5.1.0; python_version >= '3.6' +natural==0.2.0 +parsedatetime==2.6 +pymongo==3.11.4 +python-dateutil==2.8.1 +python-dotenv==0.18.0 +six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +typing-extensions==3.10.0.0 +uvloop==0.15.2; sys_platform != 'win32' +wheel==0.36.2 +yarl==1.6.3; python_version >= '3.6' diff --git a/runtime.txt b/runtime.txt deleted file mode 100644 index 87665291b8..0000000000 --- a/runtime.txt +++ /dev/null @@ -1 +0,0 @@ -python-3.9.4 From f976165e8274a683c349c381ebbeabc851d7f915 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Wed, 7 Jul 2021 12:42:32 +0800 Subject: [PATCH 369/705] Sort pipfile --- Pipfile | 16 ++++++++-------- Pipfile.lock | 10 +++++----- bot.py | 4 ++-- requirements.txt | 3 +-- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Pipfile b/Pipfile index eeb21b15e7..5c1d2f8670 100644 --- a/Pipfile +++ b/Pipfile @@ -4,23 +4,23 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -black = "==21.6b0" -pylint = "~=2.9.3" bandit = "~=1.7.0" +black = "==21.6b0" flake8 = "~=3.9.2" +pylint = "~=2.9.3" [packages] +aiohttp = "==3.7.4.post0" colorama = "~=0.4.4" -python-dateutil = "~=2.8.1" +"discord.py" = "==1.7.3" emoji = "~=1.2.0" -uvloop = {version = ">=0.15.2",sys_platform = "!= 'win32'"} +isodate = "~=0.6.0" motor = "~=2.4.0" natural = "~=0.2.0" -isodate = "~=0.6.0" parsedatetime = "~=2.6" -aiohttp = "==3.7.4.post0" -python-dotenv = ">=0.18.0" -"discord.py" = "==1.7.3" +python-dateutil = "~=2.8.1" +python-dotenv = "~=0.18.0" +uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index cfaece3094..892d2fddfa 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0700f9473d2588f168a63141ac5f44596d303e7a55db173968edddd0ace2e2ac" + "sha256": "0ffab0587a7d21d864d2c5a7a789e7c883caada73c9c23ff275877aad567729e" }, "pipfile-spec": 6, "requires": { @@ -279,7 +279,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "typing-extensions": { @@ -420,7 +420,7 @@ "sha256:83510593e07e433b77bd5bff0f6f607dbafa06d1a89022616f02d8b699cfcd56", "sha256:8e2c107091cfec7286bc0f68a547d0ba4c094d460b732075b6fba674f1035c0c" ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", + "markers": "python_full_version >= '3.6.1' and python_version < '4.0'", "version": "==5.9.1" }, "lazy-object-proxy": { @@ -590,7 +590,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "smmap": { @@ -614,7 +614,7 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.10.2" }, "wrapt": { diff --git a/bot.py b/bot.py index 1b9a9f2c1f..6102caa915 100644 --- a/bot.py +++ b/bot.py @@ -1695,9 +1695,9 @@ def main(): pass # check discord version - if discord.__version__ != "1.6.0": + if discord.__version__ != "1.7.3": logger.error( - "Dependencies are not updated, run pipenv install. discord.py version expected 1.6.0, received %s", + "Dependencies are not updated, run pipenv install. discord.py version expected 1.7.3, received %s", discord.__version__, ) sys.exit(0) diff --git a/requirements.txt b/requirements.txt index 7e1360e73e..0cc483cc3c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,8 +22,7 @@ parsedatetime==2.6 pymongo==3.11.4 python-dateutil==2.8.1 python-dotenv==0.18.0 -six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' typing-extensions==3.10.0.0 uvloop==0.15.2; sys_platform != 'win32' -wheel==0.36.2 yarl==1.6.3; python_version >= '3.6' From b5f593035b4a1137438b8ca29dd9f98701953adc Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Wed, 7 Jul 2021 19:37:11 +0800 Subject: [PATCH 370/705] Remove flake8 from req, use new rec line-width of 110, black format --- .github/workflows/lints.yml | 15 ++-- Pipfile | 1 - Pipfile.lock | 34 ++------- bot.py | 127 +++++++++----------------------- cogs/modmail.py | 76 ++++++------------- cogs/plugins.py | 36 +++------ cogs/utility.py | 143 ++++++++++++------------------------ core/changelog.py | 12 +-- core/checks.py | 4 +- core/clients.py | 30 +++----- core/config.py | 16 +--- core/models.py | 4 +- core/thread.py | 103 ++++++++------------------ core/time.py | 4 +- core/utils.py | 3 +- pyproject.toml | 12 ++- 16 files changed, 195 insertions(+), 425 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 94b322d968..145a83d489 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -14,20 +14,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: Set up Python 3.7 - uses: actions/setup-python@v1 + - uses: actions/checkout@v2 + - name: Set up Python 3.9 + uses: actions/setup-python@v2 with: - python-version: 3.7 + python-version: 3.9 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install bandit==1.6.2 pylint black==19.10b0 - continue-on-error: true + python -m pip install --upgrade pip pipenv + pipenv install --dev --system - name: Bandit syntax check run: bandit -r . -b .bandit_baseline.json - name: Pylint - run: pylint ./bot.py cogs/*.py core/*.py --disable=import-error --exit-zero -r y + run: pylint ./bot.py cogs/*.py core/*.py --exit-zero -r y continue-on-error: true - name: Black run: | diff --git a/Pipfile b/Pipfile index 5c1d2f8670..813b6700aa 100644 --- a/Pipfile +++ b/Pipfile @@ -6,7 +6,6 @@ verify_ssl = true [dev-packages] bandit = "~=1.7.0" black = "==21.6b0" -flake8 = "~=3.9.2" pylint = "~=2.9.3" [packages] diff --git a/Pipfile.lock b/Pipfile.lock index 892d2fddfa..b10f516efc 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0ffab0587a7d21d864d2c5a7a789e7c883caada73c9c23ff275877aad567729e" + "sha256": "dedff7c4534f29ac1560a57f358852e90d6e6b9d04eb07a35f6daa2d661bc0c2" }, "pipfile-spec": 6, "requires": { @@ -279,7 +279,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "typing-extensions": { @@ -391,14 +391,6 @@ "markers": "python_version >= '3.6'", "version": "==8.0.1" }, - "flake8": { - "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" - ], - "index": "pypi", - "version": "==3.9.2" - }, "gitdb": { "hashes": [ "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0", @@ -420,7 +412,7 @@ "sha256:83510593e07e433b77bd5bff0f6f607dbafa06d1a89022616f02d8b699cfcd56", "sha256:8e2c107091cfec7286bc0f68a547d0ba4c094d460b732075b6fba674f1035c0c" ], - "markers": "python_full_version >= '3.6.1' and python_version < '4.0'", + "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", "version": "==5.9.1" }, "lazy-object-proxy": { @@ -480,22 +472,6 @@ "markers": "python_version >= '2.6'", "version": "==5.6.0" }, - "pycodestyle": { - "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" - }, - "pyflakes": { - "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" - }, "pylint": { "hashes": [ "sha256:23a1dc8b30459d78e9ff25942c61bb936108ccbe29dd9e71c01dc8274961709a", @@ -590,7 +566,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "smmap": { @@ -614,7 +590,7 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, "wrapt": { diff --git a/bot.py b/bot.py index 6102caa915..ce7cfc529d 100644 --- a/bot.py +++ b/bot.py @@ -328,9 +328,7 @@ def log_channel(self) -> typing.Optional[discord.TextChannel]: try: channel = self.main_category.channels[0] self.config["log_channel_id"] = channel.id - logger.warning( - "No log channel set, setting #%s to be the log channel.", channel.name - ) + logger.warning("No log channel set, setting #%s to be the log channel.", channel.name) return channel except IndexError: pass @@ -392,9 +390,7 @@ def auto_triggers(self) -> typing.Dict[str, str]: def token(self) -> str: token = self.config["token"] if token is None: - logger.critical( - "TOKEN must be set, set this as bot token found on the Discord Developer Portal." - ) + logger.critical("TOKEN must be set, set this as bot token found on the Discord Developer Portal.") sys.exit(0) return token @@ -510,11 +506,7 @@ def command_perm(self, command_name: str) -> PermissionLevel: logger.debug("Command %s not found.", command_name) return PermissionLevel.INVALID level = next( - ( - check.permission_level - for check in command.checks - if hasattr(check, "permission_level") - ), + (check.permission_level for check in command.checks if hasattr(check, "permission_level")), None, ) if level is None: @@ -549,8 +541,7 @@ async def on_ready(self): logger.info("Logged in as: %s", self.user) logger.info("Bot ID: %s", self.user.id) owners = ", ".join( - getattr(self.get_user(owner_id), "name", str(owner_id)) - for owner_id in self.bot_owner_ids + getattr(self.get_user(owner_id), "name", str(owner_id)) for owner_id in self.bot_owner_ids ) logger.info("Owners: %s", owners) logger.info("Prefix: %s", self.prefix) @@ -573,9 +564,7 @@ async def on_ready(self): logger.debug("Closing thread for recipient %s.", recipient_id) after = 0 else: - logger.debug( - "Thread for recipient %s will be closed after %s seconds.", recipient_id, after - ) + logger.debug("Thread for recipient %s will be closed after %s seconds.", recipient_id, after) thread = await self.threads.find(recipient_id=int(recipient_id)) @@ -617,9 +606,7 @@ async def on_ready(self): if log_data: logger.debug("Successfully closed thread with channel %s.", log["channel_id"]) else: - logger.debug( - "Failed to close thread with channel %s, skipping.", log["channel_id"] - ) + logger.debug("Failed to close thread with channel %s, skipping.", log["channel_id"]) if self.config.get("data_collection"): self.metadata_loop = tasks.Loop( @@ -640,9 +627,7 @@ async def on_ready(self): self.autoupdate_loop.before_loop(self.before_autoupdate) self.autoupdate_loop.start() - other_guilds = [ - guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild} - ] + other_guilds = [guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild}] if any(other_guilds): logger.warning( "The bot is in more servers other than the main and staff server. " @@ -880,9 +865,7 @@ async def get_thread_cooldown(self, author: discord.Member): cooldown = datetime.fromisoformat(last_log_closed_at) + thread_cooldown except ValueError: logger.warning("Error with 'thread_cooldown'.", exc_info=True) - cooldown = datetime.fromisoformat(last_log_closed_at) + self.config.remove( - "thread_cooldown" - ) + cooldown = datetime.fromisoformat(last_log_closed_at) + self.config.remove("thread_cooldown") if cooldown > now: # User messaged before thread cooldown ended @@ -930,12 +913,8 @@ async def process_dm_modmail(self, message: discord.Message) -> None: color=self.error_color, description=self.config["disabled_new_thread_response"], ) - embed.set_footer( - text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon_url - ) - logger.info( - "A new thread was blocked from %s due to disabled Modmail.", message.author - ) + embed.set_footer(text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon_url) + logger.info("A new thread was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) @@ -951,9 +930,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: text=self.config["disabled_current_thread_footer"], icon_url=self.guild.icon_url, ) - logger.info( - "A message was blocked from %s due to disabled Modmail.", message.author - ) + logger.info("A message was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) @@ -1025,15 +1002,11 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) invoker = None if self.config.get("use_regex_autotrigger"): - trigger = next( - filter(lambda x: re.search(x, message.content), self.auto_triggers.keys()) - ) + trigger = next(filter(lambda x: re.search(x, message.content), self.auto_triggers.keys())) if trigger: invoker = re.search(trigger, message.content).group(0) else: - trigger = next( - filter(lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys()) - ) + trigger = next(filter(lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys())) if trigger: invoker = trigger.lower() @@ -1169,9 +1142,7 @@ async def process_commands(self, message): ctxs = await self.get_contexts(message) for ctx in ctxs: if ctx.command: - if not any( - 1 for check in ctx.command.checks if hasattr(check, "permission_level") - ): + if not any(1 for check in ctx.command.checks if hasattr(check, "permission_level")): logger.debug( "Command %s has no permissions check, adding invalid level.", ctx.command.qualified_name, @@ -1199,9 +1170,7 @@ async def process_commands(self, message): else: await self.api.append_log(message, type_="internal") elif ctx.invoked_with: - exc = commands.CommandNotFound( - 'Command "{}" is not found'.format(ctx.invoked_with) - ) + exc = commands.CommandNotFound('Command "{}" is not found'.format(ctx.invoked_with)) self.dispatch("command_error", ctx, exc) async def on_typing(self, channel, user, _): @@ -1275,9 +1244,7 @@ async def handle_reaction_events(self, payload): if not thread.recipient.dm_channel: await thread.recipient.create_dm() try: - linked_message = await thread.find_linked_message_from_dm( - message, either_direction=True - ) + linked_message = await thread.find_linked_message_from_dm(message, either_direction=True) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return @@ -1286,9 +1253,7 @@ async def handle_reaction_events(self, payload): if not thread: return try: - _, linked_message = await thread.find_linked_messages( - message.id, either_direction=True - ) + _, linked_message = await thread.find_linked_messages(message.id, either_direction=True) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return @@ -1345,9 +1310,7 @@ async def on_raw_reaction_add(self, payload): ctx = await self.get_context(message) ctx.author = member - await ctx.invoke( - self.get_command("contact"), user=member, manual_trigger=False - ) + await ctx.invoke(self.get_command("contact"), user=member, manual_trigger=False) async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: @@ -1373,9 +1336,7 @@ async def on_guild_channel_delete(self, channel): await self.config.update() return - audit_logs = self.modmail_guild.audit_logs( - limit=10, action=discord.AuditLogAction.channel_delete - ) + audit_logs = self.modmail_guild.audit_logs(limit=10, action=discord.AuditLogAction.channel_delete) entry = await audit_logs.find(lambda a: int(a.target.id) == channel.id) if entry is None: @@ -1413,9 +1374,7 @@ async def on_member_join(self, member): return thread = await self.threads.find(recipient=member) if thread: - embed = discord.Embed( - description="The recipient has joined the server.", color=self.mod_color - ) + embed = discord.Embed(description="The recipient has joined the server.", color=self.mod_color) await thread.channel.send(embed=embed) async def on_message_delete(self, message): @@ -1448,9 +1407,7 @@ async def on_message_delete(self, message): if not thread: return - audit_logs = self.modmail_guild.audit_logs( - limit=10, action=discord.AuditLogAction.message_delete - ) + audit_logs = self.modmail_guild.audit_logs(limit=10, action=discord.AuditLogAction.message_delete) entry = await audit_logs.find(lambda a: a.target == self.user) @@ -1459,15 +1416,11 @@ async def on_message_delete(self, message): try: await thread.delete_message(message, note=False) - embed = discord.Embed( - description="Successfully deleted message.", color=self.main_color - ) + embed = discord.Embed(description="Successfully deleted message.", color=self.main_color) except ValueError as e: if str(e) not in {"DM message not found.", "Malformed thread message."}: logger.debug("Failed to find linked message to delete: %s", e) - embed = discord.Embed( - description="Failed to delete message.", color=self.error_color - ) + embed = discord.Embed(description="Failed to delete message.", color=self.error_color) else: return except discord.NotFound: @@ -1495,9 +1448,7 @@ async def on_message_edit(self, before, after): _, blocked_emoji = await self.retrieve_emoji() await self.add_reaction(after, blocked_emoji) else: - embed = discord.Embed( - description="Successfully Edited Message", color=self.main_color - ) + embed = discord.Embed(description="Successfully Edited Message", color=self.main_color) embed.set_footer(text=f"Message ID: {after.id}") await after.channel.send(embed=embed) @@ -1508,9 +1459,7 @@ async def on_error(self, event_method, *args, **kwargs): async def on_command_error(self, context, exception): if isinstance(exception, commands.BadArgument): await context.trigger_typing() - await context.send( - embed=discord.Embed(color=self.error_color, description=str(exception)) - ) + await context.send(embed=discord.Embed(color=self.error_color, description=str(exception))) elif isinstance(exception, commands.CommandNotFound): logger.warning("CommandNotFound: %s", exception) elif isinstance(exception, commands.MissingRequiredArgument): @@ -1531,9 +1480,7 @@ async def on_command_error(self, context, exception): embed=discord.Embed(color=self.error_color, description=check.fail_msg) ) if hasattr(check, "permission_level"): - corrected_permission_level = self.command_perm( - context.command.qualified_name - ) + corrected_permission_level = self.command_perm(context.command.qualified_name) logger.warning( "User %s does not have permission to use this command: `%s` (%s).", context.author.name, @@ -1542,9 +1489,7 @@ async def on_command_error(self, context, exception): ) logger.warning("CheckFailure: %s", exception) elif isinstance(exception, commands.DisabledCommand): - logger.info( - "DisabledCommand: %s is trying to run eval but it's disabled", context.author.name - ) + logger.info("DisabledCommand: %s is trying to run eval but it's disabled", context.author.name) else: logger.error("Unexpected exception:", exc_info=exception) @@ -1568,9 +1513,7 @@ async def post_metadata(self): if info.team is not None: data.update( { - "owner_name": info.team.owner.name - if info.team.owner is not None - else "No Owner", + "owner_name": info.team.owner.name if info.team.owner is not None else "No Owner", "owner_id": info.team.owner_id, "team": True, } @@ -1632,7 +1575,11 @@ async def autoupdate(self): pass command = "git pull" - proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + proc = await asyncio.create_subprocess_shell( + command, + stderr=PIPE, + stdout=PIPE, + ) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() @@ -1648,9 +1595,7 @@ async def autoupdate(self): channel = self.update_channel if self.hosting_method in (HostingMethod.PM2, HostingMethod.SYSTEMD): embed = discord.Embed(title="Bot has been updated", color=self.main_color) - embed.set_footer( - text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" - ) + embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") if self.config["update_notifications"]: await channel.send(embed=embed) else: @@ -1659,9 +1604,7 @@ async def autoupdate(self): description="If you do not have an auto-restart setup, please manually start the bot.", color=self.main_color, ) - embed.set_footer( - text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" - ) + embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") if self.config["update_notifications"]: await channel.send(embed=embed) await self.logout() diff --git a/cogs/modmail.py b/cogs/modmail.py index 87b9d91e57..5b3f67bdd2 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -42,9 +42,7 @@ async def setup(self, ctx): """ if ctx.guild != self.bot.modmail_guild: - return await ctx.send( - f"You can only setup in the Modmail guild: {self.bot.modmail_guild}." - ) + return await ctx.send(f"You can only setup in the Modmail guild: {self.bot.modmail_guild}.") if self.bot.main_category is not None: logger.debug("Can't re-setup server, main_category is found.") @@ -79,15 +77,11 @@ async def setup(self, ctx): logger.info("Granting %s access to Modmail category.", key.name) overwrites[key] = discord.PermissionOverwrite(read_messages=True) - category = await self.bot.modmail_guild.create_category( - name="Modmail", overwrites=overwrites - ) + category = await self.bot.modmail_guild.create_category(name="Modmail", overwrites=overwrites) await category.edit(position=0) - log_channel = await self.bot.modmail_guild.create_text_channel( - name="bot-logs", category=category - ) + log_channel = await self.bot.modmail_guild.create_text_channel(name="bot-logs", category=category) embed = discord.Embed( title="Friendly Reminder", @@ -434,9 +428,7 @@ def parse_user_or_role(ctx, user_or_role): @commands.command(aliases=["alert"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() - async def notify( - self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None - ): + async def notify(self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None): """ Notify a user or role when the next thread message received. @@ -474,9 +466,7 @@ async def notify( @commands.command(aliases=["unalert"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() - async def unnotify( - self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None - ): + async def unnotify(self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None): """ Un-notify a user, role, or yourself from a thread. @@ -511,9 +501,7 @@ async def unnotify( @commands.command(aliases=["sub"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() - async def subscribe( - self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None - ): + async def subscribe(self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None): """ Notify a user, role, or yourself for every thread message received. @@ -551,9 +539,7 @@ async def subscribe( @commands.command(aliases=["unsub"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() - async def unsubscribe( - self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None - ): + async def unsubscribe(self, ctx, *, user_or_role: Union[discord.Role, User, str.lower, None] = None): """ Unsubscribe a user, role, or yourself from a thread. @@ -638,7 +624,9 @@ def format_log_embeds(self, logs, avatar_url): prefix = self.bot.config["log_url_prefix"].strip("/") if prefix == "NONE": prefix = "" - log_url = f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{entry['key']}" + log_url = ( + f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{entry['key']}" + ) username = entry["recipient"]["name"] + "#" username += entry["recipient"]["discriminator"] @@ -946,9 +934,7 @@ async def note_persistent(self, ctx, *, msg: str = ""): async with ctx.typing(): msg = await ctx.thread.note(ctx.message, persistent=True) await msg.pin() - await self.bot.api.create_note( - recipient=ctx.thread.recipient, message=ctx.message, message_id=msg.id - ) + await self.bot.api.create_note(recipient=ctx.thread.recipient, message=ctx.message, message_id=msg.id) @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1011,17 +997,14 @@ async def contact( category = None if user.bot: - embed = discord.Embed( - color=self.bot.error_color, description="Cannot start a thread with a bot." - ) + embed = discord.Embed(color=self.bot.error_color, description="Cannot start a thread with a bot.") return await ctx.send(embed=embed, delete_after=3) exists = await self.bot.threads.find(recipient=user) if exists: embed = discord.Embed( color=self.bot.error_color, - description="A thread for this user already " - f"exists in {exists.channel.mention}.", + description="A thread for this user already " f"exists in {exists.channel.mention}.", ) await ctx.channel.send(embed=embed, delete_after=3) @@ -1045,7 +1028,9 @@ async def contact( description = f"{ctx.author.name} has opened a Modmail thread." em = discord.Embed( - title="New Thread", description=description, color=self.bot.main_color, + title="New Thread", + description=description, + color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: em.timestamp = datetime.utcnow() @@ -1153,9 +1138,7 @@ async def blocked(self, ctx): else: embeds[0].description = "Currently there are no blocked users." - embeds.append( - discord.Embed(title="Blocked Roles", color=self.bot.main_color, description="") - ) + embeds.append(discord.Embed(title="Blocked Roles", color=self.bot.main_color, description="")) if roles: embed = embeds[-1] @@ -1341,10 +1324,7 @@ async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): mention = getattr(user_or_role, "mention", f"`{user_or_role.id}`") name = getattr(user_or_role, "name", f"`{user_or_role.id}`") - if ( - not isinstance(user_or_role, discord.Role) - and str(user_or_role.id) in self.bot.blocked_users - ): + if not isinstance(user_or_role, discord.Role) and str(user_or_role.id) in self.bot.blocked_users: msg = self.bot.blocked_users.pop(str(user_or_role.id)) or "" await self.bot.config.update() @@ -1369,10 +1349,7 @@ async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): color=self.bot.main_color, description=f"{mention} is no longer blocked.", ) - elif ( - isinstance(user_or_role, discord.Role) - and str(user_or_role.id) in self.bot.blocked_roles - ): + elif isinstance(user_or_role, discord.Role) and str(user_or_role.id) in self.bot.blocked_roles: msg = self.bot.blocked_roles.pop(str(user_or_role.id)) or "" await self.bot.config.update() @@ -1465,12 +1442,8 @@ async def repair(self, ctx): self.bot.threads, recipient, ctx.channel ) thread.ready = True - logger.info( - "Setting current channel's topic to User ID and created new thread." - ) - await ctx.channel.edit( - reason="Fix broken Modmail thread", topic=f"User ID: {user_id}" - ) + logger.info("Setting current channel's topic to User ID and created new thread.") + await ctx.channel.edit(reason="Fix broken Modmail thread", topic=f"User ID: {user_id}") return await self.bot.add_reaction(ctx.message, sent_emoji) else: @@ -1482,8 +1455,7 @@ async def repair(self, ctx): if m is not None: users = set( filter( - lambda member: member.name == m.group(1) - and member.discriminator == m.group(2), + lambda member: member.name == m.group(1) and member.discriminator == m.group(2), ctx.guild.members, ) ) @@ -1508,9 +1480,7 @@ async def repair(self, ctx): except discord.HTTPException: pass if recipient is None: - self.bot.threads.cache[user.id] = thread = Thread( - self.bot.threads, user_id, ctx.channel - ) + self.bot.threads.cache[user.id] = thread = Thread(self.bot.threads, user_id, ctx.channel) else: self.bot.threads.cache[user.id] = thread = Thread( self.bot.threads, recipient, ctx.channel diff --git a/cogs/plugins.py b/cogs/plugins.py index 94a3f425c0..aab5dc8bd6 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -251,12 +251,8 @@ async def load_plugin(self, plugin): if stderr: logger.debug("[stderr]\n%s.", stderr.decode()) - logger.error( - "Failed to download requirements for %s.", plugin.ext_string, exc_info=True - ) - raise InvalidPluginError( - f"Unable to download requirements: ```\n{stderr.decode()}\n```" - ) + logger.error("Failed to download requirements for %s.", plugin.ext_string, exc_info=True) + raise InvalidPluginError(f"Unable to download requirements: ```\n{stderr.decode()}\n```") if os.path.exists(USER_SITE): sys.path.insert(0, USER_SITE) @@ -347,9 +343,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): return if str(plugin) in self.bot.config["plugins"]: - embed = discord.Embed( - description="This plugin is already installed.", color=self.bot.error_color - ) + embed = discord.Embed(description="This plugin is already installed.", color=self.bot.error_color) return await ctx.send(embed=embed) if plugin.name in self.bot.cogs: @@ -433,9 +427,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): return if str(plugin) not in self.bot.config["plugins"]: - embed = discord.Embed( - description="Plugin is not installed.", color=self.bot.error_color - ) + embed = discord.Embed(description="Plugin is not installed.", color=self.bot.error_color) return await ctx.send(embed=embed) if self.bot.config.get("enable_plugins"): @@ -472,9 +464,7 @@ async def update_plugin(self, ctx, plugin_name): return if str(plugin) not in self.bot.config["plugins"]: - embed = discord.Embed( - description="Plugin is not installed.", color=self.bot.error_color - ) + embed = discord.Embed(description="Plugin is not installed.", color=self.bot.error_color) return await ctx.send(embed=embed) async with ctx.typing(): @@ -598,9 +588,7 @@ async def plugins_loaded(self, ctx): embeds = [] for page in pages: - embed = discord.Embed( - title="Loaded plugins:", description=page, color=self.bot.main_color - ) + embed = discord.Embed(title="Loaded plugins:", description=page, color=self.bot.main_color) embeds.append(embed) paginator = EmbedPaginatorSession(ctx, *embeds) await paginator.run() @@ -641,9 +629,7 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N matches = get_close_matches(plugin_name, self.registry.keys()) if matches: - embed.add_field( - name="Perhaps you meant:", value="\n".join(f"`{m}`" for m in matches) - ) + embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{m}`" for m in matches)) return await ctx.send(embed=embed) @@ -661,13 +647,9 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N title=details["repository"], ) - embed.add_field( - name="Installation", value=f"```{self.bot.prefix}plugins add {name}```" - ) + embed.add_field(name="Installation", value=f"```{self.bot.prefix}plugins add {name}```") - embed.set_author( - name=details["title"], icon_url=details.get("icon_url"), url=plugin.link - ) + embed.set_author(name=details["title"], icon_url=details.get("icon_url"), url=plugin.link) if details.get("thumbnail_url"): embed.set_thumbnail(url=details.get("thumbnail_url")) diff --git a/cogs/utility.py b/cogs/utility.py index 7b39631dcd..0e03ab1ba1 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -184,9 +184,7 @@ async def send_error_message(self, error): command = self.context.kwargs.get("command") val = self.context.bot.snippets.get(command) if val is not None: - embed = discord.Embed( - title=f"{command} is a snippet.", color=self.context.bot.main_color - ) + embed = discord.Embed(title=f"{command} is a snippet.", color=self.context.bot.main_color) embed.add_field(name=f"`{command}` will send:", value=val) return await self.get_destination().send(embed=embed) @@ -206,9 +204,7 @@ async def send_error_message(self, error): await self.context.bot.config.update() else: if len(values) == 1: - embed = discord.Embed( - title=f"{command} is an alias.", color=self.context.bot.main_color - ) + embed = discord.Embed(title=f"{command} is an alias.", color=self.context.bot.main_color) embed.add_field(name=f"`{command}` points to:", value=values[0]) else: embed = discord.Embed( @@ -330,12 +326,8 @@ async def about(self, ctx): latest = changelog.latest_version if self.bot.version.is_prerelease: - stable = next( - filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions) - ) - footer = ( - f"You are on the prerelease version • the latest version is v{stable.version}." - ) + stable = next(filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions)) + footer = f"You are on the prerelease version • the latest version is v{stable.version}." elif self.bot.version < parse_version(latest.version): footer = f"A newer version is available v{latest.version}." else: @@ -389,9 +381,7 @@ async def debug(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join( - os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" - ), + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "r+", ) as f: logs = f.read().strip() @@ -444,9 +434,7 @@ async def debug_hastebin(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join( - os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" - ), + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "rb+", ) as f: logs = BytesIO(f.read().strip()) @@ -482,16 +470,12 @@ async def debug_clear(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join( - os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" - ), + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "w", ): pass await ctx.send( - embed=discord.Embed( - color=self.bot.main_color, description="Cached logs are now cleared." - ) + embed=discord.Embed(color=self.bot.main_color, description="Cached logs are now cleared.") ) @commands.command(aliases=["presence"]) @@ -536,9 +520,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): except KeyError: raise commands.MissingRequiredArgument(SimpleNamespace(name="activity")) - activity, _ = await self.set_presence( - activity_type=activity_type, activity_message=message - ) + activity, _ = await self.set_presence(activity_type=activity_type, activity_message=message) self.bot.config["activity_type"] = activity.type.value self.bot.config["activity_message"] = activity.name @@ -603,9 +585,7 @@ async def set_presence(self, *, status=None, activity_type=None, activity_messag url = None activity_message = (activity_message or self.bot.config["activity_message"]).strip() if activity_type is not None and not activity_message: - logger.warning( - 'No activity message found whilst activity is provided, defaults to "Modmail".' - ) + logger.warning('No activity message found whilst activity is provided, defaults to "Modmail".') activity_message = "Modmail" if activity_type == ActivityType.listening: @@ -706,12 +686,14 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, option = user_or_role[0].lower() if option == "disable": embed = discord.Embed( - description=f"Disabled mention on thread creation.", color=self.bot.main_color, + description=f"Disabled mention on thread creation.", + color=self.bot.main_color, ) self.bot.config["mention"] = None else: embed = discord.Embed( - description="`mention` is reset to default.", color=self.bot.main_color, + description="`mention` is reset to default.", + color=self.bot.main_color, ) self.bot.config.remove("mention") await self.bot.config.update() @@ -747,9 +729,7 @@ async def prefix(self, ctx, *, prefix=None): """ current = self.bot.prefix - embed = discord.Embed( - title="Current prefix", color=self.bot.main_color, description=f"{current}" - ) + embed = discord.Embed(title="Current prefix", color=self.bot.main_color, description=f"{current}") if prefix is None: await ctx.send(embed=embed) @@ -786,9 +766,7 @@ async def config_options(self, ctx): """Return a list of valid configuration names you can change.""" embeds = [] for names in zip_longest(*(iter(sorted(self.bot.config.public_keys)),) * 15): - description = "\n".join( - f"`{name}`" for name in takewhile(lambda x: x is not None, names) - ) + description = "\n".join(f"`{name}`" for name in takewhile(lambda x: x is not None, names)) embed = discord.Embed( title="Available configuration keys:", color=self.bot.main_color, @@ -906,9 +884,7 @@ async def config_help(self, ctx, key: str.lower = None): description=f"`{key}` is an invalid key.", ) if closest: - embed.add_field( - name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest) - ) + embed.add_field(name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) return await ctx.send(embed=embed) config_help = self.bot.config.config_help @@ -1401,9 +1377,7 @@ async def permissions_remove( Do not ping `@everyone` for granting permission to everyone, use "everyone" or "all" instead. """ - if type_ not in {"command", "level", "override"} or ( - type_ != "override" and user_or_role is None - ): + if type_ not in {"command", "level", "override"} or (type_ != "override" and user_or_role is None): return await ctx.send_help(ctx.command) if type_ == "override": @@ -1566,15 +1540,9 @@ async def permissions_get( levels.append(level.name) mention = getattr(user_or_role, "name", getattr(user_or_role, "id", user_or_role)) - desc_cmd = ( - ", ".join(map(lambda x: f"`{x}`", cmds)) - if cmds - else "No permission entries found." - ) + desc_cmd = ", ".join(map(lambda x: f"`{x}`", cmds)) if cmds else "No permission entries found." desc_level = ( - ", ".join(map(lambda x: f"`{x}`", levels)) - if levels - else "No permission entries found." + ", ".join(map(lambda x: f"`{x}`", levels)) if levels else "No permission entries found." ) embeds = [ @@ -1599,9 +1567,7 @@ async def permissions_get( for command in self.bot.walk_commands(): if command not in done: done.add(command) - level = self.bot.config["override_command_level"].get( - command.qualified_name - ) + level = self.bot.config["override_command_level"].get(command.qualified_name) if level is not None: overrides[command.qualified_name] = level @@ -1620,12 +1586,8 @@ async def permissions_get( ": ".join((f"`{name}`", level)) for name, level in takewhile(lambda x: x is not None, items) ) - embed = discord.Embed( - color=self.bot.main_color, description=description - ) - embed.set_author( - name="Permission Overrides", icon_url=ctx.guild.icon_url - ) + embed = discord.Embed(color=self.bot.main_color, description=description) + embed.set_author(name="Permission Overrides", icon_url=ctx.guild.icon_url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1727,9 +1689,7 @@ async def oauth_whitelist(self, ctx, target: Union[discord.Role, utils.User]): if not hasattr(target, "mention"): target = self.bot.get_user(target.id) or self.bot.modmail_guild.get_role(target.id) - embed.description = ( - f"{'Un-w' if removed else 'W'}hitelisted {target.mention} to view logs." - ) + embed.description = f"{'Un-w' if removed else 'W'}hitelisted {target.mention} to view logs." await ctx.send(embed=embed) @@ -1807,9 +1767,7 @@ async def autotrigger_add(self, ctx, keyword, *, command): async def autotrigger_edit(self, ctx, keyword, *, command): """Edits a pre-existing trigger to automatically trigger an alias-like command""" if keyword not in self.bot.auto_triggers: - embed = utils.create_not_found_embed( - keyword, self.bot.auto_triggers.keys(), "Autotrigger" - ) + embed = utils.create_not_found_embed(keyword, self.bot.auto_triggers.keys(), "Autotrigger") else: # command validation valid = False @@ -1895,7 +1853,11 @@ async def autotrigger_list(self, ctx): embeds = [] for keyword in self.bot.auto_triggers: command = self.bot.auto_triggers[keyword] - embed = discord.Embed(title=keyword, color=self.bot.main_color, description=command,) + embed = discord.Embed( + title=keyword, + color=self.bot.main_color, + description=command, + ) embeds.append(embed) if not embeds: @@ -1918,17 +1880,13 @@ async def github(self, ctx): data = await self.bot.api.get_user_info() if data: - embed = discord.Embed( - title="GitHub", description="Current User", color=self.bot.main_color - ) + embed = discord.Embed(title="GitHub", description="Current User", color=self.bot.main_color) user = data["user"] embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) embed.set_thumbnail(url=user["avatar_url"]) await ctx.send(embed=embed) else: - await ctx.send( - embed=discord.Embed(title="Invalid Github Token", color=self.bot.error_color) - ) + await ctx.send(embed=discord.Embed(title="Invalid Github Token", color=self.bot.error_color)) @commands.command() @checks.has_permissions(PermissionLevel.OWNER) @@ -1950,16 +1908,12 @@ async def update(self, ctx, *, flag: str = ""): ) if self.bot.version >= parse_version(latest.version) and flag.lower() != "force": - embed = discord.Embed( - title="Already up to date", description=desc, color=self.bot.main_color - ) + embed = discord.Embed(title="Already up to date", description=desc, color=self.bot.main_color) data = await self.bot.api.get_user_info() if data: user = data["user"] - embed.set_author( - name=user["username"], icon_url=user["avatar_url"], url=user["url"] - ) + embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) await ctx.send(embed=embed) else: if self.bot.hosting_method == HostingMethod.HEROKU: @@ -1971,9 +1925,7 @@ async def update(self, ctx, *, flag: str = ""): if commit_data and commit_data.get("html_url"): embed = discord.Embed(color=self.bot.main_color) - embed.set_footer( - text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" - ) + embed.set_footer(text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}") embed.set_author( name=user["username"] + " - Updating bot", @@ -1995,9 +1947,7 @@ async def update(self, ctx, *, flag: str = ""): color=self.bot.main_color, ) embed.set_footer(text="Force update") - embed.set_author( - name=user["username"], icon_url=user["avatar_url"], url=user["url"] - ) + embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) await ctx.send(embed=embed) else: # update fork if gh_token exists @@ -2008,25 +1958,28 @@ async def update(self, ctx, *, flag: str = ""): command = "git pull" - proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + proc = await asyncio.create_subprocess_shell( + command, + stderr=PIPE, + stdout=PIPE, + ) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() res = res.decode("utf-8").rstrip() if err and not res: - embed = discord.Embed( - title="Update failed", description=err, color=self.bot.error_color - ) + embed = discord.Embed(title="Update failed", description=err, color=self.bot.error_color) await ctx.send(embed=embed) elif res != "Already up to date.": logger.info("Bot has been updated.") - embed = discord.Embed(title="Bot has been updated", color=self.bot.main_color,) - embed.set_footer( - text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" + embed = discord.Embed( + title="Bot has been updated", + color=self.bot.main_color, ) + embed.set_footer(text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}") embed.description = latest.description for name, value in latest.fields.items(): embed.add_field(name=name, value=truncate(value, 200)) @@ -2040,7 +1993,9 @@ async def update(self, ctx, *, flag: str = ""): await self.bot.logout() else: embed = discord.Embed( - title="Already up to date", description=desc, color=self.bot.main_color, + title="Already up to date", + description=desc, + color=self.bot.main_color, ) embed.set_footer(text="Force update") await ctx.send(embed=embed) diff --git a/core/changelog.py b/core/changelog.py index 878a19b26c..7c9af2e1bb 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -65,9 +65,7 @@ def parse(self) -> None: Parse the lines and split them into `description` and `fields`. """ self.description = re.match(self.DESCRIPTION_REGEX, self.lines, re.DOTALL) - self.description = ( - self.description.group(1).strip() if self.description is not None else "" - ) + self.description = self.description.group(1).strip() if self.description is not None else "" matches = re.finditer(self.ACTION_REGEX, self.lines, re.DOTALL) for m in matches: @@ -91,7 +89,9 @@ def embed(self) -> Embed: """ embed = Embed(color=self.bot.main_color, description=self.description) embed.set_author( - name=f"v{self.version} - Changelog", icon_url=self.bot.user.avatar_url, url=self.url, + name=f"v{self.version} - Changelog", + icon_url=self.bot.user.avatar_url, + url=self.url, ) for name, value in self.fields.items(): @@ -171,7 +171,9 @@ async def from_url(cls, bot, url: str = "") -> "Changelog": """ # get branch via git cli if available proc = await asyncio.create_subprocess_shell( - "git branch --show-current", stderr=PIPE, stdout=PIPE, + "git branch --show-current", + stderr=PIPE, + stdout=PIPE, ) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() diff --git a/core/checks.py b/core/checks.py index 74b7dc38cd..1079b55530 100644 --- a/core/checks.py +++ b/core/checks.py @@ -5,7 +5,9 @@ logger = getLogger(__name__) -def has_permissions_predicate(permission_level: PermissionLevel = PermissionLevel.REGULAR,): +def has_permissions_predicate( + permission_level: PermissionLevel = PermissionLevel.REGULAR, +): async def predicate(ctx): return await check_permissions(ctx, ctx.command.qualified_name) diff --git a/core/clients.py b/core/clients.py index db4e9936b4..1d90cbb0e3 100644 --- a/core/clients.py +++ b/core/clients.py @@ -305,9 +305,7 @@ async def get_log(self, channel_id: Union[str, int]) -> dict: async def get_log_link(self, channel_id: Union[str, int]) -> str: return NotImplemented - async def create_log_entry( - self, recipient: Member, channel: TextChannel, creator: Member - ) -> str: + async def create_log_entry(self, recipient: Member, channel: TextChannel, creator: Member) -> str: return NotImplemented async def delete_log_entry(self, key: str) -> bool: @@ -479,13 +477,9 @@ async def get_log_link(self, channel_id: Union[str, int]) -> str: prefix = self.bot.config["log_url_prefix"].strip("/") if prefix == "NONE": prefix = "" - return ( - f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{doc['key']}" - ) + return f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{doc['key']}" - async def create_log_entry( - self, recipient: Member, channel: TextChannel, creator: Member - ) -> str: + async def create_log_entry(self, recipient: Member, channel: TextChannel, creator: Member) -> str: key = secrets.token_hex(6) await self.logs.insert_one( @@ -536,9 +530,7 @@ async def get_config(self) -> dict: async def update_config(self, data: dict): toset = self.bot.config.filter_valid(data) - unset = self.bot.config.filter_valid( - {k: 1 for k in self.bot.config.all_keys if k not in data} - ) + unset = self.bot.config.filter_valid({k: 1 for k in self.bot.config.all_keys if k not in data}) if toset and unset: return await self.db.config.update_one( @@ -635,17 +627,13 @@ async def find_notes(self, recipient: Member): async def update_note_ids(self, ids: dict): for object_id, message_id in ids.items(): - await self.db.notes.update_one( - {"_id": object_id}, {"$set": {"message_id": message_id}} - ) + await self.db.notes.update_one({"_id": object_id}, {"$set": {"message_id": message_id}}) async def delete_note(self, message_id: Union[int, str]): await self.db.notes.delete_one({"message_id": str(message_id)}) async def edit_note(self, message_id: Union[int, str], message: str): - await self.db.notes.update_one( - {"message_id": str(message_id)}, {"$set": {"message": message}} - ) + await self.db.notes.update_one({"message_id": str(message_id)}, {"$set": {"message": message}}) def get_plugin_partition(self, cog): cls_name = cog.__class__.__name__ @@ -656,7 +644,11 @@ async def update_repository(self) -> dict: data = await user.update_repository() return { "data": data, - "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,}, + "user": { + "username": user.username, + "avatar_url": user.avatar_url, + "url": user.url, + }, } async def get_user_info(self) -> dict: diff --git a/core/config.py b/core/config.py index 30f364622d..255c3667de 100644 --- a/core/config.py +++ b/core/config.py @@ -210,28 +210,18 @@ def populate_cache(self) -> dict: # populate from env var and .env file data.update({k.lower(): v for k, v in os.environ.items() if k.lower() in self.all_keys}) - config_json = os.path.join( - os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config.json" - ) + config_json = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config.json") if os.path.exists(config_json): logger.debug("Loading envs from config.json.") with open(config_json, "r", encoding="utf-8") as f: # Config json should override env vars try: - data.update( - { - k.lower(): v - for k, v in json.load(f).items() - if k.lower() in self.all_keys - } - ) + data.update({k.lower(): v for k, v in json.load(f).items() if k.lower() in self.all_keys}) except json.JSONDecodeError: logger.critical("Failed to load config.json env values.", exc_info=True) self._cache = data - config_help_json = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "config_help.json" - ) + config_help_json = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config_help.json") with open(config_help_json, "r", encoding="utf-8") as f: self.config_help = dict(sorted(json.load(f).items())) diff --git a/core/models.py b/core/models.py index 0238e051d4..d17e118e6c 100644 --- a/core/models.py +++ b/core/models.py @@ -203,9 +203,7 @@ async def convert(self, ctx, argument): except commands.ChannelNotFound: def check(c): - return isinstance(c, discord.CategoryChannel) and c.name.lower().startswith( - argument.lower() - ) + return isinstance(c, discord.CategoryChannel) and c.name.lower().startswith(argument.lower()) if guild: result = discord.utils.find(check, guild.categories) diff --git a/core/thread.py b/core/thread.py index 530e063e54..41d2cd96ba 100644 --- a/core/thread.py +++ b/core/thread.py @@ -109,9 +109,7 @@ async def setup(self, *, creator=None, category=None, initial_message=None): recipient = self.recipient # in case it creates a channel outside of category - overwrites = { - self.bot.modmail_guild.default_role: discord.PermissionOverwrite(read_messages=False) - } + overwrites = {self.bot.modmail_guild.default_role: discord.PermissionOverwrite(read_messages=False)} category = category or self.bot.main_category @@ -170,9 +168,7 @@ async def setup(self, *, creator=None, category=None, initial_message=None): mention = self.bot.config["mention"] async def send_genesis_message(): - info_embed = self._format_info_embed( - recipient, log_url, log_count, self.bot.main_color - ) + info_embed = self._format_info_embed(recipient, log_url, log_count, self.bot.main_color) try: msg = await channel.send(mention, embed=info_embed) self.bot.loop.create_task(msg.pin()) @@ -238,9 +234,7 @@ class Author: "author": Author(), } message = discord.Message(state=State(), channel=None, data=data) - ids[note["_id"]] = str( - (await self.note(message, persistent=True, thread_creation=True)).id - ) + ids[note["_id"]] = str((await self.note(message, persistent=True, thread_creation=True)).id) await self.bot.api.update_note_ids(ids) @@ -330,16 +324,12 @@ def _format_info_embed(self, user, log_url, log_count, color): mutual_guilds = [g for g in self.bot.guilds if user in g.members] if member is None or len(mutual_guilds) > 1: - embed.add_field( - name="Mutual Server(s)", value=", ".join(g.name for g in mutual_guilds) - ) + embed.add_field(name="Mutual Server(s)", value=", ".join(g.name for g in mutual_guilds)) return embed def _close_after(self, closer, silent, delete_channel, message): - return self.bot.loop.create_task( - self._close(closer, silent, delete_channel, message, True) - ) + return self.bot.loop.create_task(self._close(closer, silent, delete_channel, message, True)) async def close( self, @@ -372,9 +362,7 @@ async def close( self.bot.config["closures"][str(self.id)] = items await self.bot.config.update() - task = self.bot.loop.call_later( - after, self._close_after, closer, silent, delete_channel, message - ) + task = self.bot.loop.call_later(after, self._close_after, closer, silent, delete_channel, message) if auto_close: self.auto_close_task = task @@ -383,9 +371,7 @@ async def close( else: await self._close(closer, silent, delete_channel, message) - async def _close( - self, closer, silent=False, delete_channel=True, message=None, scheduled=False - ): + async def _close(self, closer, silent=False, delete_channel=True, message=None, scheduled=False): try: self.manager.cache.pop(self.id) except KeyError as e: @@ -425,7 +411,9 @@ async def _close( prefix = self.bot.config["log_url_prefix"].strip("/") if prefix == "NONE": prefix = "" - log_url = f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{log_data['key']}" + log_url = ( + f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{log_data['key']}" + ) if log_data["title"]: sneak_peak = log_data["title"] @@ -473,7 +461,8 @@ async def _close( # Thread closed message embed = discord.Embed( - title=self.bot.config["thread_close_title"], color=self.bot.error_color, + title=self.bot.config["thread_close_title"], + color=self.bot.error_color, ) if self.bot.config["show_timestamp"]: embed.timestamp = datetime.utcnow() @@ -531,9 +520,7 @@ async def _restart_close_timer(self): human_time = human_timedelta(dt=reset_time) if self.bot.config.get("thread_auto_close_silently"): - return await self.close( - closer=self.bot.user, silent=True, after=int(seconds), auto_close=True - ) + return await self.close(closer=self.bot.user, silent=True, after=int(seconds), auto_close=True) # Grab message close_message = self.bot.formatter.format( @@ -549,9 +536,7 @@ async def _restart_close_timer(self): time_marker_regex, ) - await self.close( - closer=self.bot.user, after=int(seconds), message=close_message, auto_close=True - ) + await self.close(closer=self.bot.user, after=int(seconds), message=close_message, auto_close=True) async def find_linked_messages( self, @@ -561,11 +546,7 @@ async def find_linked_messages( note: bool = True, ) -> typing.Tuple[discord.Message, typing.Optional[discord.Message]]: if message1 is not None: - if ( - not message1.embeds - or not message1.embeds[0].author.url - or message1.author != self.bot.user - ): + if not message1.embeds or not message1.embeds[0].author.url or message1.author != self.bot.user: raise ValueError("Malformed thread message.") elif message_id is not None: @@ -602,10 +583,7 @@ async def find_linked_messages( and message1.embeds[0].color and ( message1.embeds[0].color.value == self.bot.mod_color - or ( - either_direction - and message1.embeds[0].color.value == self.bot.recipient_color - ) + or (either_direction and message1.embeds[0].color.value == self.bot.recipient_color) ) and message1.embeds[0].author.url.split("#")[-1].isdigit() and message1.author == self.bot.user @@ -710,13 +688,9 @@ async def edit_dm_message(self, message: discord.Message, content: str) -> None: embed = linked_message.embeds[0] embed.add_field(name="**Edited, former message:**", value=embed.description) embed.description = content - await asyncio.gather( - self.bot.api.edit_message(message.id, content), linked_message.edit(embed=embed) - ) + await asyncio.gather(self.bot.api.edit_message(message.id, content), linked_message.edit(embed=embed)) - async def note( - self, message: discord.Message, persistent=False, thread_creation=False - ) -> None: + async def note(self, message: discord.Message, persistent=False, thread_creation=False) -> None: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) @@ -729,16 +703,12 @@ async def note( ) self.bot.loop.create_task( - self.bot.api.append_log( - message, message_id=msg.id, channel_id=self.channel.id, type_="system" - ) + self.bot.api.append_log(message, message_id=msg.id, channel_id=self.channel.id, type_="system") ) return msg - async def reply( - self, message: discord.Message, anonymous: bool = False, plain: bool = False - ) -> None: + async def reply(self, message: discord.Message, anonymous: bool = False, plain: bool = False) -> None: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): @@ -777,7 +747,10 @@ async def reply( ) tasks.append( message.channel.send( - embed=discord.Embed(color=self.bot.error_color, description=description,) + embed=discord.Embed( + color=self.bot.error_color, + description=description, + ) ) ) else: @@ -825,9 +798,7 @@ async def send( thread_creation: bool = False, ) -> None: - self.bot.loop.create_task( - self._restart_close_timer() - ) # Start or restart thread auto close + self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close if self.close_task is not None: # cancel closing if a thread message is sent. @@ -967,9 +938,7 @@ async def send( file_upload_count = 1 for url, filename, _ in attachments: - embed.add_field( - name=f"File upload ({file_upload_count})", value=f"[{filename}]({url})" - ) + embed.add_field(name=f"File upload ({file_upload_count})", value=f"[{filename}]({url})") file_upload_count += 1 if from_mod: @@ -1028,9 +997,7 @@ async def send( files = [] for i in embed.fields: if "Image" in i.name: - async with self.bot.session.get( - i.field[i.field.find("http") : -1] - ) as resp: + async with self.bot.session.get(i.field[i.field.find("http") : -1]) as resp: stream = io.BytesIO(await resp.read()) files.append(discord.File(stream)) @@ -1119,9 +1086,7 @@ async def find( return thread else: if not thread.channel or not self.bot.get_channel(thread.channel.id): - logger.warning( - "Found existing thread for %s but the channel is invalid.", recipient_id - ) + logger.warning("Found existing thread for %s but the channel is invalid.", recipient_id) self.bot.loop.create_task( thread.close(closer=self.bot.user, silent=True, delete_channel=False) ) @@ -1192,9 +1157,7 @@ async def create( if thread.channel and self.bot.get_channel(thread.channel.id): logger.warning("Found an existing thread for %s, abort creating.", recipient) return thread - logger.warning( - "Found an existing thread for %s, closing previous thread.", recipient - ) + logger.warning("Found an existing thread for %s, closing previous thread.", recipient) self.bot.loop.create_task( thread.close(closer=self.bot.user, silent=True, delete_channel=False) ) @@ -1263,15 +1226,11 @@ async def create( await confirm.remove_reaction(accept_emoji, self.bot.user) await asyncio.sleep(0.2) await confirm.remove_reaction(deny_emoji, self.bot.user) - await destination.send( - embed=discord.Embed(title="Cancelled", color=self.bot.error_color) - ) + await destination.send(embed=discord.Embed(title="Cancelled", color=self.bot.error_color)) del self.cache[recipient.id] return thread - self.bot.loop.create_task( - thread.setup(creator=creator, category=category, initial_message=message) - ) + self.bot.loop.create_task(thread.setup(creator=creator, category=category, initial_message=message)) return thread async def find_or_create(self, recipient) -> Thread: diff --git a/core/time.py b/core/time.py index 331e26349f..bdec8d2549 100644 --- a/core/time.py +++ b/core/time.py @@ -57,9 +57,7 @@ def __init__(self, argument): if not status.hasTime: # replace it with the current time - dt = dt.replace( - hour=now.hour, minute=now.minute, second=now.second, microsecond=now.microsecond - ) + dt = dt.replace(hour=now.hour, minute=now.minute, second=now.second, microsecond=now.microsecond) self.dt = dt self._past = dt < now diff --git a/core/utils.py b/core/utils.py index 2dfb319a8e..af47c8e2e6 100644 --- a/core/utils.py +++ b/core/utils.py @@ -355,8 +355,7 @@ def format_channel_name(bot, author, exclude_channel=None, force_null=False): name = "null" name = new_name = ( - "".join(l for l in name if l not in string.punctuation and l.isprintable()) - or "null" + "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" ) + f"-{author.discriminator}" counter = 1 diff --git a/pyproject.toml b/pyproject.toml index a920956e85..994cdd7cca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [tool.black] -line-length = 99 -target-version = ['py37'] +line-length = "110" +target-version = ['py39'] include = '\.pyi?$' -exclude = ''' +extend-exclude = ''' ( /( \.eggs @@ -18,3 +18,9 @@ exclude = ''' )/ ) ''' + +[tool.pylint.messages_control] +disable = "C0330, C0326" + +[tool.pylint.format] +max-line-length = "110" From b3a2918c34587f1c45b590402e87f1c5ccde06ad Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Wed, 7 Jul 2021 19:46:36 +0800 Subject: [PATCH 371/705] Remove flake8 from req, use new rec line-width of 110, black format --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0cc483cc3c..39904e9180 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ parsedatetime==2.6 pymongo==3.11.4 python-dateutil==2.8.1 python-dotenv==0.18.0 -six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' +six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' typing-extensions==3.10.0.0 uvloop==0.15.2; sys_platform != 'win32' yarl==1.6.3; python_version >= '3.6' From 77a1ac41bd2799b8e81cd4e4f33fffbfabdabc9b Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Jul 2021 13:45:26 +0800 Subject: [PATCH 372/705] Add dnspython (pymongo[srv]) as req --- Pipfile | 3 ++- Pipfile.lock | 14 +++++++++++++- requirements.txt | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Pipfile b/Pipfile index 813b6700aa..9c7b4e03b7 100644 --- a/Pipfile +++ b/Pipfile @@ -10,13 +10,14 @@ pylint = "~=2.9.3" [packages] aiohttp = "==3.7.4.post0" -colorama = "~=0.4.4" +colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 "discord.py" = "==1.7.3" emoji = "~=1.2.0" isodate = "~=0.6.0" motor = "~=2.4.0" natural = "~=0.2.0" parsedatetime = "~=2.6" +pymongo = {version = "*", extras = ['srv']} # Required by motor python-dateutil = "~=2.8.1" python-dotenv = "~=0.18.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} diff --git a/Pipfile.lock b/Pipfile.lock index b10f516efc..15fdcacc5c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "dedff7c4534f29ac1560a57f358852e90d6e6b9d04eb07a35f6daa2d661bc0c2" + "sha256": "0e726213f83b90d7c4e90a04cea6636dbdc5be2ad82049c96820535e5cc3d1ad" }, "pipfile-spec": 6, "requires": { @@ -99,6 +99,14 @@ "index": "pypi", "version": "==1.7.3" }, + "dnspython": { + "hashes": [ + "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", + "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, "emoji": { "hashes": [ "sha256:496f432058567985838c13d67dde84ca081614a8286c0b9cdc7d63dfa89d51a3", @@ -190,6 +198,9 @@ "version": "==2.6" }, "pymongo": { + "extras": [ + "srv" + ], "hashes": [ "sha256:03be7ad107d252bb7325d4af6309fdd2c025d08854d35f0e7abc8bf048f4245e", "sha256:071552b065e809d24c5653fcc14968cfd6fde4e279408640d5ac58e3353a3c5f", @@ -256,6 +267,7 @@ "sha256:fedf0dee7a412ca6d1d6d92c158fe9cbaa8ea0cae90d268f9ccc0744de7a97d0", "sha256:fffff7bfb6799a763d3742c59c6ee7ffadda21abed557637bc44ed1080876484" ], + "index": "pypi", "version": "==3.11.4" }, "python-dateutil": { diff --git a/requirements.txt b/requirements.txt index 39904e9180..d802cc0c46 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ attrs==21.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' colorama==0.4.4 discord.py==1.7.3 +dnspython==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.2.0 idna==3.2; python_version >= '3.5' isodate==0.6.0 @@ -19,7 +20,7 @@ motor==2.4.0 multidict==5.1.0; python_version >= '3.6' natural==0.2.0 parsedatetime==2.6 -pymongo==3.11.4 +pymongo[srv]==3.11.4 python-dateutil==2.8.1 python-dotenv==0.18.0 six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' From 79acb3509127cad21d98457d313dcecfd6ac5b7d Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Jul 2021 13:48:33 +0800 Subject: [PATCH 373/705] Updates channel.move, bot.close, emoji changes --- bot.py | 8 ++++---- cogs/modmail.py | 3 ++- cogs/utility.py | 2 +- core/clients.py | 3 +-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bot.py b/bot.py index ce7cfc529d..3cb5bb2d5f 100644 --- a/bot.py +++ b/bot.py @@ -519,7 +519,7 @@ async def on_connect(self): await self.api.validate_database_connection() except Exception: logger.debug("Logging out due to failed database connection.") - return await self.logout() + return await self.close() logger.debug("Connected to gateway.") await self.config.refresh() @@ -534,7 +534,7 @@ async def on_ready(self): if self.guild is None: logger.error("Logging out due to invalid GUILD_ID.") - return await self.logout() + return await self.close() logger.line() logger.debug("Client ready.") @@ -640,7 +640,7 @@ async def convert_emoji(self, name: str) -> str: ctx = SimpleNamespace(bot=self, guild=self.modmail_guild) converter = commands.EmojiConverter() - if name not in UNICODE_EMOJI: + if name not in UNICODE_EMOJI['en']: try: name = await converter.convert(ctx, name.strip(":")) except commands.BadArgument as e: @@ -1607,7 +1607,7 @@ async def autoupdate(self): embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") if self.config["update_notifications"]: await channel.send(embed=embed) - await self.logout() + return await self.close() async def before_autoupdate(self): await self.wait_for_connected() diff --git a/cogs/modmail.py b/cogs/modmail.py index 5b3f67bdd2..55110c323e 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -322,7 +322,8 @@ async def move(self, ctx, *, arguments): silent_words = ["silent", "silently"] silent = any(word in silent_words for word in options.split()) - await thread.channel.edit(category=category, sync_permissions=True) + await thread.channel.move(category=category, end=True, sync_permissions=True, + reason=f"{ctx.author} moved this thread.") if self.bot.config["thread_move_notify"] and not silent: embed = discord.Embed( diff --git a/cogs/utility.py b/cogs/utility.py index 0e03ab1ba1..a00027eca3 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1990,7 +1990,7 @@ async def update(self, ctx, *, flag: str = ""): ) await ctx.send(embed=embed) - await self.bot.logout() + return await self.bot.close() else: embed = discord.Embed( title="Already up to date", diff --git a/core/clients.py b/core/clients.py index 1d90cbb0e3..c8798e5423 100644 --- a/core/clients.py +++ b/core/clients.py @@ -377,9 +377,8 @@ def __init__(self, bot): except ConfigurationError as e: logger.critical( "Your MongoDB CONNECTION_URI might be copied wrong, try re-copying from the source again. " - "Otherwise noted in the following message:" + "Otherwise noted in the following message:\n%s", e ) - logger.critical(e) sys.exit(0) super().__init__(bot, db) From 69d69e63b8f336ce203aaef1854b32fbdbbab527 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Jul 2021 13:58:15 +0800 Subject: [PATCH 374/705] Keep more log files --- core/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/models.py b/core/models.py index d17e118e6c..76889809f7 100644 --- a/core/models.py +++ b/core/models.py @@ -127,7 +127,7 @@ def format(self, record): def configure_logging(name, level=None): global ch_debug, log_level - ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=48000, backupCount=1) + ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=78000, backupCount=10) formatter_debug = FileFormatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", From 703f04f2d63d78facf6fb6808ac05e18b8aaff7c Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Jul 2021 13:59:33 +0800 Subject: [PATCH 375/705] Bump version --- CHANGELOG.md | 7 +++++++ README.md | 2 +- bot.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12f1ddc9ef..fb9ee01487 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.9.5dev1 + +## Misc + +- Bumped discord.py to v1.7.3, updated all other packages to latest. +- More debug log files are now kept. + # v3.9.4 ## Fixed diff --git a/README.md b/README.md index f61512d608..ea70af1ad2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 3cb5bb2d5f..dab03836a1 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.4" +__version__ = "3.9.5dev1" import asyncio From 3ed0eb7f870e9b056ea7901ea68558126b1b784d Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Jul 2021 14:01:45 +0800 Subject: [PATCH 376/705] Black format --- bot.py | 2 +- cogs/modmail.py | 5 +++-- core/clients.py | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bot.py b/bot.py index dab03836a1..1deb9b7d2a 100644 --- a/bot.py +++ b/bot.py @@ -640,7 +640,7 @@ async def convert_emoji(self, name: str) -> str: ctx = SimpleNamespace(bot=self, guild=self.modmail_guild) converter = commands.EmojiConverter() - if name not in UNICODE_EMOJI['en']: + if name not in UNICODE_EMOJI["en"]: try: name = await converter.convert(ctx, name.strip(":")) except commands.BadArgument as e: diff --git a/cogs/modmail.py b/cogs/modmail.py index 55110c323e..81fd2a911e 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -322,8 +322,9 @@ async def move(self, ctx, *, arguments): silent_words = ["silent", "silently"] silent = any(word in silent_words for word in options.split()) - await thread.channel.move(category=category, end=True, sync_permissions=True, - reason=f"{ctx.author} moved this thread.") + await thread.channel.move( + category=category, end=True, sync_permissions=True, reason=f"{ctx.author} moved this thread." + ) if self.bot.config["thread_move_notify"] and not silent: embed = discord.Embed( diff --git a/core/clients.py b/core/clients.py index c8798e5423..5c5acc8fad 100644 --- a/core/clients.py +++ b/core/clients.py @@ -377,7 +377,8 @@ def __init__(self, bot): except ConfigurationError as e: logger.critical( "Your MongoDB CONNECTION_URI might be copied wrong, try re-copying from the source again. " - "Otherwise noted in the following message:\n%s", e + "Otherwise noted in the following message:\n%s", + e, ) sys.exit(0) From 2ace13fc959bf6642aedff629a765096107f29c4 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Jul 2021 14:28:03 +0800 Subject: [PATCH 377/705] Updated sponsors --- README.md | 7 +++++++ SPONSORS.json | 24 ++++++++++++++++++++++-- cogs/utility.py | 17 ++++++++++++----- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f61512d608..81305c51db 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,13 @@ Real Madrid: +
      +
      +Discord Advice Center: +
      + + + Become a sponsor on [Patreon](https://patreon.com/kyber). diff --git a/SPONSORS.json b/SPONSORS.json index 1f1ed56d37..049998ca55 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -21,7 +21,7 @@ "value": "[**Click Here**](https://www.youtube.com/channel/UCgSmBJD9imASmJRleycTCwQ?sub_confirmation=1)" }, { - "name": "Discord Server!", + "name": "Discord Server", "value": "[**Click Here**](https://discord.gg/V8ErqHb)" } ] @@ -37,7 +37,7 @@ }, "fields": [ { - "name": "Discord Server!", + "name": "Discord Server", "value": "[**Click here**](https://discord.gg/BanCwptMJV)" } ] @@ -70,5 +70,25 @@ } ] } + }, + { + "embed": { + "description": "──── 《𝐃𝐢𝐬𝐜𝐨𝐫𝐝 𝐀𝐝𝐯𝐢𝐜𝐞 𝐂𝐞𝐧𝐭𝐞𝐫 》 ────\n\n◈ We are a server aimed to meet your discord needs. We have tools, tricks and tips to grow your server and advertise your server. We offer professional server reviews and suggestions how to run it successfully as a part of our courtesy. Join the server and get the chance to add our very own BUMP BOT called DAC Advertise where you can advertise your server to other servers!\n", + "color": 53380, + "author": { + "name": "Discord Advice Center", + "url": "https://discord.gg/nkMDQfuK", + "icon_url": "https://i.imgur.com/cjVtRw5.jpg" + }, + "image": { + "url": "https://i.imgur.com/1hrjcHd.png" + }, + "fields": [ + { + "name": "Discord Server", + "value": "[**Click Here**](https://discord.gg/nkMDQfuK)" + } + ] + } } ] diff --git a/cogs/utility.py b/cogs/utility.py index 7b39631dcd..58b0449d7d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -356,18 +356,25 @@ async def about(self, ctx): inline=False, ) + embed.add_field( + name="Project Sponsors", + value=f"Checkout the people who supported Modmail with command `{self.bot.prefix}sponsors`!", + inline=False, + ) + embed.set_footer(text=footer) await ctx.send(embed=embed) - @commands.command() + @commands.command(aliases=["sponsor"]) @checks.has_permissions(PermissionLevel.REGULAR) @utils.trigger_typing async def sponsors(self, ctx): - """Shows a list of sponsors.""" - resp = await self.bot.session.get( + """Shows the sponsors of this project.""" + + async with self.bot.session.get( "https://raw.githubusercontent.com/kyb3r/modmail/master/SPONSORS.json" - ) - data = loads(await resp.text()) + ) as resp: + data = loads(await resp.text()) embeds = [] From 1efdc3403a622d70892f30dbffda894228f93ae8 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Fri, 9 Jul 2021 09:50:47 +0800 Subject: [PATCH 378/705] Improved dockerfile --- .dockerignore | 12 +++--------- Dockerfile | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/.dockerignore b/.dockerignore index 99fd4a241b..74003e7e30 100644 --- a/.dockerignore +++ b/.dockerignore @@ -140,17 +140,11 @@ test.py # Other stuff .env.example .gitignore -.lint.py -.pylintrc -.travis.yml +.github/ app.json CHANGELOG.md -CODE_OF_CONDUCT.md -CONTRIBUTING.md -requirements.min.txt Procfile pyproject.toml README.md -runtime.txt -SPONSORS.json -stack.yml \ No newline at end of file +Pipfile +Pipfile.lock diff --git a/Dockerfile b/Dockerfile index 8165e06a53..232e84fb20 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,16 @@ -FROM python:3.7-alpine +FROM python:3.9-slim as py + +FROM py as build + +RUN apt update && apt install -y g++ +COPY requirements.min.txt / +RUN pip install --prefix=/inst -U -r /requirements.min.txt + +FROM py + ENV USING_DOCKER yes +COPY --from=build /inst /usr/local + WORKDIR /modmailbot +CMD ["python", "bot.py"] COPY . /modmailbot -RUN export PIP_NO_CACHE_DIR=false \ - && apk update \ - && apk add --update --no-cache --virtual .build-deps alpine-sdk \ - && pip install pipenv \ - && pipenv install --deploy --ignore-pipfile \ - && apk del .build-deps -CMD ["pipenv", "run", "bot"] \ No newline at end of file From 2c26227a12712c6b550245b9aa33e36b909c91b0 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Fri, 9 Jul 2021 10:20:16 +0800 Subject: [PATCH 379/705] Add restart and environment for bot --- docker-compose.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5d2061df6b..d3745c9b4c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,20 +2,25 @@ version: "3.7" services: bot: image: kyb3rr/modmail + restart: always env_file: - .env + environment: + - CONNECTION_URI=mongodb://mongo depends_on: - mongo logviewer: image: kyb3rr/logviewer + restart: always depends_on: - mongo environment: - MONGO_URI=mongodb://mongo ports: - - 8000:8000 + - 80:8000 mongo: image: mongo + restart: always volumes: - mongodb:/data/db From 05cde283d31af5622da8ded6b81f68620eafda59 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Fri, 9 Jul 2021 10:26:03 +0800 Subject: [PATCH 380/705] Update sponsors --- README.md | 2 +- SPONSORS.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 81305c51db..701661c4d0 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,7 @@ Real Madrid:
      Discord Advice Center:
      - + diff --git a/SPONSORS.json b/SPONSORS.json index 049998ca55..30081e24e5 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -86,7 +86,7 @@ "fields": [ { "name": "Discord Server", - "value": "[**Click Here**](https://discord.gg/nkMDQfuK)" + "value": "[**Click Here**](https://discord.gg/zmwZy5fd9v)" } ] } From 10f1bccf4722026d8c7aa0474e048d8a0b9ada2f Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sat, 10 Jul 2021 15:49:28 +0200 Subject: [PATCH 381/705] Update modmail.py fix typo { https://github.com/kyb3r/modmail/pull/3067 } { https://usagi.xn--6frz82g/6DEshJ } --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 87b9d91e57..8b91342fa4 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -537,7 +537,7 @@ async def subscribe( if mention in mentions: embed = discord.Embed( color=self.bot.error_color, - description=f"{mention} is not subscribed to this thread.", + description=f"{mention} is already subscribed to this thread.", ) else: mentions.append(mention) From 1a238b3099b5593a5465479ef63c6ffbadd9b07e Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 22 Jul 2021 16:17:06 +0800 Subject: [PATCH 382/705] Formatting and final updates to deps --- Pipfile.lock | 225 +++++++++++++++++++++++++++------------------- bot.py | 49 +++------- cogs/modmail.py | 84 +++++------------ cogs/plugins.py | 19 ++-- cogs/utility.py | 86 +++++------------- core/changelog.py | 10 +-- core/checks.py | 4 +- core/clients.py | 34 ++----- core/models.py | 7 +- core/thread.py | 32 ++----- 10 files changed, 210 insertions(+), 340 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 15fdcacc5c..a9f820119e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -202,81 +202,115 @@ "srv" ], "hashes": [ - "sha256:03be7ad107d252bb7325d4af6309fdd2c025d08854d35f0e7abc8bf048f4245e", - "sha256:071552b065e809d24c5653fcc14968cfd6fde4e279408640d5ac58e3353a3c5f", - "sha256:08b8723248730599c9803ae4c97b8f3f76c55219104303c88cb962a31e3bb5ee", - "sha256:08bda7b2c522ff9f1e554570da16298271ebb0c56ab9699446aacba249008988", - "sha256:0aaf4d44f1f819360f9432df538d54bbf850f18152f34e20337c01b828479171", - "sha256:0cabfc297f4cf921f15bc789a8fbfd7115eb9f813d3f47a74b609894bc66ab0d", - "sha256:13acf6164ead81c9fc2afa0e1ea6d6134352973ce2bb35496834fee057063c04", - "sha256:15b083d1b789b230e5ac284442d9ecb113c93f3785a6824f748befaab803b812", - "sha256:161fcd3281c42f644aa8dec7753cca2af03ce654e17d76da4f0dab34a12480ca", - "sha256:1a994a42f49dab5b6287e499be7d3d2751776486229980d8857ad53b8333d469", - "sha256:20d75ea11527331a2980ab04762a9d960bcfea9475c54bbeab777af880de61cd", - "sha256:225c61e08fe517aede7912937939e09adf086c8e6f7e40d4c85ad678c2c2aea3", - "sha256:3135dd574ef1286189f3f04a36c8b7a256376914f8cbbce66b94f13125ded858", - "sha256:3491c7de09e44eded16824cb58cf9b5cc1dc6f066a0bb7aa69929d02aa53b828", - "sha256:3551912f5c34d8dd7c32c6bb00ae04192af47f7b9f653608f107d19c1a21a194", - "sha256:38a7b5140a48fc91681cdb5cb95b7cd64640b43d19259fdd707fa9d5a715f2b2", - "sha256:3a3498a8326111221560e930f198b495ea6926937e249f475052ffc6893a6680", - "sha256:3bfc7689a1bacb9bcd2f2d5185d99507aa29f667a58dd8adaa43b5a348139e46", - "sha256:421d13523d11c57f57f257152bc4a6bb463aadf7a3918e9c96fefdd6be8dbfb8", - "sha256:424799c71ff435094e5fb823c40eebb4500f0e048133311e9c026467e8ccebac", - "sha256:474e21d0e07cd09679e357d1dac76e570dab86665e79a9d3354b10a279ac6fb3", - "sha256:4c7e8c8e1e1918dcf6a652ac4b9d87164587c26fd2ce5dd81e73a5ab3b3d492f", - "sha256:506a6dab4c7ffdcacdf0b8e70bd20eb2e77fa994519547c9d88d676400fcad58", - "sha256:510cd3bfabb63a07405b7b79fae63127e34c118b7531a2cbbafc7a24fd878594", - "sha256:517ba47ca04a55b1f50ee8df9fd97f6c37df5537d118fb2718952b8623860466", - "sha256:539d4cb1b16b57026999c53e5aab857fe706e70ae5310cc8c232479923f932e6", - "sha256:5c36428cc4f7fae56354db7f46677fd21222fc3cb1e8829549b851172033e043", - "sha256:5db59223ed1e634d842a053325f85f908359c6dac9c8ddce8ef145061fae7df8", - "sha256:5e606846c049ed40940524057bfdf1105af6066688c0e6a1a3ce2038589bae70", - "sha256:6060794aac9f7b0644b299f46a9c6cbc0bc470bd01572f4134df140afd41ded6", - "sha256:62c29bc36a6d9be68fe7b5aaf1e120b4aa66a958d1e146601fcd583eb12cae7b", - "sha256:73326b211e7410c8bd6a74500b1e3f392f39cf10862e243d00937e924f112c01", - "sha256:78f07961f4f214ea8e80be63cffd5cc158eb06cd922ffbf6c7155b11728f28f9", - "sha256:7c97554ea521f898753d9773891d0347ebfaddcc1dee2ad94850b163171bf1f1", - "sha256:8898f6699f740ca93a0879ed07d8e6db02d68af889d0ebb3d13ab017e6b1af1e", - "sha256:8a41fdc751dc4707a4fafb111c442411816a7c225ebb5cadb57599534b5d5372", - "sha256:8e0004b0393d72d76de94b4792a006cb960c1c65c7659930fbf9a81ce4341982", - "sha256:977b1d4f868986b4ba5d03c317fde4d3b66e687d74473130cd598e3103db34fa", - "sha256:9a4f6e0b01df820ba9ed0b4e618ca83a1c089e48d4f268d0e00dcd49893d4549", - "sha256:9b9298964389c180a063a9e8bac8a80ed42de11d04166b20249bfa0a489e0e0f", - "sha256:a08c8b322b671857c81f4c30cd3c8df2895fd3c0e9358714f39e0ef8fb327702", - "sha256:ad31f184dcd3271de26ab1f9c51574afb99e1b0e484ab1da3641256b723e4994", - "sha256:aff3656af2add93f290731a6b8930b23b35c0c09569150130a58192b3ec6fc61", - "sha256:b2f41261b648cf5dee425f37ff14f4ad151c2f24b827052b402637158fd056ef", - "sha256:b413117210fa6d92664c3d860571e8e8727c3e8f2ff197276c5d0cb365abd3ad", - "sha256:b7efc7e7049ef366777cfd35437c18a4166bb50a5606a1c840ee3b9624b54fc9", - "sha256:b8f94acd52e530a38f25e4d5bf7ddfdd4bea9193e718f58419def0d4406b58d3", - "sha256:d0a70151d7de8a3194cdc906bcc1a42e14594787c64b0c1c9c975e5a2af3e251", - "sha256:d360e5d5dd3d55bf5d1776964625018d85b937d1032bae1926dd52253decd0db", - "sha256:d4e62417e89b717a7bcd8576ac3108cd063225942cc91c5b37ff5465fdccd386", - "sha256:d65bac5f6724d9ea6f0b5a0f0e4952fbbf209adcf6b5583b54c54bd2fcd74dc0", - "sha256:e02beaab433fd1104b2804f909e694cfbdb6578020740a9051597adc1cd4e19f", - "sha256:e4b631688dfbdd61b5610e20b64b99d25771c6d52d9da73349342d2a0f11c46a", - "sha256:e4e9db78b71db2b1684ee4ecc3e32c4600f18cdf76e6b9ae03e338e52ee4b168", - "sha256:eb4d176394c37a76e8b0afe54b12d58614a67a60a7f8c0dd3a5afbb013c01092", - "sha256:f08665d3cc5abc2f770f472a9b5f720a9b3ab0b8b3bb97c7c1487515e5653d39", - "sha256:f3d851af3852f16ad4adc7ee054fd9c90a7a5063de94d815b7f6a88477b9f4c6", - "sha256:f4ba58157e8ae33ee86fadf9062c506e535afd904f07f9be32731f4410a23b7f", - "sha256:f664ed7613b8b18f0ce5696b146776266a038c19c5cd6efffa08ecc189b01b73", - "sha256:f947b359cc4769af8b49be7e37af01f05fcf15b401da2528021148e4a54426d1", - "sha256:fe4189846448df013cd9df11bba38ddf78043f8c290a9f06430732a7a8601cce", - "sha256:fea5cb1c63efe1399f0812532c7cf65458d38fd011be350bc5021dfcac39fba8", - "sha256:fedf0dee7a412ca6d1d6d92c158fe9cbaa8ea0cae90d268f9ccc0744de7a97d0", - "sha256:fffff7bfb6799a763d3742c59c6ee7ffadda21abed557637bc44ed1080876484" + "sha256:02dc0b0f48ed3cd06c13b7e31b066bf91e00dac5f8147b0a0a45f9009bfab857", + "sha256:053b4ebf91c7395d1fcd2ce6a9edff0024575b7b2de6781554a4114448a8adc9", + "sha256:070a4ef689c9438a999ec3830e69b208ff0d12251846e064d947f97d819d1d05", + "sha256:072ba7cb65c8aa4d5c5659bf6722ee85781c9d7816dc00679b8b6f3dff1ddafc", + "sha256:0b6055e0ef451ff73c93d0348d122a0750dddf323b9361de5835dac2f6cf7fc1", + "sha256:11f9e0cfc84ade088a38df2708d0b958bb76360181df1b2e1e1a41beaa57952b", + "sha256:18290649759f9db660972442aa606f845c368db9b08c4c73770f6da14113569b", + "sha256:186104a94d39b8412f8e3de385acd990a628346a4402d4f3a288a82b8660bd22", + "sha256:1970cfe2aec1bf74b40cf30c130ad10cd968941694630386db33e1d044c22a2e", + "sha256:19d4bd0fc29aa405bb1781456c9cfff9fceabb68543741eb17234952dbc2bbb0", + "sha256:1bab889ae7640eba739f67fcbf8eff252dddc60d4495e6ddd3a87cd9a95fdb52", + "sha256:1bc6fe7279ff40c6818db002bf5284aa03ec181ea1b1ceaeee33c289d412afa7", + "sha256:208debdcf76ed39ebf24f38509f50dc1c100e31e8653817fedb8e1f867850a13", + "sha256:2399a85b54f68008e483b2871f4a458b4c980469c7fe921595ede073e4844f1e", + "sha256:246ec420e4c8744fceb4e259f906211b9c198e1f345e6158dcd7cbad3737e11e", + "sha256:24f8aeec4d6b894a6128844e50ff423dd02462ee83addf503c598ee3a80ddf3d", + "sha256:255a35bf29185f44b412e31a927d9dcedda7c2c380127ecc4fbf2f61b72fa978", + "sha256:2dbfbbded947a83a3dffc2bd1ec4750c17e40904692186e2c55a3ad314ca0222", + "sha256:2e92aa32300a0b5e4175caec7769f482b292769807024a86d674b3f19b8e3755", + "sha256:316c1b8723afa9870567cd6dff35d440b2afeda53aa13da6c5ab85f98ed6f5ca", + "sha256:333bfad77aa9cd11711febfb75eed0bb537a1d022e1c252714dad38993590240", + "sha256:39dafa2eaf577d1969f289dc9a44501859a1897eb45bd589e93ce843fc610800", + "sha256:3ce83f17f641a62a4dfb0ba1b8a3c1ced7c842f511b5450d90c030c7828e3693", + "sha256:46d5ec90276f71af3a29917b30f2aec2315a2759b5f8d45b3b63a07ca8a070a3", + "sha256:48d5bc80ab0af6b60c4163c5617f5cd23f2f880d7600940870ea5055816af024", + "sha256:4ba0def4abef058c0e5101e05e3d5266e6fffb9795bbf8be0fe912a7361a0209", + "sha256:5af390fa9faf56c93252dab09ea57cd020c9123aa921b63a0ed51832fdb492e7", + "sha256:5e574664f1468872cd40f74e4811e22b1aa4de9399d6bcfdf1ee6ea94c017fcf", + "sha256:625befa3bc9b40746a749115cc6a15bf20b9bd7597ca55d646205b479a2c99c7", + "sha256:6261bee7c5abadeac7497f8f1c43e521da78dd13b0a2439f526a7b0fc3788824", + "sha256:657ad80de8ec9ed656f28844efc801a0802961e8c6a85038d97ff6f555ef4919", + "sha256:6b89dc51206e4971c5568c797991eaaef5dc2a6118d67165858ad11752dba055", + "sha256:6e66780f14c2efaf989cd3ac613b03ee6a8e3a0ba7b96c0bb14adca71a427e55", + "sha256:6fb3f85870ae26896bb44e67db94045f2ebf00c5d41e6b66cdcbb5afd644fc18", + "sha256:701e08457183da70ed96b35a6b43e6ba1df0b47c837b063cde39a1fbe1aeda81", + "sha256:70761fd3c576b027eec882b43ee0a8e5b22ff9c20cdf4d0400e104bc29e53e34", + "sha256:73b400fdc22de84bae0dbf1a22613928a41612ec0a3d6ed47caf7ad4d3d0f2ff", + "sha256:7412a36798966624dc4c57d64aa43c2d1100b348abd98daaac8e99e57d87e1d7", + "sha256:78ecb8d42f50d393af912bfb1fb1dcc9aabe9967973efb49ee577e8f1cea494c", + "sha256:7c6a9948916a7bbcc6d3a9f6fb75db1acb5546078023bfb3db6efabcd5a67527", + "sha256:7c72d08acdf573455b2b9d2b75b8237654841d63a48bc2327dc102c6ee89b75a", + "sha256:7d98ce3c42921bb91566121b658e0d9d59a9082a9bd6f473190607ff25ab637f", + "sha256:845a8b83798b2fb11b09928413cb32692866bfbc28830a433d9fa4c8c3720dd0", + "sha256:94d38eba4d1b5eb3e6bfece0651b855a35c44f32fd91f512ab4ba41b8c0d3e66", + "sha256:9a13661681d17e43009bb3e85e837aa1ec5feeea1e3654682a01b8821940f8b3", + "sha256:a0e5dff6701fa615f165306e642709e1c1550d5b237c5a7a6ea299886828bd50", + "sha256:a2239556ff7241584ce57be1facf25081669bb457a9e5cbe68cce4aae6567aa1", + "sha256:a325600c83e61e3c9cebc0c2b1c8c4140fa887f789085075e8f44c8ff2547eb9", + "sha256:a3566acfbcde46911c52810374ecc0354fdb841284a3efef6ff7105bc007e9a8", + "sha256:a634a4730ce0b0934ed75e45beba730968e12b4dafbb22f69b3b2f616d9e644e", + "sha256:a6d055f01b83b1a4df8bb0c61983d3bdffa913764488910af3620e5c2450bf83", + "sha256:a752ecd1a26000a6d67be7c9a2e93801994a8b3f866ac95b672fbc00225ca91a", + "sha256:a9ba2a63777027b06b116e1ea8248e66fd1bedc2c644f93124b81a91ddbf6d88", + "sha256:aaa038eafb7186a4abbb311fcf20724be9363645882bbce540bef4797e812a7a", + "sha256:af586e85144023686fb0af09c8cdf672484ea182f352e7ceead3d832de381e1b", + "sha256:b0a0cf39f589e52d801fdef418305562bc030cdf8929217463c8433c65fd5c2f", + "sha256:b1c4874331ab960429caca81acb9d2932170d66d6d6f87e65dc4507a85aca152", + "sha256:b3b5b3cbc3fdf4fcfa292529df2a85b5d9c7053913a739d3069af1e12e12219f", + "sha256:b542d56ed1b8d5cf3bb36326f814bd2fbe8812dfd2582b80a15689ea433c0e35", + "sha256:b6ea08758b6673610b3c5bdf47189286cf9c58b1077558706a2f6f8744922527", + "sha256:b754240daafecd9d5fce426b0fbaaed03f4ebb130745c8a4ae9231fffb8d75e5", + "sha256:b772bab31cbd9cb911e41e1a611ebc9497f9a32a7348e2747c38210f75c00f41", + "sha256:b88d1742159bc93a078733f9789f563cef26f5e370eba810476a71aa98e5fbc2", + "sha256:b8bf42d3b32f586f4c9e37541769993783a534ad35531ce8a4379f6fa664fba9", + "sha256:bc9ac81e73573516070d24ce15da91281922811f385645df32bd3c8a45ab4684", + "sha256:c188db6cf9e14dbbb42f5254292be96f05374a35e7dfa087cc2140f0ff4f10f6", + "sha256:c55782a55f4a013a78ac5b6ee4b8731a192dea7ab09f1b6b3044c96d5128edd4", + "sha256:c5cab230e7cabdae9ff23c12271231283efefb944c1b79bed79a91beb65ba547", + "sha256:cbf8672edeb7b7128c4a939274801f0e32bbf5159987815e3d1eace625264a46", + "sha256:cc2894fe91f31a513860238ede69fe47fada21f9e7ddfe73f7f9fef93a971e41", + "sha256:cda9e628b1315beec8341e8c04aac9a0b910650b05e0751e42e399d5694aeacb", + "sha256:ceae3ab9e11a27aaab42878f1d203600dfd24f0e43678b47298219a0f10c0d30", + "sha256:ced944dcdd561476deef7cb7bfd4987c69fffbfeff6d02ca4d5d4fd592d559b7", + "sha256:d04ca462cb99077e6c059e97c072957caf2918e6e4191e3161c01c439e0193de", + "sha256:d1131562ddc2ea8a446f66c2648d7dabec2b3816fc818528eb978a75a6d23b2e", + "sha256:d1740776b70367277323fafb76bcf09753a5cc9824f5d705bac22a34ff3668ea", + "sha256:d6e11ffd43184d529d6752d6dcb62b994f903038a17ea2168ef1910c96324d26", + "sha256:d73e10772152605f6648ba4410318594f1043bbfe36d2fadee7c4b8912eff7c5", + "sha256:da8288bc4a7807c6715416deed1c57d94d5e03e93537889e002bf985be503f1a", + "sha256:db93608a246da44d728842b8fa9e45aa9782db76955f634a707739a8d53ff544", + "sha256:dcd3d0009fbb6e454d729f8b22d0063bd9171c31a55e0f0271119bd4f2700023", + "sha256:dd1f49f949a658c4e8f81ed73f9aad25fcc7d4f62f767f591e749e30038c4e1d", + "sha256:dd6ff2192f34bd622883c745a56f492b1c9ccd44e14953e8051c33024a2947d5", + "sha256:e018a4921657c2d3f89c720b7b90b9182e277178a04a7e9542cc79d7d787ca51", + "sha256:e2b7670c0c8c6b501464150dd49dd0d6be6cb7f049e064124911cec5514fa19e", + "sha256:e7a33322e08021c37e89cae8ff06327503e8a1719e97c69f32c31cbf6c30d72c", + "sha256:e8a82e35d52ad6f867e88096a1a2b9bdc7ec4d5e65c7b4976a248bf2d1a32a93", + "sha256:e9faf8d4712d5ea301d74abfcf6dafe4b7f4af7936e91f283b0ad7bf69ed3e3a", + "sha256:ec5ca7c0007ce268048bbe0ffc6846ed1616cf3d8628b136e81d5e64ff3f52a2", + "sha256:eee42a1cc06565f6b21caa1f504ec15e07de7ebfd520ab57f8cb3308bc118e22", + "sha256:f2acf9bbcd514e901f82c4ca6926bbd2ae61716728f110b4343eb0a69612d018", + "sha256:f55c1ddcc1f6050b07d468ce594f55dbf6107b459e16f735d26818d7be1e9538", + "sha256:f6977a520bd96e097c8a37a8cbb9faa1ea99d21bf84190195056e25f688af73d", + "sha256:f94c7d22fb36b184734dded7345a04ec5f95130421c775b8b0c65044ef073f34", + "sha256:fa8957e9a1b202cb45e6b839c241cd986c897be1e722b81d2f32e9c6aeee80b0", + "sha256:fd3854148005c808c485c754a184c71116372263709958b42aefbef2e5dd373a", + "sha256:fe5872ce6f9627deac8314bdffd3862624227c3de4c17ef0cc78bbf0402999eb", + "sha256:ffbae429ba9e42d0582d3ac63fdb410338892468a2107d8ff68228ec9a39a0ed" ], "index": "pypi", - "version": "==3.11.4" + "version": "==3.12.0" }, "python-dateutil": { "hashes": [ - "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", - "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], "index": "pypi", - "version": "==2.8.1" + "version": "==2.8.2" }, "python-dotenv": { "hashes": [ @@ -304,20 +338,19 @@ }, "uvloop": { "hashes": [ - "sha256:114543c84e95df1b4ff546e6e3a27521580466a30127f12172a3278172ad68bc", - "sha256:19fa1d56c91341318ac5d417e7b61c56e9a41183946cc70c411341173de02c69", - "sha256:2bb0624a8a70834e54dde8feed62ed63b50bad7a1265c40d6403a2ac447bce01", - "sha256:42eda9f525a208fbc4f7cecd00fa15c57cc57646c76632b3ba2fe005004f051d", - "sha256:44cac8575bf168601424302045234d74e3561fbdbac39b2b54cc1d1d00b70760", - "sha256:6de130d0cb78985a5d080e323b86c5ecaf3af82f4890492c05981707852f983c", - "sha256:7ae39b11a5f4cec1432d706c21ecc62f9e04d116883178b09671aa29c46f7a47", - "sha256:90e56f17755e41b425ad19a08c41dc358fa7bf1226c0f8e54d4d02d556f7af7c", - "sha256:b45218c99795803fb8bdbc9435ff7f54e3a591b44cd4c121b02fa83affb61c7c", - "sha256:e5e5f855c9bf483ee6cd1eb9a179b740de80cb0ae2988e3fa22309b78e2ea0e7" + "sha256:0de811931e90ae2da9e19ce70ffad73047ab0c1dba7c6e74f9ae1a3aabeb89bd", + "sha256:1ff05116ede1ebdd81802df339e5b1d4cab1dfbd99295bf27e90b4cec64d70e9", + "sha256:2d8ffe44ae709f839c54bacf14ed283f41bee90430c3b398e521e10f8d117b3a", + "sha256:5cda65fc60a645470b8525ce014516b120b7057b576fa876cdfdd5e60ab1efbb", + "sha256:63a3288abbc9c8ee979d7e34c34e780b2fbab3e7e53d00b6c80271119f277399", + "sha256:7522df4e45e4f25b50adbbbeb5bb9847495c438a628177099d2721f2751ff825", + "sha256:7f4b8a905df909a407c5791fb582f6c03b0d3b491ecdc1cdceaefbc9bf9e08f6", + "sha256:905f0adb0c09c9f44222ee02f6b96fd88b493478fffb7a345287f9444e926030", + "sha256:ae2b325c0f6d748027f7463077e457006b4fdb35a8788f01754aadba825285ee", + "sha256:e71fb9038bfcd7646ca126c5ef19b17e48d4af9e838b2bcfda7a9f55a6552a32" ], - "index": "pypi", "markers": "sys_platform != 'win32'", - "version": "==0.15.2" + "version": "==0.15.3" }, "yarl": { "hashes": [ @@ -373,11 +406,11 @@ }, "astroid": { "hashes": [ - "sha256:38b95085e9d92e2ca06cf8b35c12a74fa81da395a6f9e65803742e6509c05892", - "sha256:606b2911d10c3dcf35e58d2ee5c97360e8477d7b9f3efc3f24811c93e6fc2cd9" + "sha256:7b963d1c590d490f60d2973e57437115978d3a2529843f160b5003b721e1e925", + "sha256:83e494b02d75d07d4e347b27c066fd791c0c74fc96c613d1ea3de0c82c48168f" ], "markers": "python_version ~= '3.6'", - "version": "==2.6.2" + "version": "==2.6.5" }, "bandit": { "hashes": [ @@ -403,6 +436,14 @@ "markers": "python_version >= '3.6'", "version": "==8.0.1" }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "index": "pypi", + "version": "==0.4.4" + }, "gitdb": { "hashes": [ "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0", @@ -421,11 +462,11 @@ }, "isort": { "hashes": [ - "sha256:83510593e07e433b77bd5bff0f6f607dbafa06d1a89022616f02d8b699cfcd56", - "sha256:8e2c107091cfec7286bc0f68a547d0ba4c094d460b732075b6fba674f1035c0c" + "sha256:eed17b53c3e7912425579853d078a0832820f023191561fcee9d7cae424e0813", + "sha256:f65ce5bd4cbc6abdfbe29afc2f0245538ab358c14590912df638033f157d555e" ], "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", - "version": "==5.9.1" + "version": "==5.9.2" }, "lazy-object-proxy": { "hashes": [ @@ -471,10 +512,10 @@ }, "pathspec": { "hashes": [ - "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd", - "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d" + "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", + "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1" ], - "version": "==0.8.1" + "version": "==0.9.0" }, "pbr": { "hashes": [ @@ -486,11 +527,11 @@ }, "pylint": { "hashes": [ - "sha256:23a1dc8b30459d78e9ff25942c61bb936108ccbe29dd9e71c01dc8274961709a", - "sha256:5d46330e6b8886c31b5e3aba5ff48c10f4aa5e76cbf9002c6544306221e63fbc" + "sha256:1f333dc72ef7f5ea166b3230936ebcfb1f3b722e76c980cb9fe6b9f95e8d3172", + "sha256:748f81e5776d6273a6619506e08f1b48ff9bcb8198366a56821cf11aac14fc87" ], "index": "pypi", - "version": "==2.9.3" + "version": "==2.9.5" }, "pyyaml": { "hashes": [ diff --git a/bot.py b/bot.py index 1deb9b7d2a..131032ec80 100644 --- a/bot.py +++ b/bot.py @@ -506,8 +506,7 @@ def command_perm(self, command_name: str) -> PermissionLevel: logger.debug("Command %s not found.", command_name) return PermissionLevel.INVALID level = next( - (check.permission_level for check in command.checks if hasattr(check, "permission_level")), - None, + (check.permission_level for check in command.checks if hasattr(check, "permission_level")), None, ) if level is None: logger.debug("Command %s does not have a permission level.", command_name) @@ -610,13 +609,7 @@ async def on_ready(self): if self.config.get("data_collection"): self.metadata_loop = tasks.Loop( - self.post_metadata, - seconds=0, - minutes=0, - hours=1, - count=None, - reconnect=True, - loop=None, + self.post_metadata, seconds=0, minutes=0, hours=1, count=None, reconnect=True, loop=None, ) self.metadata_loop.before_loop(self.before_post_metadata) self.metadata_loop.start() @@ -769,8 +762,7 @@ def check_manual_blocked(self, author: discord.Member) -> bool: end_time = re.search(r"%([^%]+?)%", blocked_reason) if end_time is not None: logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", - author.name, + r"Deprecated time message for user %s, block and unblock again to update.", author.name, ) if end_time is not None: @@ -791,11 +783,7 @@ async def _process_blocked(self, message): return False async def is_blocked( - self, - author: discord.User, - *, - channel: discord.TextChannel = None, - send_message: bool = False, + self, author: discord.User, *, channel: discord.TextChannel = None, send_message: bool = False, ) -> typing.Tuple[bool, str]: member = self.guild.get_member(author.id) @@ -826,9 +814,7 @@ async def is_blocked( if send_message: await channel.send( embed=discord.Embed( - title="Message not sent!", - description=new_reason, - color=self.error_color, + title="Message not sent!", description=new_reason, color=self.error_color, ) ) return True @@ -927,8 +913,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: description=self.config["disabled_current_thread_response"], ) embed.set_footer( - text=self.config["disabled_current_thread_footer"], - icon_url=self.guild.icon_url, + text=self.config["disabled_current_thread_footer"], icon_url=self.guild.icon_url, ) logger.info("A message was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -1289,18 +1274,14 @@ async def on_raw_reaction_add(self, payload): await message.remove_reaction(payload.emoji, member) await message.add_reaction(emoji_fmt) # bot adds as well - if self.config["dm_disabled"] in ( - DMDisabled.NEW_THREADS, - DMDisabled.ALL_THREADS, - ): + if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS,): embed = discord.Embed( title=self.config["disabled_new_thread_title"], color=self.error_color, description=self.config["disabled_new_thread_response"], ) embed.set_footer( - text=self.config["disabled_new_thread_footer"], - icon_url=self.guild.icon_url, + text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon_url, ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", @@ -1359,9 +1340,7 @@ async def on_member_remove(self, member): if thread: if self.config["close_on_leave"]: await thread.close( - closer=member.guild.me, - message=self.config["close_on_leave_reason"], - silent=True, + closer=member.guild.me, message=self.config["close_on_leave_reason"], silent=True, ) else: embed = discord.Embed( @@ -1544,9 +1523,7 @@ async def autoupdate(self): commit_data = data["data"] user = data["user"] embed.set_author( - name=user["username"] + " - Updating Bot", - icon_url=user["avatar_url"], - url=user["url"], + name=user["username"] + " - Updating Bot", icon_url=user["avatar_url"], url=user["url"], ) embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") @@ -1575,11 +1552,7 @@ async def autoupdate(self): pass command = "git pull" - proc = await asyncio.create_subprocess_shell( - command, - stderr=PIPE, - stdout=PIPE, - ) + proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() diff --git a/cogs/modmail.py b/cogs/modmail.py index 0e41b76677..0db8a85e2e 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -50,9 +50,7 @@ async def setup(self, ctx): if self.bot.modmail_guild is None: embed = discord.Embed( - title="Error", - description="Modmail functioning guild not found.", - color=self.bot.error_color, + title="Error", description="Modmail functioning guild not found.", color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -184,9 +182,7 @@ async def snippet_raw(self, ctx, *, name: str.lower): else: val = truncate(escape_code_block(val), 2048 - 7) embed = discord.Embed( - title=f'Raw snippet - "{name}":', - description=f"```\n{val}```", - color=self.bot.main_color, + title=f'Raw snippet - "{name}":', description=f"```\n{val}```", color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -208,9 +204,7 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte """ if name in self.bot.snippets: embed = discord.Embed( - title="Error", - color=self.bot.error_color, - description=f"Snippet `{name}` already exists.", + title="Error", color=self.bot.error_color, description=f"Snippet `{name}` already exists.", ) return await ctx.send(embed=embed) @@ -234,9 +228,7 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte await self.bot.config.update() embed = discord.Embed( - title="Added snippet", - color=self.bot.main_color, - description="Successfully created snippet.", + title="Added snippet", color=self.bot.main_color, description="Successfully created snippet.", ) return await ctx.send(embed=embed) @@ -453,8 +445,7 @@ async def notify(self, ctx, *, user_or_role: Union[discord.Role, User, str.lower if mention in mentions: embed = discord.Embed( - color=self.bot.error_color, - description=f"{mention} is already going to be mentioned.", + color=self.bot.error_color, description=f"{mention} is already going to be mentioned.", ) else: mentions.append(mention) @@ -489,8 +480,7 @@ async def unnotify(self, ctx, *, user_or_role: Union[discord.Role, User, str.low if mention not in mentions: embed = discord.Embed( - color=self.bot.error_color, - description=f"{mention} does not have a pending notification.", + color=self.bot.error_color, description=f"{mention} does not have a pending notification.", ) else: mentions.remove(mention) @@ -526,8 +516,7 @@ async def subscribe(self, ctx, *, user_or_role: Union[discord.Role, User, str.lo if mention in mentions: embed = discord.Embed( - color=self.bot.error_color, - description=f"{mention} is already subscribed to this thread.", + color=self.bot.error_color, description=f"{mention} is already subscribed to this thread.", ) else: mentions.append(mention) @@ -562,15 +551,13 @@ async def unsubscribe(self, ctx, *, user_or_role: Union[discord.Role, User, str. if mention not in mentions: embed = discord.Embed( - color=self.bot.error_color, - description=f"{mention} is not subscribed to this thread.", + color=self.bot.error_color, description=f"{mention} is not subscribed to this thread.", ) else: mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( - color=self.bot.main_color, - description=f"{mention} is now unsubscribed from this thread.", + color=self.bot.main_color, description=f"{mention} is now unsubscribed from this thread.", ) return await ctx.send(embed=embed) @@ -697,8 +684,7 @@ async def logs(self, ctx, *, user: User = None): if not any(not log["open"] for log in logs): embed = discord.Embed( - color=self.bot.error_color, - description="This user does not have any previous logs.", + color=self.bot.error_color, description="This user does not have any previous logs.", ) return await ctx.send(embed=embed) @@ -725,8 +711,7 @@ async def logs_closed_by(self, ctx, *, user: User = None): if not embeds: embed = discord.Embed( - color=self.bot.error_color, - description="No log entries have been found for that query.", + color=self.bot.error_color, description="No log entries have been found for that query.", ) return await ctx.send(embed=embed) @@ -745,9 +730,7 @@ async def logs_delete(self, ctx, key_or_link: str): if not success: embed = discord.Embed( - title="Error", - description=f"Log entry `{key}` not found.", - color=self.bot.error_color, + title="Error", description=f"Log entry `{key}` not found.", color=self.bot.error_color, ) else: embed = discord.Embed( @@ -800,8 +783,7 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): if not embeds: embed = discord.Embed( - color=self.bot.error_color, - description="No log entries have been found for that query.", + color=self.bot.error_color, description="No log entries have been found for that query.", ) return await ctx.send(embed=embed) @@ -1012,10 +994,7 @@ async def contact( else: thread = await self.bot.threads.create( - recipient=user, - creator=ctx.author, - category=category, - manual_trigger=manual_trigger, + recipient=user, creator=ctx.author, category=category, manual_trigger=manual_trigger, ) if thread.cancelled: return @@ -1029,11 +1008,7 @@ async def contact( else: description = f"{ctx.author.name} has opened a Modmail thread." - em = discord.Embed( - title="New Thread", - description=description, - color=self.bot.main_color, - ) + em = discord.Embed(title="New Thread", description=description, color=self.bot.main_color,) if self.bot.config["show_timestamp"]: em.timestamp = datetime.utcnow() em.set_footer(icon_url=ctx.author.avatar_url) @@ -1075,8 +1050,7 @@ async def blocked(self, ctx): end_time = re.search(r"%([^%]+?)%", reason) if end_time is not None: logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", - id_, + r"Deprecated time message for user %s, block and unblock again to update.", id_, ) if end_time is not None: @@ -1107,8 +1081,7 @@ async def blocked(self, ctx): end_time = re.search(r"%([^%]+?)%", reason) if end_time is not None: logger.warning( - r"Deprecated time message for role %s, block and unblock again to update.", - id_, + r"Deprecated time message for role %s, block and unblock again to update.", id_, ) if end_time is not None: @@ -1130,9 +1103,7 @@ async def blocked(self, ctx): line = mention + f" - {reason or 'No Reason Provided'}\n" if len(embed.description) + len(line) > 2048: embed = discord.Embed( - title="Blocked Users (Continued)", - color=self.bot.main_color, - description=line, + title="Blocked Users (Continued)", color=self.bot.main_color, description=line, ) embeds.append(embed) else: @@ -1149,9 +1120,7 @@ async def blocked(self, ctx): line = mention + f" - {reason or 'No Reason Provided'}\n" if len(embed.description) + len(line) > 2048: embed = discord.Embed( - title="Blocked Roles (Continued)", - color=self.bot.main_color, - description=line, + title="Blocked Roles (Continued)", color=self.bot.main_color, description=line, ) embeds.append(embed) else: @@ -1211,9 +1180,7 @@ async def blocked_whitelist(self, ctx, *, user: User = None): ) else: embed = discord.Embed( - title="Success", - color=self.bot.main_color, - description=f"{mention} is now whitelisted.", + title="Success", color=self.bot.main_color, description=f"{mention} is now whitelisted.", ) return await ctx.send(embed=embed) @@ -1291,9 +1258,7 @@ async def block( ) else: embed = discord.Embed( - title="Success", - color=self.bot.main_color, - description=f"{mention} is now blocked {reason}", + title="Success", color=self.bot.main_color, description=f"{mention} is now blocked {reason}", ) if isinstance(user_or_role, discord.Role): @@ -1356,9 +1321,7 @@ async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): await self.bot.config.update() embed = discord.Embed( - title="Success", - color=self.bot.main_color, - description=f"{mention} is no longer blocked.", + title="Success", color=self.bot.main_color, description=f"{mention} is no longer blocked.", ) else: embed = discord.Embed( @@ -1415,8 +1378,7 @@ async def repair(self, ctx): # Search cache for channel user_id, thread = next( - ((k, v) for k, v in self.bot.threads.cache.items() if v.channel == ctx.channel), - (-1, None), + ((k, v) for k, v in self.bot.threads.cache.items() if v.channel == ctx.channel), (-1, None), ) if thread is not None: logger.debug("Found thread with tempered ID.") diff --git a/cogs/plugins.py b/cogs/plugins.py index aab5dc8bd6..a9a4d247da 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -159,9 +159,7 @@ async def initial_load_plugins(self): except Exception: self.bot.config["plugins"].remove(plugin_name) logger.error( - "Error when loading plugin %s. Plugin removed from config.", - plugin, - exc_info=True, + "Error when loading plugin %s. Plugin removed from config.", plugin, exc_info=True, ) continue @@ -278,8 +276,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if not self._ready_event.is_set(): embed = discord.Embed( - description="Plugins are still loading, please try again later.", - color=self.bot.main_color, + description="Plugins are still loading, please try again later.", color=self.bot.main_color, ) await ctx.send(embed=embed) return @@ -349,20 +346,17 @@ async def plugins_add(self, ctx, *, plugin_name: str): if plugin.name in self.bot.cogs: # another class with the same name embed = discord.Embed( - description="Cannot install this plugin (dupe cog name).", - color=self.bot.error_color, + description="Cannot install this plugin (dupe cog name).", color=self.bot.error_color, ) return await ctx.send(embed=embed) if plugin.local: embed = discord.Embed( - description=f"Starting to load local plugin from {plugin.link}...", - color=self.bot.main_color, + description=f"Starting to load local plugin from {plugin.link}...", color=self.bot.main_color, ) else: embed = discord.Embed( - description=f"Starting to download plugin from {plugin.link}...", - color=self.bot.main_color, + description=f"Starting to download plugin from {plugin.link}...", color=self.bot.main_color, ) msg = await ctx.send(embed=embed) @@ -562,8 +556,7 @@ async def plugins_loaded(self, ctx): if not self._ready_event.is_set(): embed = discord.Embed( - description="Plugins are still loading, please try again later.", - color=self.bot.main_color, + description="Plugins are still loading, please try again later.", color=self.bot.main_color, ) return await ctx.send(embed=embed) diff --git a/cogs/utility.py b/cogs/utility.py index 759b573748..6f6ed89b47 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -305,9 +305,7 @@ async def about(self, ctx): """Shows information about this bot.""" embed = discord.Embed(color=self.bot.main_color, timestamp=datetime.utcnow()) embed.set_author( - name="Modmail - About", - icon_url=self.bot.user.avatar_url, - url="https://discord.gg/F34cRU8", + name="Modmail - About", icon_url=self.bot.user.avatar_url, url="https://discord.gg/F34cRU8", ) embed.set_thumbnail(url=self.bot.user.avatar_url) @@ -388,8 +386,7 @@ async def debug(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "r+", + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "r+", ) as f: logs = f.read().strip() @@ -441,8 +438,7 @@ async def debug_hastebin(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "rb+", + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "rb+", ) as f: logs = BytesIO(f.read().strip()) @@ -455,9 +451,7 @@ async def debug_hastebin(self, ctx): logger.error(data["message"]) raise embed = discord.Embed( - title="Debug Logs", - color=self.bot.main_color, - description=f"{haste_url}/" + key, + title="Debug Logs", color=self.bot.main_color, description=f"{haste_url}/" + key, ) except (JSONDecodeError, ClientResponseError, IndexError, KeyError): embed = discord.Embed( @@ -477,8 +471,7 @@ async def debug_clear(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "w", + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "w", ): pass await ctx.send( @@ -693,14 +686,12 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, option = user_or_role[0].lower() if option == "disable": embed = discord.Embed( - description=f"Disabled mention on thread creation.", - color=self.bot.main_color, + description=f"Disabled mention on thread creation.", color=self.bot.main_color, ) self.bot.config["mention"] = None else: embed = discord.Embed( - description="`mention` is reset to default.", - color=self.bot.main_color, + description="`mention` is reset to default.", color=self.bot.main_color, ) self.bot.config.remove("mention") await self.bot.config.update() @@ -775,9 +766,7 @@ async def config_options(self, ctx): for names in zip_longest(*(iter(sorted(self.bot.config.public_keys)),) * 15): description = "\n".join(f"`{name}`" for name in takewhile(lambda x: x is not None, names)) embed = discord.Embed( - title="Available configuration keys:", - color=self.bot.main_color, - description=description, + title="Available configuration keys:", color=self.bot.main_color, description=description, ) embeds.append(embed) @@ -820,9 +809,7 @@ async def config_remove(self, ctx, *, key: str.lower): self.bot.config.remove(key) await self.bot.config.update() embed = discord.Embed( - title="Success", - color=self.bot.main_color, - description=f"`{key}` had been reset to default.", + title="Success", color=self.bot.main_color, description=f"`{key}` had been reset to default.", ) else: embed = discord.Embed( @@ -851,9 +838,7 @@ async def config_get(self, ctx, *, key: str.lower = None): else: embed = discord.Embed( - title="Error", - color=self.bot.error_color, - description=f"`{key}` is an invalid key.", + title="Error", color=self.bot.error_color, description=f"`{key}` is an invalid key.", ) embed.set_footer( text=f'Type "{self.bot.prefix}config options" for a list of config variables.' @@ -886,9 +871,7 @@ async def config_help(self, ctx, key: str.lower = None): key, {**self.bot.config.public_keys, **self.bot.config.protected_keys} ) embed = discord.Embed( - title="Error", - color=self.bot.error_color, - description=f"`{key}` is an invalid key.", + title="Error", color=self.bot.error_color, description=f"`{key}` is an invalid key.", ) if closest: embed.add_field(name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) @@ -898,9 +881,7 @@ async def config_help(self, ctx, key: str.lower = None): if key is not None and key not in config_help: embed = discord.Embed( - title="Error", - color=self.bot.error_color, - description=f"No help details found for `{key}`.", + title="Error", color=self.bot.error_color, description=f"No help details found for `{key}`.", ) return await ctx.send(embed=embed) @@ -992,9 +973,7 @@ async def alias(self, ctx, *, name: str.lower = None): embeds = [] for i, val in enumerate(values, start=1): embed = discord.Embed( - color=self.bot.main_color, - title=f'Alias - "{name}" - Step {i}:', - description=val, + color=self.bot.main_color, title=f'Alias - "{name}" - Step {i}:', description=val, ) embeds += [embed] session = EmbedPaginatorSession(ctx, *embeds) @@ -1269,9 +1248,7 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name ) else: logger.info( - "Updated command permission level for `%s` to `%s`.", - command.qualified_name, - level.name, + "Updated command permission level for `%s` to `%s`.", command.qualified_name, level.name, ) self.bot.config["override_command_level"][command.qualified_name] = level.name @@ -1287,12 +1264,7 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name @permissions.command(name="add", usage="[command/level] [name] [user/role]") @checks.has_permissions(PermissionLevel.OWNER) async def permissions_add( - self, - ctx, - type_: str.lower, - name: str, - *, - user_or_role: Union[discord.Role, utils.User, str], + self, ctx, type_: str.lower, name: str, *, user_or_role: Union[discord.Role, utils.User, str], ): """ Add a permission to a command or a permission level. @@ -1361,12 +1333,7 @@ async def permissions_add( ) @checks.has_permissions(PermissionLevel.OWNER) async def permissions_remove( - self, - ctx, - type_: str.lower, - name: str, - *, - user_or_role: Union[discord.Role, utils.User, str] = None, + self, ctx, type_: str.lower, name: str, *, user_or_role: Union[discord.Role, utils.User, str] = None, ): """ Remove permission to use a command, permission level, or command level override. @@ -1860,11 +1827,7 @@ async def autotrigger_list(self, ctx): embeds = [] for keyword in self.bot.auto_triggers: command = self.bot.auto_triggers[keyword] - embed = discord.Embed( - title=keyword, - color=self.bot.main_color, - description=command, - ) + embed = discord.Embed(title=keyword, color=self.bot.main_color, description=command,) embeds.append(embed) if not embeds: @@ -1965,11 +1928,7 @@ async def update(self, ctx, *, flag: str = ""): command = "git pull" - proc = await asyncio.create_subprocess_shell( - command, - stderr=PIPE, - stdout=PIPE, - ) + proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() @@ -1982,10 +1941,7 @@ async def update(self, ctx, *, flag: str = ""): elif res != "Already up to date.": logger.info("Bot has been updated.") - embed = discord.Embed( - title="Bot has been updated", - color=self.bot.main_color, - ) + embed = discord.Embed(title="Bot has been updated", color=self.bot.main_color,) embed.set_footer(text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}") embed.description = latest.description for name, value in latest.fields.items(): @@ -2000,9 +1956,7 @@ async def update(self, ctx, *, flag: str = ""): return await self.bot.close() else: embed = discord.Embed( - title="Already up to date", - description=desc, - color=self.bot.main_color, + title="Already up to date", description=desc, color=self.bot.main_color, ) embed.set_footer(text="Force update") await ctx.send(embed=embed) diff --git a/core/changelog.py b/core/changelog.py index 7c9af2e1bb..5c23020eb6 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -89,9 +89,7 @@ def embed(self) -> Embed: """ embed = Embed(color=self.bot.main_color, description=self.description) embed.set_author( - name=f"v{self.version} - Changelog", - icon_url=self.bot.user.avatar_url, - url=self.url, + name=f"v{self.version} - Changelog", icon_url=self.bot.user.avatar_url, url=self.url, ) for name, value in self.fields.items(): @@ -170,11 +168,7 @@ async def from_url(cls, bot, url: str = "") -> "Changelog": The newly created `Changelog` parsed from the `url`. """ # get branch via git cli if available - proc = await asyncio.create_subprocess_shell( - "git branch --show-current", - stderr=PIPE, - stdout=PIPE, - ) + proc = await asyncio.create_subprocess_shell("git branch --show-current", stderr=PIPE, stdout=PIPE,) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() diff --git a/core/checks.py b/core/checks.py index 1079b55530..74b7dc38cd 100644 --- a/core/checks.py +++ b/core/checks.py @@ -5,9 +5,7 @@ logger = getLogger(__name__) -def has_permissions_predicate( - permission_level: PermissionLevel = PermissionLevel.REGULAR, -): +def has_permissions_predicate(permission_level: PermissionLevel = PermissionLevel.REGULAR,): async def predicate(ctx): return await check_permissions(ctx, ctx.command.qualified_name) diff --git a/core/clients.py b/core/clients.py index 5c5acc8fad..61fcfdb487 100644 --- a/core/clients.py +++ b/core/clients.py @@ -321,12 +321,7 @@ async def edit_message(self, message_id: Union[int, str], new_content: str) -> N return NotImplemented async def append_log( - self, - message: Message, - *, - message_id: str = "", - channel_id: str = "", - type_: str = "thread_message", + self, message: Message, *, message_id: str = "", channel_id: str = "", type_: str = "thread_message", ) -> dict: return NotImplemented @@ -548,12 +543,7 @@ async def edit_message(self, message_id: Union[int, str], new_content: str) -> N ) async def append_log( - self, - message: Message, - *, - message_id: str = "", - channel_id: str = "", - type_: str = "thread_message", + self, message: Message, *, message_id: str = "", channel_id: str = "", type_: str = "thread_message", ) -> dict: channel_id = str(channel_id) or str(message.channel.id) message_id = str(message_id) or str(message.id) @@ -599,11 +589,7 @@ async def search_closed_by(self, user_id: Union[int, str]): async def search_by_text(self, text: str, limit: Optional[int]): return await self.bot.db.logs.find( - { - "guild_id": str(self.bot.guild_id), - "open": False, - "$text": {"$search": f'"{text}"'}, - }, + {"guild_id": str(self.bot.guild_id), "open": False, "$text": {"$search": f'"{text}"'},}, {"messages": {"$slice": 5}}, ).to_list(limit) @@ -644,11 +630,7 @@ async def update_repository(self) -> dict: data = await user.update_repository() return { "data": data, - "user": { - "username": user.username, - "avatar_url": user.avatar_url, - "url": user.url, - }, + "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,}, } async def get_user_info(self) -> dict: @@ -657,13 +639,7 @@ async def get_user_info(self) -> dict: except InvalidConfigError: return None else: - return { - "user": { - "username": user.username, - "avatar_url": user.avatar_url, - "url": user.url, - } - } + return {"user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,}} class PluginDatabaseClient: diff --git a/core/models.py b/core/models.py index 76889809f7..19c8ccf1fc 100644 --- a/core/models.py +++ b/core/models.py @@ -87,9 +87,7 @@ def line(self, level="info"): level = logging.INFO if self.isEnabledFor(level): self._log( - level, - Fore.BLACK + Style.BRIGHT + "-------------------------" + Style.RESET_ALL, - [], + level, Fore.BLACK + Style.BRIGHT + "-------------------------" + Style.RESET_ALL, [], ) @@ -130,8 +128,7 @@ def configure_logging(name, level=None): ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=78000, backupCount=10) formatter_debug = FileFormatter( - "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", - datefmt="%Y-%m-%d %H:%M:%S", + "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) ch_debug.setFormatter(formatter_debug) ch_debug.setLevel(logging.DEBUG) diff --git a/core/thread.py b/core/thread.py index 41d2cd96ba..7c49ee7425 100644 --- a/core/thread.py +++ b/core/thread.py @@ -181,9 +181,7 @@ async def send_recipient_genesis_message(): thread_creation_response = self.bot.config["thread_creation_response"] embed = discord.Embed( - color=self.bot.mod_color, - description=thread_creation_response, - timestamp=channel.created_at, + color=self.bot.mod_color, description=thread_creation_response, timestamp=channel.created_at, ) recipient_thread_close = self.bot.config.get("recipient_thread_close") @@ -460,10 +458,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, # Thread closed message - embed = discord.Embed( - title=self.bot.config["thread_close_title"], - color=self.bot.error_color, - ) + embed = discord.Embed(title=self.bot.config["thread_close_title"], color=self.bot.error_color,) if self.bot.config["show_timestamp"]: embed.timestamp = datetime.utcnow() @@ -695,11 +690,7 @@ async def note(self, message: discord.Message, persistent=False, thread_creation raise MissingRequiredArgument(SimpleNamespace(name="msg")) msg = await self.send( - message, - self.channel, - note=True, - persistent_note=persistent, - thread_creation=thread_creation, + message, self.channel, note=True, persistent_note=persistent, thread_creation=thread_creation, ) self.bot.loop.create_task( @@ -724,11 +715,7 @@ async def reply(self, message: discord.Message, anonymous: bool = False, plain: try: user_msg = await self.send( - message, - destination=self.recipient, - from_mod=True, - anonymous=anonymous, - plain=plain, + message, destination=self.recipient, from_mod=True, anonymous=anonymous, plain=plain, ) except Exception as e: logger.error("Message delivery failed:", exc_info=True) @@ -747,10 +734,7 @@ async def reply(self, message: discord.Message, anonymous: bool = False, plain: ) tasks.append( message.channel.send( - embed=discord.Embed( - color=self.bot.error_color, - description=description, - ) + embed=discord.Embed(color=self.bot.error_color, description=description,) ) ) else: @@ -774,8 +758,7 @@ async def reply(self, message: discord.Message, anonymous: bool = False, plain: tasks.append( self.channel.send( embed=discord.Embed( - color=self.bot.error_color, - description="Scheduled close has been cancelled.", + color=self.bot.error_color, description="Scheduled close has been cancelled.", ) ) ) @@ -806,8 +789,7 @@ async def send( self.bot.loop.create_task( self.channel.send( embed=discord.Embed( - color=self.bot.error_color, - description="Scheduled close has been cancelled.", + color=self.bot.error_color, description="Scheduled close has been cancelled.", ) ) ) From 8db612b1b983e895860835233af1b46fbca8aea2 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 22 Jul 2021 17:08:17 +0800 Subject: [PATCH 383/705] formatting --- Pipfile | 2 +- bot.py | 49 +++++++++++++++++++++------ cogs/modmail.py | 84 ++++++++++++++++++++++++++++++++------------- cogs/plugins.py | 19 +++++++---- cogs/utility.py | 86 ++++++++++++++++++++++++++++++++++++----------- core/changelog.py | 10 ++++-- core/checks.py | 4 ++- core/clients.py | 34 ++++++++++++++++--- core/models.py | 7 ++-- core/thread.py | 32 ++++++++++++++---- 10 files changed, 249 insertions(+), 78 deletions(-) diff --git a/Pipfile b/Pipfile index 9c7b4e03b7..4ed01f5b70 100644 --- a/Pipfile +++ b/Pipfile @@ -17,7 +17,7 @@ isodate = "~=0.6.0" motor = "~=2.4.0" natural = "~=0.2.0" parsedatetime = "~=2.6" -pymongo = {version = "*", extras = ['srv']} # Required by motor +pymongo = {extras = ["srv"], version = "*"} # Required by motor python-dateutil = "~=2.8.1" python-dotenv = "~=0.18.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} diff --git a/bot.py b/bot.py index 131032ec80..1deb9b7d2a 100644 --- a/bot.py +++ b/bot.py @@ -506,7 +506,8 @@ def command_perm(self, command_name: str) -> PermissionLevel: logger.debug("Command %s not found.", command_name) return PermissionLevel.INVALID level = next( - (check.permission_level for check in command.checks if hasattr(check, "permission_level")), None, + (check.permission_level for check in command.checks if hasattr(check, "permission_level")), + None, ) if level is None: logger.debug("Command %s does not have a permission level.", command_name) @@ -609,7 +610,13 @@ async def on_ready(self): if self.config.get("data_collection"): self.metadata_loop = tasks.Loop( - self.post_metadata, seconds=0, minutes=0, hours=1, count=None, reconnect=True, loop=None, + self.post_metadata, + seconds=0, + minutes=0, + hours=1, + count=None, + reconnect=True, + loop=None, ) self.metadata_loop.before_loop(self.before_post_metadata) self.metadata_loop.start() @@ -762,7 +769,8 @@ def check_manual_blocked(self, author: discord.Member) -> bool: end_time = re.search(r"%([^%]+?)%", blocked_reason) if end_time is not None: logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", author.name, + r"Deprecated time message for user %s, block and unblock again to update.", + author.name, ) if end_time is not None: @@ -783,7 +791,11 @@ async def _process_blocked(self, message): return False async def is_blocked( - self, author: discord.User, *, channel: discord.TextChannel = None, send_message: bool = False, + self, + author: discord.User, + *, + channel: discord.TextChannel = None, + send_message: bool = False, ) -> typing.Tuple[bool, str]: member = self.guild.get_member(author.id) @@ -814,7 +826,9 @@ async def is_blocked( if send_message: await channel.send( embed=discord.Embed( - title="Message not sent!", description=new_reason, color=self.error_color, + title="Message not sent!", + description=new_reason, + color=self.error_color, ) ) return True @@ -913,7 +927,8 @@ async def process_dm_modmail(self, message: discord.Message) -> None: description=self.config["disabled_current_thread_response"], ) embed.set_footer( - text=self.config["disabled_current_thread_footer"], icon_url=self.guild.icon_url, + text=self.config["disabled_current_thread_footer"], + icon_url=self.guild.icon_url, ) logger.info("A message was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -1274,14 +1289,18 @@ async def on_raw_reaction_add(self, payload): await message.remove_reaction(payload.emoji, member) await message.add_reaction(emoji_fmt) # bot adds as well - if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS,): + if self.config["dm_disabled"] in ( + DMDisabled.NEW_THREADS, + DMDisabled.ALL_THREADS, + ): embed = discord.Embed( title=self.config["disabled_new_thread_title"], color=self.error_color, description=self.config["disabled_new_thread_response"], ) embed.set_footer( - text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon_url, + text=self.config["disabled_new_thread_footer"], + icon_url=self.guild.icon_url, ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", @@ -1340,7 +1359,9 @@ async def on_member_remove(self, member): if thread: if self.config["close_on_leave"]: await thread.close( - closer=member.guild.me, message=self.config["close_on_leave_reason"], silent=True, + closer=member.guild.me, + message=self.config["close_on_leave_reason"], + silent=True, ) else: embed = discord.Embed( @@ -1523,7 +1544,9 @@ async def autoupdate(self): commit_data = data["data"] user = data["user"] embed.set_author( - name=user["username"] + " - Updating Bot", icon_url=user["avatar_url"], url=user["url"], + name=user["username"] + " - Updating Bot", + icon_url=user["avatar_url"], + url=user["url"], ) embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") @@ -1552,7 +1575,11 @@ async def autoupdate(self): pass command = "git pull" - proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + proc = await asyncio.create_subprocess_shell( + command, + stderr=PIPE, + stdout=PIPE, + ) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() diff --git a/cogs/modmail.py b/cogs/modmail.py index 0db8a85e2e..0e41b76677 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -50,7 +50,9 @@ async def setup(self, ctx): if self.bot.modmail_guild is None: embed = discord.Embed( - title="Error", description="Modmail functioning guild not found.", color=self.bot.error_color, + title="Error", + description="Modmail functioning guild not found.", + color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -182,7 +184,9 @@ async def snippet_raw(self, ctx, *, name: str.lower): else: val = truncate(escape_code_block(val), 2048 - 7) embed = discord.Embed( - title=f'Raw snippet - "{name}":', description=f"```\n{val}```", color=self.bot.main_color, + title=f'Raw snippet - "{name}":', + description=f"```\n{val}```", + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -204,7 +208,9 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte """ if name in self.bot.snippets: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"Snippet `{name}` already exists.", + title="Error", + color=self.bot.error_color, + description=f"Snippet `{name}` already exists.", ) return await ctx.send(embed=embed) @@ -228,7 +234,9 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte await self.bot.config.update() embed = discord.Embed( - title="Added snippet", color=self.bot.main_color, description="Successfully created snippet.", + title="Added snippet", + color=self.bot.main_color, + description="Successfully created snippet.", ) return await ctx.send(embed=embed) @@ -445,7 +453,8 @@ async def notify(self, ctx, *, user_or_role: Union[discord.Role, User, str.lower if mention in mentions: embed = discord.Embed( - color=self.bot.error_color, description=f"{mention} is already going to be mentioned.", + color=self.bot.error_color, + description=f"{mention} is already going to be mentioned.", ) else: mentions.append(mention) @@ -480,7 +489,8 @@ async def unnotify(self, ctx, *, user_or_role: Union[discord.Role, User, str.low if mention not in mentions: embed = discord.Embed( - color=self.bot.error_color, description=f"{mention} does not have a pending notification.", + color=self.bot.error_color, + description=f"{mention} does not have a pending notification.", ) else: mentions.remove(mention) @@ -516,7 +526,8 @@ async def subscribe(self, ctx, *, user_or_role: Union[discord.Role, User, str.lo if mention in mentions: embed = discord.Embed( - color=self.bot.error_color, description=f"{mention} is already subscribed to this thread.", + color=self.bot.error_color, + description=f"{mention} is already subscribed to this thread.", ) else: mentions.append(mention) @@ -551,13 +562,15 @@ async def unsubscribe(self, ctx, *, user_or_role: Union[discord.Role, User, str. if mention not in mentions: embed = discord.Embed( - color=self.bot.error_color, description=f"{mention} is not subscribed to this thread.", + color=self.bot.error_color, + description=f"{mention} is not subscribed to this thread.", ) else: mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( - color=self.bot.main_color, description=f"{mention} is now unsubscribed from this thread.", + color=self.bot.main_color, + description=f"{mention} is now unsubscribed from this thread.", ) return await ctx.send(embed=embed) @@ -684,7 +697,8 @@ async def logs(self, ctx, *, user: User = None): if not any(not log["open"] for log in logs): embed = discord.Embed( - color=self.bot.error_color, description="This user does not have any previous logs.", + color=self.bot.error_color, + description="This user does not have any previous logs.", ) return await ctx.send(embed=embed) @@ -711,7 +725,8 @@ async def logs_closed_by(self, ctx, *, user: User = None): if not embeds: embed = discord.Embed( - color=self.bot.error_color, description="No log entries have been found for that query.", + color=self.bot.error_color, + description="No log entries have been found for that query.", ) return await ctx.send(embed=embed) @@ -730,7 +745,9 @@ async def logs_delete(self, ctx, key_or_link: str): if not success: embed = discord.Embed( - title="Error", description=f"Log entry `{key}` not found.", color=self.bot.error_color, + title="Error", + description=f"Log entry `{key}` not found.", + color=self.bot.error_color, ) else: embed = discord.Embed( @@ -783,7 +800,8 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): if not embeds: embed = discord.Embed( - color=self.bot.error_color, description="No log entries have been found for that query.", + color=self.bot.error_color, + description="No log entries have been found for that query.", ) return await ctx.send(embed=embed) @@ -994,7 +1012,10 @@ async def contact( else: thread = await self.bot.threads.create( - recipient=user, creator=ctx.author, category=category, manual_trigger=manual_trigger, + recipient=user, + creator=ctx.author, + category=category, + manual_trigger=manual_trigger, ) if thread.cancelled: return @@ -1008,7 +1029,11 @@ async def contact( else: description = f"{ctx.author.name} has opened a Modmail thread." - em = discord.Embed(title="New Thread", description=description, color=self.bot.main_color,) + em = discord.Embed( + title="New Thread", + description=description, + color=self.bot.main_color, + ) if self.bot.config["show_timestamp"]: em.timestamp = datetime.utcnow() em.set_footer(icon_url=ctx.author.avatar_url) @@ -1050,7 +1075,8 @@ async def blocked(self, ctx): end_time = re.search(r"%([^%]+?)%", reason) if end_time is not None: logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", id_, + r"Deprecated time message for user %s, block and unblock again to update.", + id_, ) if end_time is not None: @@ -1081,7 +1107,8 @@ async def blocked(self, ctx): end_time = re.search(r"%([^%]+?)%", reason) if end_time is not None: logger.warning( - r"Deprecated time message for role %s, block and unblock again to update.", id_, + r"Deprecated time message for role %s, block and unblock again to update.", + id_, ) if end_time is not None: @@ -1103,7 +1130,9 @@ async def blocked(self, ctx): line = mention + f" - {reason or 'No Reason Provided'}\n" if len(embed.description) + len(line) > 2048: embed = discord.Embed( - title="Blocked Users (Continued)", color=self.bot.main_color, description=line, + title="Blocked Users (Continued)", + color=self.bot.main_color, + description=line, ) embeds.append(embed) else: @@ -1120,7 +1149,9 @@ async def blocked(self, ctx): line = mention + f" - {reason or 'No Reason Provided'}\n" if len(embed.description) + len(line) > 2048: embed = discord.Embed( - title="Blocked Roles (Continued)", color=self.bot.main_color, description=line, + title="Blocked Roles (Continued)", + color=self.bot.main_color, + description=line, ) embeds.append(embed) else: @@ -1180,7 +1211,9 @@ async def blocked_whitelist(self, ctx, *, user: User = None): ) else: embed = discord.Embed( - title="Success", color=self.bot.main_color, description=f"{mention} is now whitelisted.", + title="Success", + color=self.bot.main_color, + description=f"{mention} is now whitelisted.", ) return await ctx.send(embed=embed) @@ -1258,7 +1291,9 @@ async def block( ) else: embed = discord.Embed( - title="Success", color=self.bot.main_color, description=f"{mention} is now blocked {reason}", + title="Success", + color=self.bot.main_color, + description=f"{mention} is now blocked {reason}", ) if isinstance(user_or_role, discord.Role): @@ -1321,7 +1356,9 @@ async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): await self.bot.config.update() embed = discord.Embed( - title="Success", color=self.bot.main_color, description=f"{mention} is no longer blocked.", + title="Success", + color=self.bot.main_color, + description=f"{mention} is no longer blocked.", ) else: embed = discord.Embed( @@ -1378,7 +1415,8 @@ async def repair(self, ctx): # Search cache for channel user_id, thread = next( - ((k, v) for k, v in self.bot.threads.cache.items() if v.channel == ctx.channel), (-1, None), + ((k, v) for k, v in self.bot.threads.cache.items() if v.channel == ctx.channel), + (-1, None), ) if thread is not None: logger.debug("Found thread with tempered ID.") diff --git a/cogs/plugins.py b/cogs/plugins.py index a9a4d247da..aab5dc8bd6 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -159,7 +159,9 @@ async def initial_load_plugins(self): except Exception: self.bot.config["plugins"].remove(plugin_name) logger.error( - "Error when loading plugin %s. Plugin removed from config.", plugin, exc_info=True, + "Error when loading plugin %s. Plugin removed from config.", + plugin, + exc_info=True, ) continue @@ -276,7 +278,8 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if not self._ready_event.is_set(): embed = discord.Embed( - description="Plugins are still loading, please try again later.", color=self.bot.main_color, + description="Plugins are still loading, please try again later.", + color=self.bot.main_color, ) await ctx.send(embed=embed) return @@ -346,17 +349,20 @@ async def plugins_add(self, ctx, *, plugin_name: str): if plugin.name in self.bot.cogs: # another class with the same name embed = discord.Embed( - description="Cannot install this plugin (dupe cog name).", color=self.bot.error_color, + description="Cannot install this plugin (dupe cog name).", + color=self.bot.error_color, ) return await ctx.send(embed=embed) if plugin.local: embed = discord.Embed( - description=f"Starting to load local plugin from {plugin.link}...", color=self.bot.main_color, + description=f"Starting to load local plugin from {plugin.link}...", + color=self.bot.main_color, ) else: embed = discord.Embed( - description=f"Starting to download plugin from {plugin.link}...", color=self.bot.main_color, + description=f"Starting to download plugin from {plugin.link}...", + color=self.bot.main_color, ) msg = await ctx.send(embed=embed) @@ -556,7 +562,8 @@ async def plugins_loaded(self, ctx): if not self._ready_event.is_set(): embed = discord.Embed( - description="Plugins are still loading, please try again later.", color=self.bot.main_color, + description="Plugins are still loading, please try again later.", + color=self.bot.main_color, ) return await ctx.send(embed=embed) diff --git a/cogs/utility.py b/cogs/utility.py index 6f6ed89b47..759b573748 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -305,7 +305,9 @@ async def about(self, ctx): """Shows information about this bot.""" embed = discord.Embed(color=self.bot.main_color, timestamp=datetime.utcnow()) embed.set_author( - name="Modmail - About", icon_url=self.bot.user.avatar_url, url="https://discord.gg/F34cRU8", + name="Modmail - About", + icon_url=self.bot.user.avatar_url, + url="https://discord.gg/F34cRU8", ) embed.set_thumbnail(url=self.bot.user.avatar_url) @@ -386,7 +388,8 @@ async def debug(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "r+", + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), + "r+", ) as f: logs = f.read().strip() @@ -438,7 +441,8 @@ async def debug_hastebin(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "rb+", + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), + "rb+", ) as f: logs = BytesIO(f.read().strip()) @@ -451,7 +455,9 @@ async def debug_hastebin(self, ctx): logger.error(data["message"]) raise embed = discord.Embed( - title="Debug Logs", color=self.bot.main_color, description=f"{haste_url}/" + key, + title="Debug Logs", + color=self.bot.main_color, + description=f"{haste_url}/" + key, ) except (JSONDecodeError, ClientResponseError, IndexError, KeyError): embed = discord.Embed( @@ -471,7 +477,8 @@ async def debug_clear(self, ctx): log_file_name = self.bot.token.split(".")[0] with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "w", + os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), + "w", ): pass await ctx.send( @@ -686,12 +693,14 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, option = user_or_role[0].lower() if option == "disable": embed = discord.Embed( - description=f"Disabled mention on thread creation.", color=self.bot.main_color, + description=f"Disabled mention on thread creation.", + color=self.bot.main_color, ) self.bot.config["mention"] = None else: embed = discord.Embed( - description="`mention` is reset to default.", color=self.bot.main_color, + description="`mention` is reset to default.", + color=self.bot.main_color, ) self.bot.config.remove("mention") await self.bot.config.update() @@ -766,7 +775,9 @@ async def config_options(self, ctx): for names in zip_longest(*(iter(sorted(self.bot.config.public_keys)),) * 15): description = "\n".join(f"`{name}`" for name in takewhile(lambda x: x is not None, names)) embed = discord.Embed( - title="Available configuration keys:", color=self.bot.main_color, description=description, + title="Available configuration keys:", + color=self.bot.main_color, + description=description, ) embeds.append(embed) @@ -809,7 +820,9 @@ async def config_remove(self, ctx, *, key: str.lower): self.bot.config.remove(key) await self.bot.config.update() embed = discord.Embed( - title="Success", color=self.bot.main_color, description=f"`{key}` had been reset to default.", + title="Success", + color=self.bot.main_color, + description=f"`{key}` had been reset to default.", ) else: embed = discord.Embed( @@ -838,7 +851,9 @@ async def config_get(self, ctx, *, key: str.lower = None): else: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"`{key}` is an invalid key.", + title="Error", + color=self.bot.error_color, + description=f"`{key}` is an invalid key.", ) embed.set_footer( text=f'Type "{self.bot.prefix}config options" for a list of config variables.' @@ -871,7 +886,9 @@ async def config_help(self, ctx, key: str.lower = None): key, {**self.bot.config.public_keys, **self.bot.config.protected_keys} ) embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"`{key}` is an invalid key.", + title="Error", + color=self.bot.error_color, + description=f"`{key}` is an invalid key.", ) if closest: embed.add_field(name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) @@ -881,7 +898,9 @@ async def config_help(self, ctx, key: str.lower = None): if key is not None and key not in config_help: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"No help details found for `{key}`.", + title="Error", + color=self.bot.error_color, + description=f"No help details found for `{key}`.", ) return await ctx.send(embed=embed) @@ -973,7 +992,9 @@ async def alias(self, ctx, *, name: str.lower = None): embeds = [] for i, val in enumerate(values, start=1): embed = discord.Embed( - color=self.bot.main_color, title=f'Alias - "{name}" - Step {i}:', description=val, + color=self.bot.main_color, + title=f'Alias - "{name}" - Step {i}:', + description=val, ) embeds += [embed] session = EmbedPaginatorSession(ctx, *embeds) @@ -1248,7 +1269,9 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name ) else: logger.info( - "Updated command permission level for `%s` to `%s`.", command.qualified_name, level.name, + "Updated command permission level for `%s` to `%s`.", + command.qualified_name, + level.name, ) self.bot.config["override_command_level"][command.qualified_name] = level.name @@ -1264,7 +1287,12 @@ async def permissions_override(self, ctx, command_name: str.lower, *, level_name @permissions.command(name="add", usage="[command/level] [name] [user/role]") @checks.has_permissions(PermissionLevel.OWNER) async def permissions_add( - self, ctx, type_: str.lower, name: str, *, user_or_role: Union[discord.Role, utils.User, str], + self, + ctx, + type_: str.lower, + name: str, + *, + user_or_role: Union[discord.Role, utils.User, str], ): """ Add a permission to a command or a permission level. @@ -1333,7 +1361,12 @@ async def permissions_add( ) @checks.has_permissions(PermissionLevel.OWNER) async def permissions_remove( - self, ctx, type_: str.lower, name: str, *, user_or_role: Union[discord.Role, utils.User, str] = None, + self, + ctx, + type_: str.lower, + name: str, + *, + user_or_role: Union[discord.Role, utils.User, str] = None, ): """ Remove permission to use a command, permission level, or command level override. @@ -1827,7 +1860,11 @@ async def autotrigger_list(self, ctx): embeds = [] for keyword in self.bot.auto_triggers: command = self.bot.auto_triggers[keyword] - embed = discord.Embed(title=keyword, color=self.bot.main_color, description=command,) + embed = discord.Embed( + title=keyword, + color=self.bot.main_color, + description=command, + ) embeds.append(embed) if not embeds: @@ -1928,7 +1965,11 @@ async def update(self, ctx, *, flag: str = ""): command = "git pull" - proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + proc = await asyncio.create_subprocess_shell( + command, + stderr=PIPE, + stdout=PIPE, + ) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() @@ -1941,7 +1982,10 @@ async def update(self, ctx, *, flag: str = ""): elif res != "Already up to date.": logger.info("Bot has been updated.") - embed = discord.Embed(title="Bot has been updated", color=self.bot.main_color,) + embed = discord.Embed( + title="Bot has been updated", + color=self.bot.main_color, + ) embed.set_footer(text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}") embed.description = latest.description for name, value in latest.fields.items(): @@ -1956,7 +2000,9 @@ async def update(self, ctx, *, flag: str = ""): return await self.bot.close() else: embed = discord.Embed( - title="Already up to date", description=desc, color=self.bot.main_color, + title="Already up to date", + description=desc, + color=self.bot.main_color, ) embed.set_footer(text="Force update") await ctx.send(embed=embed) diff --git a/core/changelog.py b/core/changelog.py index 5c23020eb6..7c9af2e1bb 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -89,7 +89,9 @@ def embed(self) -> Embed: """ embed = Embed(color=self.bot.main_color, description=self.description) embed.set_author( - name=f"v{self.version} - Changelog", icon_url=self.bot.user.avatar_url, url=self.url, + name=f"v{self.version} - Changelog", + icon_url=self.bot.user.avatar_url, + url=self.url, ) for name, value in self.fields.items(): @@ -168,7 +170,11 @@ async def from_url(cls, bot, url: str = "") -> "Changelog": The newly created `Changelog` parsed from the `url`. """ # get branch via git cli if available - proc = await asyncio.create_subprocess_shell("git branch --show-current", stderr=PIPE, stdout=PIPE,) + proc = await asyncio.create_subprocess_shell( + "git branch --show-current", + stderr=PIPE, + stdout=PIPE, + ) err = await proc.stderr.read() err = err.decode("utf-8").rstrip() res = await proc.stdout.read() diff --git a/core/checks.py b/core/checks.py index 74b7dc38cd..1079b55530 100644 --- a/core/checks.py +++ b/core/checks.py @@ -5,7 +5,9 @@ logger = getLogger(__name__) -def has_permissions_predicate(permission_level: PermissionLevel = PermissionLevel.REGULAR,): +def has_permissions_predicate( + permission_level: PermissionLevel = PermissionLevel.REGULAR, +): async def predicate(ctx): return await check_permissions(ctx, ctx.command.qualified_name) diff --git a/core/clients.py b/core/clients.py index 61fcfdb487..5c5acc8fad 100644 --- a/core/clients.py +++ b/core/clients.py @@ -321,7 +321,12 @@ async def edit_message(self, message_id: Union[int, str], new_content: str) -> N return NotImplemented async def append_log( - self, message: Message, *, message_id: str = "", channel_id: str = "", type_: str = "thread_message", + self, + message: Message, + *, + message_id: str = "", + channel_id: str = "", + type_: str = "thread_message", ) -> dict: return NotImplemented @@ -543,7 +548,12 @@ async def edit_message(self, message_id: Union[int, str], new_content: str) -> N ) async def append_log( - self, message: Message, *, message_id: str = "", channel_id: str = "", type_: str = "thread_message", + self, + message: Message, + *, + message_id: str = "", + channel_id: str = "", + type_: str = "thread_message", ) -> dict: channel_id = str(channel_id) or str(message.channel.id) message_id = str(message_id) or str(message.id) @@ -589,7 +599,11 @@ async def search_closed_by(self, user_id: Union[int, str]): async def search_by_text(self, text: str, limit: Optional[int]): return await self.bot.db.logs.find( - {"guild_id": str(self.bot.guild_id), "open": False, "$text": {"$search": f'"{text}"'},}, + { + "guild_id": str(self.bot.guild_id), + "open": False, + "$text": {"$search": f'"{text}"'}, + }, {"messages": {"$slice": 5}}, ).to_list(limit) @@ -630,7 +644,11 @@ async def update_repository(self) -> dict: data = await user.update_repository() return { "data": data, - "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,}, + "user": { + "username": user.username, + "avatar_url": user.avatar_url, + "url": user.url, + }, } async def get_user_info(self) -> dict: @@ -639,7 +657,13 @@ async def get_user_info(self) -> dict: except InvalidConfigError: return None else: - return {"user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,}} + return { + "user": { + "username": user.username, + "avatar_url": user.avatar_url, + "url": user.url, + } + } class PluginDatabaseClient: diff --git a/core/models.py b/core/models.py index 19c8ccf1fc..76889809f7 100644 --- a/core/models.py +++ b/core/models.py @@ -87,7 +87,9 @@ def line(self, level="info"): level = logging.INFO if self.isEnabledFor(level): self._log( - level, Fore.BLACK + Style.BRIGHT + "-------------------------" + Style.RESET_ALL, [], + level, + Fore.BLACK + Style.BRIGHT + "-------------------------" + Style.RESET_ALL, + [], ) @@ -128,7 +130,8 @@ def configure_logging(name, level=None): ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=78000, backupCount=10) formatter_debug = FileFormatter( - "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", + "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", ) ch_debug.setFormatter(formatter_debug) ch_debug.setLevel(logging.DEBUG) diff --git a/core/thread.py b/core/thread.py index 7c49ee7425..41d2cd96ba 100644 --- a/core/thread.py +++ b/core/thread.py @@ -181,7 +181,9 @@ async def send_recipient_genesis_message(): thread_creation_response = self.bot.config["thread_creation_response"] embed = discord.Embed( - color=self.bot.mod_color, description=thread_creation_response, timestamp=channel.created_at, + color=self.bot.mod_color, + description=thread_creation_response, + timestamp=channel.created_at, ) recipient_thread_close = self.bot.config.get("recipient_thread_close") @@ -458,7 +460,10 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, # Thread closed message - embed = discord.Embed(title=self.bot.config["thread_close_title"], color=self.bot.error_color,) + embed = discord.Embed( + title=self.bot.config["thread_close_title"], + color=self.bot.error_color, + ) if self.bot.config["show_timestamp"]: embed.timestamp = datetime.utcnow() @@ -690,7 +695,11 @@ async def note(self, message: discord.Message, persistent=False, thread_creation raise MissingRequiredArgument(SimpleNamespace(name="msg")) msg = await self.send( - message, self.channel, note=True, persistent_note=persistent, thread_creation=thread_creation, + message, + self.channel, + note=True, + persistent_note=persistent, + thread_creation=thread_creation, ) self.bot.loop.create_task( @@ -715,7 +724,11 @@ async def reply(self, message: discord.Message, anonymous: bool = False, plain: try: user_msg = await self.send( - message, destination=self.recipient, from_mod=True, anonymous=anonymous, plain=plain, + message, + destination=self.recipient, + from_mod=True, + anonymous=anonymous, + plain=plain, ) except Exception as e: logger.error("Message delivery failed:", exc_info=True) @@ -734,7 +747,10 @@ async def reply(self, message: discord.Message, anonymous: bool = False, plain: ) tasks.append( message.channel.send( - embed=discord.Embed(color=self.bot.error_color, description=description,) + embed=discord.Embed( + color=self.bot.error_color, + description=description, + ) ) ) else: @@ -758,7 +774,8 @@ async def reply(self, message: discord.Message, anonymous: bool = False, plain: tasks.append( self.channel.send( embed=discord.Embed( - color=self.bot.error_color, description="Scheduled close has been cancelled.", + color=self.bot.error_color, + description="Scheduled close has been cancelled.", ) ) ) @@ -789,7 +806,8 @@ async def send( self.bot.loop.create_task( self.channel.send( embed=discord.Embed( - color=self.bot.error_color, description="Scheduled close has been cancelled.", + color=self.bot.error_color, + description="Scheduled close has been cancelled.", ) ) ) From cf65018c5bea0228a8ce38dd112308e7ea6e9958 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 22 Jul 2021 22:45:01 +0800 Subject: [PATCH 384/705] Fix SSL Error --- core/clients.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/clients.py b/core/clients.py index 0a527b59ce..667faf71bd 100644 --- a/core/clients.py +++ b/core/clients.py @@ -417,10 +417,14 @@ async def validate_database_connection(self, *, ssl_retry=True): if mongo_uri is None: mongo_uri = self.bot.config["mongo_uri"] for _ in range(3): - logger.warning("FAILED TO VERIFY SSL CERTIFICATE, ATTEMPTING TO START WITHOUT SSL (UNSAFE).") - logger.warning("To fix this warning, check there's no proxies blocking SSL cert verification, " - "run \"Certificate.command\" on MacOS, " - "and check certifi is up to date \"pip3 install --upgrade certifi\".") + logger.warning( + "FAILED TO VERIFY SSL CERTIFICATE, ATTEMPTING TO START WITHOUT SSL (UNSAFE)." + ) + logger.warning( + "To fix this warning, check there's no proxies blocking SSL cert verification, " + 'run "Certificate.command" on MacOS, ' + 'and check certifi is up to date "pip3 install --upgrade certifi".' + ) self.db = AsyncIOMotorClient(mongo_uri, tlsAllowInvalidCertificates=True).modmail_bot return await self.validate_database_connection(ssl_retry=False) if "ServerSelectionTimeoutError" in message: From 22fd835a76f48608f59146ac35776e2aace8b70b Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 22 Jul 2021 22:46:26 +0800 Subject: [PATCH 385/705] Changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb9ee01487..67bdc5a892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.9.5dev1 +# v3.9.5 -## Misc +## Internal - Bumped discord.py to v1.7.3, updated all other packages to latest. - More debug log files are now kept. +- Resolve SSL errors by retrying without SSL # v3.9.4 From 52c0fb3d5107c361a7317f1b8b5174c6cdc40202 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 23 Jul 2021 00:03:27 +0800 Subject: [PATCH 386/705] bump v --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 1deb9b7d2a..1c4fdd5354 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.9.5dev1" +__version__ = "3.9.5" import asyncio From c7514b1899c60d4456ab339199d15883f0f49c69 Mon Sep 17 00:00:00 2001 From: Matt Nikkel Date: Sun, 25 Jul 2021 23:00:55 -0400 Subject: [PATCH 387/705] Fix failing Docker build --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 232e84fb20..34aba25ce6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,8 @@ FROM python:3.9-slim as py FROM py as build RUN apt update && apt install -y g++ -COPY requirements.min.txt / -RUN pip install --prefix=/inst -U -r /requirements.min.txt +COPY requirements.txt / +RUN pip install --prefix=/inst -U -r /requirements.txt FROM py From 3e04dd0627ce9aad9949bad4d600aaf53fe39fe0 Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 1 Aug 2021 23:23:29 +0800 Subject: [PATCH 388/705] Fix UnicodeEncodeError on Windows. (#3043) * Fix UnionEncodeError on Windows when logging unicode emojis or special characters. * Formatting... --- bot.py | 11 ++++------- cogs/utility.py | 2 ++ core/models.py | 4 +++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/bot.py b/bot.py index 07c654be3c..8961001ab1 100644 --- a/bot.py +++ b/bot.py @@ -122,12 +122,9 @@ def hosting_method(self) -> HostingMethod: def startup(self): logger.line() - if os.name != "nt": - logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬") - logger.info("││││ │ │││││├─┤││") - logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") - else: - logger.info("MODMAIL") + logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬") + logger.info("││││ │ │││││├─┤││") + logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘") logger.info("v%s", __version__) logger.info("Authors: kyb3r, fourjr, Taaku18") logger.line() @@ -659,7 +656,7 @@ async def convert_emoji(self, name: str) -> str: try: name = await converter.convert(ctx, name.strip(":")) except commands.BadArgument as e: - logger.warning("%s is not a valid emoji. %s.", e) + logger.warning("%s is not a valid emoji. %s.", name, e) raise return name diff --git a/cogs/utility.py b/cogs/utility.py index 4ac02b9073..0790274c57 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -393,6 +393,7 @@ async def debug(self, ctx): os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" ), "r+", + encoding="utf-8", ) as f: logs = f.read().strip() @@ -448,6 +449,7 @@ async def debug_hastebin(self, ctx): os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log" ), "rb+", + encoding="utf-8", ) as f: logs = BytesIO(f.read().strip()) diff --git a/core/models.py b/core/models.py index 0238e051d4..44e75043d1 100644 --- a/core/models.py +++ b/core/models.py @@ -127,7 +127,9 @@ def format(self, record): def configure_logging(name, level=None): global ch_debug, log_level - ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=48000, backupCount=1) + ch_debug = RotatingFileHandler( + name, mode="a+", maxBytes=48000, backupCount=1, encoding="utf-8" + ) formatter_debug = FileFormatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", From d50ec339ca56f2eb0d3809bc525a66e1740b1fef Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Mon, 2 Aug 2021 09:51:36 +0200 Subject: [PATCH 389/705] Plugins: add Python Discord's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - **Case insensitive snippets**: Allow snippets to be ran even if with the wrong case. For example, `?Dm-RePort` will be recognized as `?dm-report`. - **Close message:** Add a `?closemessage` command that will close the thread after 15 minutes with a default message. - **MDLink**: Generate a ready to paste link to the thread logs. - **Reply cooldown**: Forbid you from sending the same message twice in ten seconds. - **Tagging**: Add a `?tag` command capable of adding a `$message|` header to the channel name. --- plugins/registry.json | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index a9f565a013..0ba98f499c 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1,4 +1,49 @@ { + "case_insensitive_snippets": { + "repository": "python-discord/modmail-plugins", + "branch": "main", + "description": "Allow snippets to be ran even if with the wrong case. For example, ?Dm-RePort will be recognized as ?dm-report.", + "bot_version": "2.20.1", + "title": "Case insensitive snippets", + "icon_url": "https://i.imgur.com/kaJYlMB.png", + "thumbnail_url": "https://i.imgur.com/kaJYlMB.png" + }, + "close_message": { + "repository": "python-discord/modmail-plugins", + "branch": "main", + "description": "Add a ?closemessage command that will close the thread after 15 minutes with a default message.", + "bot_version": "2.20.1", + "title": "Close message", + "icon_url": "https://i.imgur.com/ev7BFMz.png", + "thumbnail_url": "https://i.imgur.com/ev7BFMz.png" + }, + "mdlink": { + "repository": "python-discord/modmail-plugins", + "branch": "main", + "description": "Generate a ready to paste link to the thread logs.", + "bot_version": "2.20.1", + "title": "MDLink", + "icon_url": "https://i.imgur.com/JA2E63R.png", + "thumbnail_url": "https://i.imgur.com/JA2E63R.png" + }, + "reply_cooldown": { + "repository": "python-discord/modmail-plugins", + "branch": "main", + "description": "Forbid you from sending the same message twice in ten seconds.", + "bot_version": "2.20.1", + "title": "Reply cooldown", + "icon_url": "https://i.imgur.com/FtRQveT.png", + "thumbnail_url": "https://i.imgur.com/FtRQveT.png" + }, + "tagging": { + "repository": "python-discord/modmail-plugins", + "branch": "main", + "description": "Add a ?tag command capable of adding a $message| header to the channel name.", + "bot_version": "2.20.1", + "title": "Tagging", + "icon_url": "https://i.imgur.com/WajSLB1.png", + "thumbnail_url": "https://i.imgur.com/WajSLB1.png" + }, "dragory-migrate": { "repository": "kyb3r/modmail-plugins", "branch": "master", From d07b1a8f486a91de1a0105ae5a558360496da910 Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Wed, 4 Aug 2021 01:31:57 +0530 Subject: [PATCH 390/705] Let snippets be invoked case-insensitively. --- bot.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index 1c4fdd5354..b140dfe7d1 100644 --- a/bot.py +++ b/bot.py @@ -1132,8 +1132,11 @@ async def process_commands(self, message): cmd = message.content[len(self.prefix) :].strip() # Process snippets - if cmd in self.snippets: - snippet = self.snippets[cmd] + try: + snippet = self.snippets[cmd.lower()] + except KeyError: + pass + else: if self.config["anonymous_snippets"]: message.content = f"{self.prefix}fareply {snippet}" else: From f99245fb0e6fb86211e3e3d832aaf5d346a70d50 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 18:58:17 +0800 Subject: [PATCH 391/705] Update changelogs --- CHANGELOG.md | 3 ++- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 073db1ef6e..8a9f22988c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev3 +# v3.10.0-dev4 ## Added @@ -20,6 +20,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) - Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/kyb3r/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/kyb3r/modmail/pull/3027)) +- UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/kyb3r/modmail/pull/3043)) # v3.9.5 diff --git a/README.md b/README.md index 19931575c9..bd9d0b8f69 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ <<<<<<< HEAD - + ======= >>>>>>> master diff --git a/bot.py b/bot.py index 4c235dedad..837fe304cd 100644 --- a/bot.py +++ b/bot.py @@ -1,5 +1,5 @@ <<<<<<< HEAD -__version__ = "v3.10.0-dev3" +__version__ = "v3.10.0-dev4" ======= __version__ = "3.9.5" >>>>>>> master diff --git a/pyproject.toml b/pyproject.toml index 4bc1a22707..556c7b277c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ extend-exclude = ''' <<<<<<< HEAD [tool.poetry] name = 'Modmail' -version = '3.10.0-dev3' +version = '3.10.0-dev4' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From dc7a61d1e09c27ccda3f40948d3b7ab8a1936e9f Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:00:01 +0800 Subject: [PATCH 392/705] Update changelog --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a9f22988c..8429a26203 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,16 +12,17 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) -### Internal - -- `thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. Potentially breaking if plugins depend on this behaviour. - ## Fixed - Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) - Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/kyb3r/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/kyb3r/modmail/pull/3027)) - UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/kyb3r/modmail/pull/3043)) +## Internal + +- `thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. Potentially breaking if plugins depend on this behaviour. +- Fix return types, type hints, and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) + # v3.9.5 ## Internal From 3358622fa0f997ac49062d23ae772229faf948c0 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:03:03 +0800 Subject: [PATCH 393/705] Improved way to do case insensitive snippets --- bot.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index b140dfe7d1..a054bbc83a 100644 --- a/bot.py +++ b/bot.py @@ -1132,11 +1132,9 @@ async def process_commands(self, message): cmd = message.content[len(self.prefix) :].strip() # Process snippets - try: - snippet = self.snippets[cmd.lower()] - except KeyError: - pass - else: + cmd = cmd.lower() + if cmd in self.snippets: + snippet = self.snippets[cmd] if self.config["anonymous_snippets"]: message.content = f"{self.prefix}fareply {snippet}" else: From c00e6be6cd1082a6e2c1ee3fbf4c8983c0caf744 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:14:21 +0800 Subject: [PATCH 394/705] Update changelog and merge issues --- CHANGELOG.md | 2 ++ README.md | 4 ---- bot.py | 14 -------------- cogs/modmail.py | 11 ----------- core/models.py | 4 ---- core/thread.py | 22 ---------------------- pyproject.toml | 5 ----- 7 files changed, 2 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8429a26203..c8ae76fbb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,14 @@ however, insignificant breaking changes do not guarantee a major version bump, s ## Added - Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) +- Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080)) ## Fixed - Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) - Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/kyb3r/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/kyb3r/modmail/pull/3027)) - UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/kyb3r/modmail/pull/3043)) +- Notifications are no longer duplicated when using both `?notify` and `subscribe`. ([PR #3015](https://github.com/kyb3r/modmail/pull/3015)) ## Internal diff --git a/README.md b/README.md index bd9d0b8f69..7659898399 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,7 @@
      -<<<<<<< HEAD -======= - ->>>>>>> master
      diff --git a/bot.py b/bot.py index 93f407bcfa..fce5afa73c 100644 --- a/bot.py +++ b/bot.py @@ -1,8 +1,4 @@ -<<<<<<< HEAD __version__ = "v3.10.0-dev4" -======= -__version__ = "3.9.5" ->>>>>>> master import asyncio @@ -1268,13 +1264,9 @@ async def handle_reaction_events(self, payload): if not thread: return try: -<<<<<<< HEAD _, *linked_message = await thread.find_linked_messages( message.id, either_direction=True ) -======= - _, linked_message = await thread.find_linked_messages(message.id, either_direction=True) ->>>>>>> master except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return @@ -1305,7 +1297,6 @@ async def handle_react_to_contact(self, payload): else: emoji_fmt = f"<:{payload.emoji.name}:{payload.emoji.id}>" -<<<<<<< HEAD if emoji_fmt != react_message_emoji: return channel = self.get_channel(payload.channel_id) @@ -1338,11 +1329,6 @@ async def on_raw_reaction_add(self, payload): await asyncio.gather( self.handle_reaction_events(payload), self.handle_react_to_contact(payload), ) -======= - ctx = await self.get_context(message) - ctx.author = member - await ctx.invoke(self.get_command("contact"), user=member, manual_trigger=False) ->>>>>>> master async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: diff --git a/cogs/modmail.py b/cogs/modmail.py index 4e6c1fc126..f10a9e50d3 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1046,18 +1046,11 @@ async def contact( exists = await self.bot.threads.find(recipient=user) if exists: -<<<<<<< HEAD desc = "A thread for this user already exists" if exists.channel: desc += f" in {exists.channel.mention}" desc += "." embed = discord.Embed(color=self.bot.error_color, description=desc) -======= - embed = discord.Embed( - color=self.bot.error_color, - description="A thread for this user already " f"exists in {exists.channel.mention}.", - ) ->>>>>>> master await ctx.channel.send(embed=embed, delete_after=3) else: @@ -1550,13 +1543,9 @@ async def repair(self, ctx): other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) if recipient is None: -<<<<<<< HEAD self.bot.threads.cache[user.id] = thread = Thread( self.bot.threads, user_id, ctx.channel, other_recipients ) -======= - self.bot.threads.cache[user.id] = thread = Thread(self.bot.threads, user_id, ctx.channel) ->>>>>>> master else: self.bot.threads.cache[user.id] = thread = Thread( self.bot.threads, recipient, ctx.channel, other_recipients diff --git a/core/models.py b/core/models.py index 3b1e9ce481..7036498910 100644 --- a/core/models.py +++ b/core/models.py @@ -127,13 +127,9 @@ def format(self, record): def configure_logging(name, level=None): global ch_debug, log_level -<<<<<<< HEAD ch_debug = RotatingFileHandler( name, mode="a+", maxBytes=48000, backupCount=1, encoding="utf-8" ) -======= - ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=78000, backupCount=10) ->>>>>>> master formatter_debug = FileFormatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", diff --git a/core/thread.py b/core/thread.py index 2d24bd9132..b99a638a88 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1136,7 +1136,6 @@ async def find( logger.warning("Thread for %s cancelled.", recipient) return thread else: -<<<<<<< HEAD if not thread.cancelled and ( not thread.channel or not self.bot.get_channel(thread.channel.id) ): @@ -1144,13 +1143,6 @@ async def find( "Found existing thread for %s but the channel is invalid.", recipient_id ) await thread.close(closer=self.bot.user, silent=True, delete_channel=False) -======= - if not thread.channel or not self.bot.get_channel(thread.channel.id): - logger.warning("Found existing thread for %s but the channel is invalid.", recipient_id) - self.bot.loop.create_task( - thread.close(closer=self.bot.user, silent=True, delete_channel=False) - ) ->>>>>>> master thread = None else: channel = discord.utils.find( @@ -1224,17 +1216,10 @@ async def create( if thread.channel and self.bot.get_channel(thread.channel.id): logger.warning("Found an existing thread for %s, abort creating.", recipient) return thread -<<<<<<< HEAD - logger.warning( - "Found an existing thread for %s, closing previous thread.", recipient - ) - await thread.close(closer=self.bot.user, silent=True, delete_channel=False) -======= logger.warning("Found an existing thread for %s, closing previous thread.", recipient) self.bot.loop.create_task( thread.close(closer=self.bot.user, silent=True, delete_channel=False) ) ->>>>>>> master thread = Thread(self, recipient) @@ -1304,18 +1289,11 @@ async def remove_reactions(): for emoji in emojis: await confirm.remove_reaction(emoji, self.bot.user) await asyncio.sleep(0.2) -<<<<<<< HEAD self.bot.loop.create_task(remove_reactions()) if thread.cancelled: del self.cache[recipient.id] return thread -======= - await confirm.remove_reaction(deny_emoji, self.bot.user) - await destination.send(embed=discord.Embed(title="Cancelled", color=self.bot.error_color)) - del self.cache[recipient.id] - return thread ->>>>>>> master self.bot.loop.create_task(thread.setup(creator=creator, category=category, initial_message=message)) return thread diff --git a/pyproject.toml b/pyproject.toml index 556c7b277c..e038685a61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,6 @@ extend-exclude = ''' ) ''' -<<<<<<< HEAD [tool.poetry] name = 'Modmail' version = '3.10.0-dev4' @@ -34,10 +33,6 @@ readme = 'README.md' repository = 'https://github.com/kyb3r/modmail' homepage = 'https://github.com/kyb3r/modmail' keywords = ['discord', 'modmail'] -======= -[tool.pylint.messages_control] -disable = "C0330, C0326" ->>>>>>> master [tool.pylint.format] max-line-length = "110" From 0c9c129793d044438bc15ebdc68364d434b8e3d6 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:14:38 +0800 Subject: [PATCH 395/705] Formatting --- bot.py | 15 ++++++--------- cogs/modmail.py | 5 ++++- core/models.py | 4 +--- core/thread.py | 30 +++++++++++------------------- core/utils.py | 4 +--- 5 files changed, 23 insertions(+), 35 deletions(-) diff --git a/bot.py b/bot.py index fce5afa73c..fb9a1a9f9d 100644 --- a/bot.py +++ b/bot.py @@ -1264,9 +1264,7 @@ async def handle_reaction_events(self, payload): if not thread: return try: - _, *linked_message = await thread.find_linked_messages( - message.id, either_direction=True - ) + _, *linked_message = await thread.find_linked_messages(message.id, either_direction=True) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return @@ -1287,10 +1285,7 @@ async def handle_reaction_events(self, payload): async def handle_react_to_contact(self, payload): react_message_id = tryint(self.config.get("react_to_contact_message")) react_message_emoji = self.config.get("react_to_contact_emoji") - if ( - not all((react_message_id, react_message_emoji)) - or payload.message_id != react_message_id - ): + if not all((react_message_id, react_message_emoji)) or payload.message_id != react_message_id: return if payload.emoji.is_unicode_emoji(): emoji_fmt = payload.emoji.name @@ -1314,7 +1309,8 @@ async def handle_react_to_contact(self, payload): description=self.config["disabled_new_thread_response"], ) embed.set_footer( - text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon_url, + text=self.config["disabled_new_thread_footer"], + icon_url=self.guild.icon_url, ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", @@ -1327,7 +1323,8 @@ async def handle_react_to_contact(self, payload): async def on_raw_reaction_add(self, payload): await asyncio.gather( - self.handle_reaction_events(payload), self.handle_react_to_contact(payload), + self.handle_reaction_events(payload), + self.handle_react_to_contact(payload), ) async def on_raw_reaction_remove(self, payload): diff --git a/cogs/modmail.py b/cogs/modmail.py index f10a9e50d3..adec3f5447 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1067,7 +1067,10 @@ async def contact( return await ctx.send(embed=embed) thread = await self.bot.threads.create( - recipient=user, creator=creator, category=category, manual_trigger=manual_trigger, + recipient=user, + creator=creator, + category=category, + manual_trigger=manual_trigger, ) if thread.cancelled: return diff --git a/core/models.py b/core/models.py index 7036498910..445f7793ae 100644 --- a/core/models.py +++ b/core/models.py @@ -127,9 +127,7 @@ def format(self, record): def configure_logging(name, level=None): global ch_debug, log_level - ch_debug = RotatingFileHandler( - name, mode="a+", maxBytes=48000, backupCount=1, encoding="utf-8" - ) + ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=48000, backupCount=1, encoding="utf-8") formatter_debug = FileFormatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", diff --git a/core/thread.py b/core/thread.py index b99a638a88..44ff156aed 100644 --- a/core/thread.py +++ b/core/thread.py @@ -111,15 +111,11 @@ def cancelled(self, flag: bool): i.cancel() @classmethod - async def from_channel( - cls, manager: "ThreadManager", channel: discord.TextChannel - ) -> "Thread": + async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChannel) -> "Thread": recipient_id = match_user_id( channel.topic ) # there is a chance it grabs from another recipient's main thread - recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user( - recipient_id - ) + recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id) other_recipients = match_other_recipients(channel.topic) for n, uid in enumerate(other_recipients): @@ -761,7 +757,11 @@ async def reply(self, message: discord.Message, anonymous: bool = False, plain: for user in self.recipients: user_msg_tasks.append( self.send( - message, destination=user, from_mod=True, anonymous=anonymous, plain=plain, + message, + destination=user, + from_mod=True, + anonymous=anonymous, + plain=plain, ) ) @@ -1071,9 +1071,7 @@ async def set_title(self, title: str) -> None: user_id = match_user_id(self.channel.topic) ids = ",".join(i.id for i in self._other_recipients) - await self.channel.edit( - topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}" - ) + await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") async def add_user(self, user: typing.Union[discord.Member, discord.User]) -> None: title = match_title(self.channel.topic) @@ -1081,9 +1079,7 @@ async def add_user(self, user: typing.Union[discord.Member, discord.User]) -> No self._other_recipients.append(user) ids = ",".join(str(i.id) for i in self._other_recipients) - await self.channel.edit( - topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}" - ) + await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") class ThreadManager: @@ -1139,9 +1135,7 @@ async def find( if not thread.cancelled and ( not thread.channel or not self.bot.get_channel(thread.channel.id) ): - logger.warning( - "Found existing thread for %s but the channel is invalid.", recipient_id - ) + logger.warning("Found existing thread for %s but the channel is invalid.", recipient_id) await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: @@ -1280,9 +1274,7 @@ async def create( if str(r.emoji) == deny_emoji: thread.cancelled = True self.bot.loop.create_task( - destination.send( - embed=discord.Embed(title="Cancelled", color=self.bot.error_color) - ) + destination.send(embed=discord.Embed(title="Cancelled", color=self.bot.error_color)) ) async def remove_reactions(): diff --git a/core/utils.py b/core/utils.py index e80e298931..173eda25d5 100644 --- a/core/utils.py +++ b/core/utils.py @@ -218,9 +218,7 @@ def cleanup_code(content: str) -> str: return content.strip("` \n") -TOPIC_OTHER_RECIPIENTS_REGEX = re.compile( - r"Other Recipients:\s*((?:\d{17,21},*)+)", flags=re.IGNORECASE -) +TOPIC_OTHER_RECIPIENTS_REGEX = re.compile(r"Other Recipients:\s*((?:\d{17,21},*)+)", flags=re.IGNORECASE) TOPIC_TITLE_REGEX = re.compile(r"\bTitle: (.*)\n(?:User ID: )\b", flags=re.IGNORECASE | re.DOTALL) TOPIC_UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) From 323a5574eb412fc9bd9f7bcaa73e4493250e8db6 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:39:37 +0800 Subject: [PATCH 396/705] Fix contact with category and silent, #3076 --- CHANGELOG.md | 1 + bot.py | 2 +- cogs/modmail.py | 9 ++++++++- core/thread.py | 7 +++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8ae76fbb6..41da5adcee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/kyb3r/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/kyb3r/modmail/pull/3027)) - UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/kyb3r/modmail/pull/3043)) - Notifications are no longer duplicated when using both `?notify` and `subscribe`. ([PR #3015](https://github.com/kyb3r/modmail/pull/3015)) +- `?contact` now works properly with both category and silent. ([GH #3076](https://github.com/kyb3r/modmail/issues/3076)) ## Internal diff --git a/bot.py b/bot.py index fb9a1a9f9d..36675a1ae4 100644 --- a/bot.py +++ b/bot.py @@ -284,7 +284,7 @@ def _cancel_tasks(): loop.run_until_complete(loop.shutdown_asyncgens()) finally: logger.info("Closing the event loop.") - loop.close() + # loop.close() if not future.cancelled(): try: diff --git a/cogs/modmail.py b/cogs/modmail.py index adec3f5447..1dee52d941 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1038,7 +1038,14 @@ async def contact( if isinstance(category, str): if "silent" in category or "silently" in category: silent = True - category = None + category = category.strip("silently").strip("silent").strip() + try: + category = await SimilarCategoryConverter().convert(ctx, category) # attempt to find a category again + except commands.BadArgument: + category = None + + if isinstance(category, str): + category = None if user.bot: embed = discord.Embed(color=self.bot.error_color, description="Cannot start a thread with a bot.") diff --git a/core/thread.py b/core/thread.py index 44ff156aed..0c5339ff83 100644 --- a/core/thread.py +++ b/core/thread.py @@ -487,10 +487,17 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, if self.bot.config["show_timestamp"]: embed.timestamp = datetime.utcnow() + if not message: + if self.id == closer.id: + message = self.bot.config["thread_self_close_response"] + else: + message = self.bot.config["thread_close_response"] + message = self.bot.formatter.format( message, closer=closer, loglink=log_url, logkey=log_data["key"] if log_data else None ) + embed.description = message footer = self.bot.config["thread_close_footer"] embed.set_footer(text=footer, icon_url=self.bot.guild.icon_url) From 0c49598ec8c7758ed5b64ad3ffa4544f793bbf18 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:48:43 +0800 Subject: [PATCH 397/705] Resolve close_on_leave_reason not properly working --- CHANGELOG.md | 1 + core/thread.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41da5adcee..ad69c7b7ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/kyb3r/modmail/pull/3043)) - Notifications are no longer duplicated when using both `?notify` and `subscribe`. ([PR #3015](https://github.com/kyb3r/modmail/pull/3015)) - `?contact` now works properly with both category and silent. ([GH #3076](https://github.com/kyb3r/modmail/issues/3076)) +- Resolves `close_on_leave_reason` not properly working when `close_on_leave` is enabled. ([GH #3075](https://github.com/kyb3r/modmail/issues/3075)) ## Internal diff --git a/core/thread.py b/core/thread.py index 0c5339ff83..2d1d5d18f9 100644 --- a/core/thread.py +++ b/core/thread.py @@ -414,7 +414,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, "title": match_title(self.channel.topic), "closed_at": str(datetime.utcnow()), "nsfw": self.channel.nsfw, - "close_message": message if not silent else None, + "close_message": message, "closer": { "id": str(closer.id), "name": closer.name, From adac1de293cd188a8b2e25d22ddb1fa01f0d6fc8 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:51:02 +0800 Subject: [PATCH 398/705] Invalid arguments are now properly catched and a proper error message is sent (BadUnionArg) --- CHANGELOG.md | 3 ++- bot.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad69c7b7ed..eaa0e668d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s - UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/kyb3r/modmail/pull/3043)) - Notifications are no longer duplicated when using both `?notify` and `subscribe`. ([PR #3015](https://github.com/kyb3r/modmail/pull/3015)) - `?contact` now works properly with both category and silent. ([GH #3076](https://github.com/kyb3r/modmail/issues/3076)) -- Resolves `close_on_leave_reason` not properly working when `close_on_leave` is enabled. ([GH #3075](https://github.com/kyb3r/modmail/issues/3075)) +- `close_on_leave_reason` now works properly when `close_on_leave` is enabled. ([GH #3075](https://github.com/kyb3r/modmail/issues/3075)) +- Invalid arguments are now properly catched and a proper error message is sent. ## Internal diff --git a/bot.py b/bot.py index 36675a1ae4..26fac619d2 100644 --- a/bot.py +++ b/bot.py @@ -1472,7 +1472,7 @@ async def on_error(self, event_method, *args, **kwargs): logger.error("Unexpected exception:", exc_info=sys.exc_info()) async def on_command_error(self, context, exception): - if isinstance(exception, commands.BadArgument): + if isinstance(exception, (commands.BadArgument, commands.BadUnionArgument)): await context.trigger_typing() await context.send(embed=discord.Embed(color=self.error_color, description=str(exception))) elif isinstance(exception, commands.CommandNotFound): From dcfdfead8959a27389eb3764ba15b5d299491268 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 20:31:41 +0800 Subject: [PATCH 399/705] Removeuser (resolve #3065), silent adding/removing (#3054) --- CHANGELOG.md | 6 +++ cogs/modmail.py | 99 +++++++++++++++++++++++++++++++++++++++---------- core/thread.py | 37 +++++++++++++++--- 3 files changed, 117 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eaa0e668d2..d398e71f2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v3.10.0-dev4 +v3.10 adds group conversations while resolving othre bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. + +## Breaking + +- `Thread.recipient` (`str`) is now `Thread.recipients` (`List[str]`). + ## Added - Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) diff --git a/cogs/modmail.py b/cogs/modmail.py index 1dee52d941..8b86a8215c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -675,8 +675,11 @@ async def title(self, ctx, *, name: str): @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @commands.cooldown(1, 600, BucketType.channel) - async def adduser(self, ctx, *, user: discord.Member): - """Adds a user to a modmail thread""" + async def adduser(self, ctx, user: discord.Member, *, options: str.lower = ""): + """Adds a user to a modmail thread + + `options` can be `silent` or `silently`. + """ curr_thread = await self.bot.threads.find(recipient=user) if curr_thread: @@ -686,30 +689,88 @@ async def adduser(self, ctx, *, user: discord.Member): color=self.bot.error_color, ) await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) else: + if 'silent' not in options and 'silently' not in options: + em = discord.Embed( + title="New Thread (Group)", + description=f"{ctx.author.name} has added you to a Modmail thread.", + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url) + await user.send(embed=em) + + em = discord.Embed( + title="New User", + description=f"{ctx.author.name} has added {user.name} to the Modmail thread.", + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{user}", icon_url=user.avatar_url) + + for i in ctx.thread.recipients: + if i != user: + await i.send(embed=em) + + await ctx.thread.add_user(user) + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + + @commands.command(cooldown_after_parsing=True) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + @commands.cooldown(1, 600, BucketType.channel) + async def removeuser(self, ctx, user: discord.Member, *, options: str.lower = ""): + """Removes a user from a modmail thread + + `options` can be `silent` or `silently`. + """ + + curr_thread = await self.bot.threads.find(recipient=user) + if ctx.thread != curr_thread: em = discord.Embed( - title="New Thread (Group)", - description=f"{ctx.author.name} has added you to a Modmail thread.", - color=self.bot.main_color, + title="Error", + description="User is not in this thread.", + color=self.bot.error_color, ) - if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url) - await user.send(embed=em) - + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + elif ctx.thread.recipient == user: em = discord.Embed( - title="New User", - description=f"{ctx.author.name} has added {user.name} to the Modmail thread.", - color=self.bot.main_color, + title="Error", + description="User is the main recipient of the thread and cannot be removed.", + color=self.bot.error_color, ) - if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{user}", icon_url=user.avatar_url) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + else: + if 'silent' not in options and 'silently' not in options: + em = discord.Embed( + title="Removed From Thread (Group)", + description=f"{ctx.author.name} has been removed from the Modmail thread.", + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url) + await user.send(embed=em) - for i in ctx.thread.recipients: - await i.send(embed=em) + em = discord.Embed( + title="User Removed", + description=f"{ctx.author.name} has removed {user.name} from the Modmail thread.", + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{user}", icon_url=user.avatar_url) - await ctx.thread.add_user(user) + for i in ctx.thread.recipients: + await i.send(embed=em) + + await ctx.thread.remove_user(user) sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) diff --git a/core/thread.py b/core/thread.py index 2d1d5d18f9..bc47f606ed 100644 --- a/core/thread.py +++ b/core/thread.py @@ -57,7 +57,10 @@ def __init__( self._cancelled = False def __repr__(self): - return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipienets={len(self._other_recipients)})' + return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipients={len(self._other_recipients)})' + + def __eq__(self, other): + return self.id == other.id async def wait_until_ready(self) -> None: """Blocks execution until the thread is fully set up.""" @@ -115,13 +118,19 @@ async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChann recipient_id = match_user_id( channel.topic ) # there is a chance it grabs from another recipient's main thread - recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id) - other_recipients = match_other_recipients(channel.topic) - for n, uid in enumerate(other_recipients): - other_recipients[n] = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid) + if recipient_id in manager.cache: + thread = manager.cache[recipient_id] + else: + recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id) - return cls(manager, recipient or recipient_id, channel, other_recipients) + other_recipients = match_other_recipients(channel.topic) + for n, uid in enumerate(other_recipients): + other_recipients[n] = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid) + + thread = cls(manager, recipient or recipient_id, channel, other_recipients) + + return thread async def setup(self, *, creator=None, category=None, initial_message=None): """Create the thread channel and other io related initialisation tasks""" @@ -1088,6 +1097,16 @@ async def add_user(self, user: typing.Union[discord.Member, discord.User]) -> No ids = ",".join(str(i.id) for i in self._other_recipients) await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + async def remove_user(self, user: typing.Union[discord.Member, discord.User]) -> None: + title = match_title(self.channel.topic) + user_id = match_user_id(self.channel.topic) + self._other_recipients.remove(user) + + ids = ",".join(str(i.id) for i in self._other_recipients) + await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + # if user.id in self.manager.cache: + # self.manager.cache.pop(self.id) + class ThreadManager: """Class that handles storing, finding and creating Modmail threads.""" @@ -1146,6 +1165,7 @@ async def find( await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: + print('in here') channel = discord.utils.find( lambda x: str(recipient_id) in x.topic if x.topic else False, self.bot.modmail_guild.text_channels, @@ -1157,6 +1177,11 @@ async def find( # only save if data is valid self.cache[recipient_id] = thread thread.ready = True + + if thread and recipient_id not in [x.id for x in thread.recipients]: + self.cache.pop(recipient_id) + thread = None + return thread async def _find_from_channel(self, channel): From 00eb779f2f9abe5f52c7413dad9656971fef9b3c Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 20:32:32 +0800 Subject: [PATCH 400/705] Formatting --- cogs/modmail.py | 8 +++++--- core/checks.py | 2 +- core/thread.py | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 8b86a8215c..bbff3b491a 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -691,7 +691,7 @@ async def adduser(self, ctx, user: discord.Member, *, options: str.lower = ""): await ctx.send(embed=em) ctx.command.reset_cooldown(ctx) else: - if 'silent' not in options and 'silently' not in options: + if "silent" not in options and "silently" not in options: em = discord.Embed( title="New Thread (Group)", description=f"{ctx.author.name} has added you to a Modmail thread.", @@ -747,7 +747,7 @@ async def removeuser(self, ctx, user: discord.Member, *, options: str.lower = "" await ctx.send(embed=em) ctx.command.reset_cooldown(ctx) else: - if 'silent' not in options and 'silently' not in options: + if "silent" not in options and "silently" not in options: em = discord.Embed( title="Removed From Thread (Group)", description=f"{ctx.author.name} has been removed from the Modmail thread.", @@ -1101,7 +1101,9 @@ async def contact( silent = True category = category.strip("silently").strip("silent").strip() try: - category = await SimilarCategoryConverter().convert(ctx, category) # attempt to find a category again + category = await SimilarCategoryConverter().convert( + ctx, category + ) # attempt to find a category again except commands.BadArgument: category = None diff --git a/core/checks.py b/core/checks.py index 1079b55530..3f3666538d 100644 --- a/core/checks.py +++ b/core/checks.py @@ -31,7 +31,7 @@ def has_permissions(permission_level: PermissionLevel = PermissionLevel.REGULAR) :: @has_permissions(PermissionLevel.OWNER) async def setup(ctx): - print("Success") + await ctx.send('Success') """ return commands.check(has_permissions_predicate(permission_level)) diff --git a/core/thread.py b/core/thread.py index bc47f606ed..29446a32c3 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1165,7 +1165,6 @@ async def find( await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: - print('in here') channel = discord.utils.find( lambda x: str(recipient_id) in x.topic if x.topic else False, self.bot.modmail_guild.text_channels, From 417f30326b315d85513b3426258a7f103d300c36 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 21:16:55 +0800 Subject: [PATCH 401/705] add multiple users to a thread (resolve #3066), new group config options --- cogs/modmail.py | 309 ++++++++++++++++++++++++++++++++---------- core/config.py | 13 ++ core/config_help.json | 144 ++++++++++++++++++++ core/thread.py | 15 +- 4 files changed, 401 insertions(+), 80 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index bbff3b491a..aeace73192 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -671,108 +671,271 @@ async def title(self, ctx, *, name: str): await ctx.message.pin() await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.command(cooldown_after_parsing=True) + @commands.command(usage=" [options]", cooldown_after_parsing=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @commands.cooldown(1, 600, BucketType.channel) - async def adduser(self, ctx, user: discord.Member, *, options: str.lower = ""): + async def adduser(self, ctx, *users: Union[discord.Member, str]): """Adds a user to a modmail thread `options` can be `silent` or `silently`. """ - - curr_thread = await self.bot.threads.find(recipient=user) - if curr_thread: + silent = False + for u in users: + if isinstance(u, str): + if "silent" in u or "silently" in u: + silent = True + users.remove(u) # remove all strings so users is a List[Member] + else: + # u is a discord.Member + curr_thread = await self.bot.threads.find(recipient=u) + if curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is already in a thread: {curr_thread.channel.mention}.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + if not silent: em = discord.Embed( - title="Error", - description=f"User is already in a thread: {curr_thread.channel.mention}.", - color=self.bot.error_color, + title=self.bot.config["private_added_to_group_title"], + description=self.bot.config["private_added_to_group_description"].format(moderator=ctx.author), + color=self.bot.main_color, ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - else: - if "silent" not in options and "silently" not in options: - em = discord.Embed( - title="New Thread (Group)", - description=f"{ctx.author.name} has added you to a Modmail thread.", - color=self.bot.main_color, - ) - if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url) - await user.send(embed=em) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=str(ctx.author), icon_url=ctx.author.avatar_url) + for u in users: + await u.send(embed=em) - em = discord.Embed( - title="New User", - description=f"{ctx.author.name} has added {user.name} to the Modmail thread.", - color=self.bot.main_color, - ) - if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{user}", icon_url=user.avatar_url) + em = discord.Embed( + title=self.bot.config["public_added_to_group_title"], + description=self.bot.config["private_added_to_group_description"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) - for i in ctx.thread.recipients: - if i != user: - await i.send(embed=em) + for i in ctx.thread.recipients: + if i not in users: + await i.send(embed=em) - await ctx.thread.add_user(user) - sent_emoji, _ = await self.bot.retrieve_emoji() - await self.bot.add_reaction(ctx.message, sent_emoji) + await ctx.thread.add_users(users) + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.command(cooldown_after_parsing=True) + @commands.command(usage=" [options]", cooldown_after_parsing=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @commands.cooldown(1, 600, BucketType.channel) - async def removeuser(self, ctx, user: discord.Member, *, options: str.lower = ""): + async def removeuser(self, ctx, *users: Union[discord.Member, str]): """Removes a user from a modmail thread `options` can be `silent` or `silently`. """ + silent = False + for u in users: + if isinstance(u, str): + if "silent" in u or "silently" in u: + silent = True + users.remove(u) # remove all strings so users is a List[Member] + else: + # u is a discord.Member + curr_thread = await self.bot.threads.find(recipient=u) + if ctx.thread != curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is not in this thread.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + elif ctx.thread.recipient == u: + em = discord.Embed( + title="Error", + description=f"{u.mention} is the main recipient of the thread and cannot be removed.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return - curr_thread = await self.bot.threads.find(recipient=user) - if ctx.thread != curr_thread: + if not silent: em = discord.Embed( - title="Error", - description="User is not in this thread.", - color=self.bot.error_color, + title=self.bot.config["private_removed_from_group_title"], + description=self.bot.config["private_removed_from_group_description"].format(moderator=ctx.author), + color=self.bot.main_color, ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - elif ctx.thread.recipient == user: + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=str(ctx.author), icon_url=ctx.author.avatar_url) + for u in users: + await u.send(embed=em) + em = discord.Embed( - title="Error", - description="User is the main recipient of the thread and cannot be removed.", - color=self.bot.error_color, + title=self.bot.config["public_removed_from_group_title"], + description=self.bot.config["private_removed_from_group_description"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + color=self.bot.main_color, ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - else: - if "silent" not in options and "silently" not in options: - em = discord.Embed( - title="Removed From Thread (Group)", - description=f"{ctx.author.name} has been removed from the Modmail thread.", - color=self.bot.main_color, - ) - if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url) - await user.send(embed=em) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) - em = discord.Embed( - title="User Removed", - description=f"{ctx.author.name} has removed {user.name} from the Modmail thread.", - color=self.bot.main_color, - ) - if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{user}", icon_url=user.avatar_url) + for i in ctx.thread.recipients: + if i not in users: + await i.send(embed=em) + + await ctx.thread.remove_users(users) + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + + @commands.command(usage=" [options]", cooldown_after_parsing=True) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + @commands.cooldown(1, 600, BucketType.channel) + async def anonadduser(self, ctx, *users: Union[discord.Member, str]): + """Adds a user to a modmail thread anonymously + + `options` can be `silent` or `silently`. + """ + silent = False + for u in users: + if isinstance(u, str): + if "silent" in u or "silently" in u: + silent = True + users.remove(u) # remove all strings so users is a List[Member] + else: + # u is a discord.Member + curr_thread = await self.bot.threads.find(recipient=u) + if curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is already in a thread: {curr_thread.channel.mention}.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + if not silent: + em = discord.Embed( + title=self.bot.config["private_added_to_group_title"], + description=self.bot.config["private_added_to_group_description_anon"], + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + + tag = self.bot.config["mod_tag"] + if tag is None: + tag = str(ctx.author.top_role) + name = self.bot.config["anon_username"] + if name is None: + name = tag + avatar_url = self.bot.config["anon_avatar_url"] + if avatar_url is None: + avatar_url = self.bot.guild.icon_url + em.set_footer(text=name, icon_url=avatar_url) + + for u in users: + await u.send(embed=em) - for i in ctx.thread.recipients: + em = discord.Embed( + title=self.bot.config["public_added_to_group_title"], + description=self.bot.config["private_added_to_group_description_anon"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) + + for i in ctx.thread.recipients: + if i not in users: await i.send(embed=em) - await ctx.thread.remove_user(user) - sent_emoji, _ = await self.bot.retrieve_emoji() - await self.bot.add_reaction(ctx.message, sent_emoji) + await ctx.thread.add_users(users) + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + + @commands.command(usage=" [options]", cooldown_after_parsing=True) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + @commands.cooldown(1, 600, BucketType.channel) + async def anonremoveuser(self, ctx, *users: Union[discord.Member, str]): + """Removes a user from a modmail thread anonymously + + `options` can be `silent` or `silently`. + """ + silent = False + for u in users: + if isinstance(u, str): + if "silent" in u or "silently" in u: + silent = True + users.remove(u) # remove all strings so users is a List[Member] + else: + # u is a discord.Member + curr_thread = await self.bot.threads.find(recipient=u) + if ctx.thread != curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is not in this thread.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + elif ctx.thread.recipient == u: + em = discord.Embed( + title="Error", + description=f"{u.mention} is the main recipient of the thread and cannot be removed.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + + if not silent: + em = discord.Embed( + title=self.bot.config["private_removed_from_group_title"], + description=self.bot.config["private_removed_from_group_description_anon"].format(moderator=ctx.author), + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + + tag = self.bot.config["mod_tag"] + if tag is None: + tag = str(ctx.author.top_role) + name = self.bot.config["anon_username"] + if name is None: + name = tag + avatar_url = self.bot.config["anon_avatar_url"] + if avatar_url is None: + avatar_url = self.bot.guild.icon_url + em.set_footer(text=name, icon_url=avatar_url) + + for u in users: + await u.send(embed=em) + + em = discord.Embed( + title=self.bot.config["public_removed_from_group_title"], + description=self.bot.config["private_removed_from_group_description"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + color=self.bot.main_color, + ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) + + for i in ctx.thread.recipients: + if i not in users: + await i.send(embed=em) + + await ctx.thread.remove_users(users) + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) diff --git a/core/config.py b/core/config.py index 255c3667de..829ce7ff3b 100644 --- a/core/config.py +++ b/core/config.py @@ -83,6 +83,19 @@ class ConfigManager: "silent_alert_on_mention": False, "show_timestamp": True, "anonymous_snippets": False, + # group conversations + "private_added_to_group_title": "New Thread (Group)", + "private_added_to_group_description": "{moderator.name} has added you to a Modmail thread.", + "private_added_to_group_description_anon": "A moderator has added you to a Modmail thread.", + "public_added_to_group_title": "New User", + "public_added_to_group_description": "{moderator.name} has added {users} to the Modmail thread.", + "public_added_to_group_description_anon": "A moderator has added {users} to the Modmail thread.", + "private_removed_from_group_title": "Removed From Thread (Group)", + "private_removed_from_group_description": "{moderator.name} has removed you from the Modmail thread.", + "private_removed_from_group_description_anon": "A moderator has removed you from the Modmail thread.", + "public_removed_from_group_title": "User Removed", + "public_removed_from_group_description": "{moderator.name} has removed {users} from the Modmail thread.", + "public_removed_from_group_description_anon": "A moderator has removed {users} from the Modmail thread.", # moderation "recipient_color": str(discord.Color.gold()), "mod_color": str(discord.Color.green()), diff --git a/core/config_help.json b/core/config_help.json index ede81617ed..d6a4627d96 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -711,6 +711,150 @@ "See also: `anon_avatar_url`, `anon_tag`." ] }, + "private_added_to_group_title": { + "default": "New Thread (Group)", + "description": "This is the message embed title sent to the recipient that is just added to a thread.", + "examples": [ + "`{prefix}config set private_added_to_group_title Welcome to this new group thread!`" + ], + "notes": [ + "The public_ variant is used when sending to other thread recipients.", + "See also: `private_added_to_group_description`, `public_added_to_group_title`" + ] + }, + "private_added_to_group_description": { + "default": "\"{{moderator.name}} has added you to a Modmail thread.\"", + "description": "This is the message embed content sent to the recipient that is just added to a thread.", + "examples": [ + "`{prefix}config set private_added_to_group_description Any message sent here will be sent to all otherthread recipients.`" + ], + "notes": [ + "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", + "When anonadduser is used, `private_added_to_group_description_anon` is used instead.", + "The public_ variant is used when sending to other thread recipients.", + "See also: `private_added_to_group_title`, `public_added_to_group_description`" + ] + }, + "private_added_to_group_description_anon": { + "default": "A moderator has added you to a Modmail thread.", + "description": "This is the message embed content sent to the recipient that is just added to a thread when adduser is used anonymously.", + "examples": [ + "`{prefix}config set private_added_to_group_description_anon Any message sent here will be sent to all other thread recipients.`" + ], + "notes": [ + "When adduser (no anon) is used, `private_added_to_group_description` is used instead.", + "The public_ variant is used when sending to other thread recipients.", + "See also: `private_added_to_group_title`, `public_added_to_group_description_anon`" + ] + }, + "public_added_to_group_title": { + "default": "New User", + "description": "This is the message embed title sent to all other recipients when someone is added to the thread.", + "examples": [ + "`{prefix}config set public_added_to_group_title Welcome to our new user!`" + ], + "notes": [ + "The private_ variant is used when sending to the new user.", + "See also: `private_added_to_group_title`, `private_added_to_group_title`" + ] + }, + "public_added_to_group_description": { + "default": "\"{{moderator.name}} has added {{users}} to the Modmail thread.\"", + "description": "This is the message embed content sent to all other recipients when someone is added to the thread.", + "examples": [ + "`{prefix}config set public_added_to_group_description Welcome {users}!`" + ], + "notes": [ + "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", + "When anonadduser is used, `public_added_to_group_description_anon` is used instead.", + "The private_ variant is used when sending to the new user.", + "See also: `public_added_to_group_title`, `private_added_to_group_description`" + ] + }, + "public_added_to_group_description_anon": { + "default": "\"A moderator has added {{users}} to the Modmail thread.\"", + "description": "This is the message embed content sent to all other recipients when someone is added to the thread when adduser is used anonymously.", + "examples": [ + "`{prefix}config set public_added_to_group_description_anon Any message sent here will be sent to all other thread recipients.`" + ], + "notes": [ + "When adduser (no anon) is used, `public_added_to_group_description` is used instead.", + "The private_ variant is used when sending to the new user.", + "See also: `public_added_to_group_title`, `private_added_to_group_description_anon`" + ] + }, + "private_removed_from_group_title": { + "default": "Removed From Thread (Group)", + "description": "This is the message embed title sent to the recipient that is just removed from a thread.", + "examples": [ + "`{prefix}config set private_removed_from_group_title Welcome to this new group thread!`" + ], + "notes": [ + "The public_ variant is used when sending to other thread recipients.", + "See also: `private_removed_from_group_description`, `public_removed_from_group_title`" + ] + }, + "private_removed_from_group_description": { + "default": "\"{{moderator.name}} has removed you from the Modmail thread.\"", + "description": "This is the message embed content sent to the recipient that is just removed from a thread.", + "examples": [ + "`{prefix}config set private_removed_from_group_description Bye`" + ], + "notes": [ + "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", + "When anonremoveuser is used, `private_removed_from_group_description_anon` is used instead.", + "The public_ variant is used when sending to other thread recipients.", + "See also: `private_removed_from_group_title`, `public_removed_from_group_description`" + ] + }, + "private_removed_from_group_description_anon": { + "default": "A moderator has removed you from the Modmail thread.", + "description": "This is the message embed content sent to the recipient that is just removed from a thread when removeuser is used anonymously.", + "examples": [ + "`{prefix}config set private_removed_from_group_description_anon You are permenantly removed from this thread.`" + ], + "notes": [ + "When adduser (no anon) is used, `private_removed_from_group_description` is used instead.", + "The public_ variant is used when sending to other thread recipients.", + "See also: `private_removed_from_group_title`, `public_removed_from_group_description_anon`" + ] + }, + "public_removed_from_group_title": { + "default": "User Removed", + "description": "This is the message embed title sent to all other recipients when someone is removed from the thread.", + "examples": [ + "`{prefix}config set public_removed_from_group_title User is now gone!`" + ], + "notes": [ + "The private_ variant is used when sending to the new user.", + "See also: `private_removed_from_group_title`, `private_removed_from_group_title`" + ] + }, + "public_removed_from_group_description": { + "default": "\"{{moderator.name}} has removed {{users}} from the Modmail thread.\"", + "description": "This is the message embed content sent to all other recipients when someone is removed from the thread.", + "examples": [ + "`{prefix}config set public_removed_from_group_description Goodbye {users}!`" + ], + "notes": [ + "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", + "When anonremoveuser is used, `public_removed_from_group_description_anon` is used instead.", + "The private_ variant is used when sending to the new user.", + "See also: `public_removed_from_group_title`, `private_removed_from_group_description`" + ] + }, + "public_removed_from_group_description_anon": { + "default": "\"A moderator has removed {{users}} from the Modmail thread.\"", + "description": "This is the message embed content sent to all other recipients when someone is removed from the thread when removeuser is used anonymously.", + "examples": [ + "`{prefix}config set public_removed_from_group_description_anon Goodbye {users}!`" + ], + "notes": [ + "When adduser (no anon) is used, `public_removed_from_group_description` is used instead.", + "The private_ variant is used when sending to the new user.", + "See also: `public_removed_from_group_title`, `private_removed_from_group_description_anon`" + ] + }, "confirm_thread_creation": { "default": "No", "description": "Ensure users confirm that they want to create a new thread", diff --git a/core/thread.py b/core/thread.py index 29446a32c3..91f30417a8 100644 --- a/core/thread.py +++ b/core/thread.py @@ -60,7 +60,9 @@ def __repr__(self): return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipients={len(self._other_recipients)})' def __eq__(self, other): - return self.id == other.id + if isinstance(other, Thread): + return self.id == other.id + return super().__eq__(other) async def wait_until_ready(self) -> None: """Blocks execution until the thread is fully set up.""" @@ -1089,23 +1091,22 @@ async def set_title(self, title: str) -> None: await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") - async def add_user(self, user: typing.Union[discord.Member, discord.User]) -> None: + async def add_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: title = match_title(self.channel.topic) user_id = match_user_id(self.channel.topic) - self._other_recipients.append(user) + self._other_recipients += users ids = ",".join(str(i.id) for i in self._other_recipients) await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") - async def remove_user(self, user: typing.Union[discord.Member, discord.User]) -> None: + async def remove_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: title = match_title(self.channel.topic) user_id = match_user_id(self.channel.topic) - self._other_recipients.remove(user) + for u in users: + self._other_recipients.remove(u) ids = ",".join(str(i.id) for i in self._other_recipients) await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") - # if user.id in self.manager.cache: - # self.manager.cache.pop(self.id) class ThreadManager: From d240e567bfffb9b80260e913b88256236040f0fb Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 21:17:10 +0800 Subject: [PATCH 402/705] Formatting --- cogs/modmail.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index aeace73192..e8e0a7cc02 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -701,7 +701,9 @@ async def adduser(self, ctx, *users: Union[discord.Member, str]): if not silent: em = discord.Embed( title=self.bot.config["private_added_to_group_title"], - description=self.bot.config["private_added_to_group_description"].format(moderator=ctx.author), + description=self.bot.config["private_added_to_group_description"].format( + moderator=ctx.author + ), color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -712,7 +714,9 @@ async def adduser(self, ctx, *users: Union[discord.Member, str]): em = discord.Embed( title=self.bot.config["public_added_to_group_title"], - description=self.bot.config["private_added_to_group_description"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + description=self.bot.config["private_added_to_group_description"].format( + moderator=ctx.author, users=", ".join(u.name for u in users) + ), color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -767,7 +771,9 @@ async def removeuser(self, ctx, *users: Union[discord.Member, str]): if not silent: em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description"].format(moderator=ctx.author), + description=self.bot.config["private_removed_from_group_description"].format( + moderator=ctx.author + ), color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -778,7 +784,9 @@ async def removeuser(self, ctx, *users: Union[discord.Member, str]): em = discord.Embed( title=self.bot.config["public_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + description=self.bot.config["private_removed_from_group_description"].format( + moderator=ctx.author, users=", ".join(u.name for u in users) + ), color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -845,7 +853,9 @@ async def anonadduser(self, ctx, *users: Union[discord.Member, str]): em = discord.Embed( title=self.bot.config["public_added_to_group_title"], - description=self.bot.config["private_added_to_group_description_anon"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + description=self.bot.config["private_added_to_group_description_anon"].format( + moderator=ctx.author, users=", ".join(u.name for u in users) + ), color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -900,7 +910,9 @@ async def anonremoveuser(self, ctx, *users: Union[discord.Member, str]): if not silent: em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description_anon"].format(moderator=ctx.author), + description=self.bot.config["private_removed_from_group_description_anon"].format( + moderator=ctx.author + ), color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -922,7 +934,9 @@ async def anonremoveuser(self, ctx, *users: Union[discord.Member, str]): em = discord.Embed( title=self.bot.config["public_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description"].format(moderator=ctx.author, users=', '.join(u.name for u in users)), + description=self.bot.config["private_removed_from_group_description"].format( + moderator=ctx.author, users=", ".join(u.name for u in users) + ), color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: From ebcfe4ea118ba9907ed403e04f5fbb3d33393027 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 21:43:47 +0800 Subject: [PATCH 403/705] Fix formatter, allow add by roles (resolve #3053) --- cogs/modmail.py | 264 +++++++++++++++++++++++++++++------------------- 1 file changed, 161 insertions(+), 103 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index e8e0a7cc02..74b99dde76 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -671,39 +671,60 @@ async def title(self, ctx, *, name: str): await ctx.message.pin() await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.command(usage=" [options]", cooldown_after_parsing=True) + @commands.command(usage=" [options]", cooldown_after_parsing=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @commands.cooldown(1, 600, BucketType.channel) - async def adduser(self, ctx, *users: Union[discord.Member, str]): + async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str]): """Adds a user to a modmail thread `options` can be `silent` or `silently`. """ silent = False - for u in users: + users = [] + for u in users_arg: if isinstance(u, str): if "silent" in u or "silently" in u: silent = True - users.remove(u) # remove all strings so users is a List[Member] - else: - # u is a discord.Member - curr_thread = await self.bot.threads.find(recipient=u) - if curr_thread: - em = discord.Embed( - title="Error", - description=f"{u.mention} is already in a thread: {curr_thread.channel.mention}.", - color=self.bot.error_color, - ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - return + elif isinstance(u, discord.Role): + users += u.members + elif isinstance(u, discord.Member): + users.append(u) + + for u in users: + # u is a discord.Member + curr_thread = await self.bot.threads.find(recipient=u) + if curr_thread == ctx.thread: + users.remove(u) + continue + + if curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is already in a thread: {curr_thread.channel.mention}.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + + if not users: + em = discord.Embed( + title="Error", + description="All users are already in the thread.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + if not silent: + description = self.bot.formatter.format( + self.bot.config["private_added_to_group_description"], moderator=ctx.author + ) em = discord.Embed( title=self.bot.config["private_added_to_group_title"], - description=self.bot.config["private_added_to_group_description"].format( - moderator=ctx.author - ), + description=description, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -712,11 +733,14 @@ async def adduser(self, ctx, *users: Union[discord.Member, str]): for u in users: await u.send(embed=em) + description = self.bot.formatter.format( + self.bot.config["public_added_to_group_description"], + moderator=ctx.author, + users=", ".join(u.name for u in users), + ) em = discord.Embed( title=self.bot.config["public_added_to_group_title"], - description=self.bot.config["private_added_to_group_description"].format( - moderator=ctx.author, users=", ".join(u.name for u in users) - ), + description=description, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -731,49 +755,55 @@ async def adduser(self, ctx, *users: Union[discord.Member, str]): sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.command(usage=" [options]", cooldown_after_parsing=True) + @commands.command(usage=" [options]", cooldown_after_parsing=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @commands.cooldown(1, 600, BucketType.channel) - async def removeuser(self, ctx, *users: Union[discord.Member, str]): + async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str]): """Removes a user from a modmail thread `options` can be `silent` or `silently`. """ silent = False - for u in users: + users = [] + for u in users_arg: if isinstance(u, str): if "silent" in u or "silently" in u: silent = True - users.remove(u) # remove all strings so users is a List[Member] - else: - # u is a discord.Member - curr_thread = await self.bot.threads.find(recipient=u) - if ctx.thread != curr_thread: - em = discord.Embed( - title="Error", - description=f"{u.mention} is not in this thread.", - color=self.bot.error_color, - ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - return - elif ctx.thread.recipient == u: - em = discord.Embed( - title="Error", - description=f"{u.mention} is the main recipient of the thread and cannot be removed.", - color=self.bot.error_color, - ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - return + elif isinstance(u, discord.Role): + users += u.members + elif isinstance(u, discord.Member): + users.append(u) + + for u in users: + # u is a discord.Member + curr_thread = await self.bot.threads.find(recipient=u) + if ctx.thread != curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is not in this thread.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + elif ctx.thread.recipient == u: + em = discord.Embed( + title="Error", + description=f"{u.mention} is the main recipient of the thread and cannot be removed.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return if not silent: + description = self.bot.formatter.format( + self.bot.config["private_removed_from_group_description"], moderator=ctx.author + ) em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description"].format( - moderator=ctx.author - ), + description=description, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -782,11 +812,14 @@ async def removeuser(self, ctx, *users: Union[discord.Member, str]): for u in users: await u.send(embed=em) + description = self.bot.formatter.format( + self.bot.config["public_removed_from_group_description"], + moderator=ctx.author, + users=", ".join(u.name for u in users), + ) em = discord.Embed( title=self.bot.config["public_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description"].format( - moderator=ctx.author, users=", ".join(u.name for u in users) - ), + description=description, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -801,33 +834,52 @@ async def removeuser(self, ctx, *users: Union[discord.Member, str]): sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.command(usage=" [options]", cooldown_after_parsing=True) + @commands.command(usage=" [options]", cooldown_after_parsing=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @commands.cooldown(1, 600, BucketType.channel) - async def anonadduser(self, ctx, *users: Union[discord.Member, str]): + async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str]): """Adds a user to a modmail thread anonymously `options` can be `silent` or `silently`. """ silent = False - for u in users: + users = [] + for u in users_arg: if isinstance(u, str): if "silent" in u or "silently" in u: silent = True - users.remove(u) # remove all strings so users is a List[Member] - else: - # u is a discord.Member - curr_thread = await self.bot.threads.find(recipient=u) - if curr_thread: - em = discord.Embed( - title="Error", - description=f"{u.mention} is already in a thread: {curr_thread.channel.mention}.", - color=self.bot.error_color, - ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - return + elif isinstance(u, discord.Role): + users += u.members + elif isinstance(u, discord.Member): + users.append(u) + + for u in users: + curr_thread = await self.bot.threads.find(recipient=u) + if curr_thread == ctx.thread: + users.remove(u) + continue + + if curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is already in a thread: {curr_thread.channel.mention}.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + + if not users: + em = discord.Embed( + title="Error", + description="All users are already in the thread.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + if not silent: em = discord.Embed( title=self.bot.config["private_added_to_group_title"], @@ -851,11 +903,13 @@ async def anonadduser(self, ctx, *users: Union[discord.Member, str]): for u in users: await u.send(embed=em) + description = self.bot.formatter.format( + self.bot.config["public_added_to_group_description_anon"], + users=", ".join(u.name for u in users), + ) em = discord.Embed( title=self.bot.config["public_added_to_group_title"], - description=self.bot.config["private_added_to_group_description_anon"].format( - moderator=ctx.author, users=", ".join(u.name for u in users) - ), + description=description, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -870,49 +924,51 @@ async def anonadduser(self, ctx, *users: Union[discord.Member, str]): sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) - @commands.command(usage=" [options]", cooldown_after_parsing=True) + @commands.command(usage=" [options]", cooldown_after_parsing=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() @commands.cooldown(1, 600, BucketType.channel) - async def anonremoveuser(self, ctx, *users: Union[discord.Member, str]): + async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str]): """Removes a user from a modmail thread anonymously `options` can be `silent` or `silently`. """ silent = False - for u in users: + users = [] + for u in users_arg: if isinstance(u, str): if "silent" in u or "silently" in u: silent = True - users.remove(u) # remove all strings so users is a List[Member] - else: - # u is a discord.Member - curr_thread = await self.bot.threads.find(recipient=u) - if ctx.thread != curr_thread: - em = discord.Embed( - title="Error", - description=f"{u.mention} is not in this thread.", - color=self.bot.error_color, - ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - return - elif ctx.thread.recipient == u: - em = discord.Embed( - title="Error", - description=f"{u.mention} is the main recipient of the thread and cannot be removed.", - color=self.bot.error_color, - ) - await ctx.send(embed=em) - ctx.command.reset_cooldown(ctx) - return + elif isinstance(u, discord.Role): + users += u.members + elif isinstance(u, discord.Member): + users.append(u) + + for u in users: + curr_thread = await self.bot.threads.find(recipient=u) + if ctx.thread != curr_thread: + em = discord.Embed( + title="Error", + description=f"{u.mention} is not in this thread.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + elif ctx.thread.recipient == u: + em = discord.Embed( + title="Error", + description=f"{u.mention} is the main recipient of the thread and cannot be removed.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return if not silent: em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description_anon"].format( - moderator=ctx.author - ), + description=self.bot.config["private_removed_from_group_description_anon"], color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: @@ -932,11 +988,13 @@ async def anonremoveuser(self, ctx, *users: Union[discord.Member, str]): for u in users: await u.send(embed=em) + description = self.bot.formatter.format( + self.bot.config["public_removed_from_group_description_anon"], + users=", ".join(u.name for u in users), + ) em = discord.Embed( title=self.bot.config["public_removed_from_group_title"], - description=self.bot.config["private_removed_from_group_description"].format( - moderator=ctx.author, users=", ".join(u.name for u in users) - ), + description=description, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: From 835390b80c8f4a36bd19aa77d19370b899f5c8b6 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 21:53:04 +0800 Subject: [PATCH 404/705] Remove tagging and case insensitive plugins --- plugins/registry.json | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 0ba98f499c..a805360b57 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1,13 +1,4 @@ { - "case_insensitive_snippets": { - "repository": "python-discord/modmail-plugins", - "branch": "main", - "description": "Allow snippets to be ran even if with the wrong case. For example, ?Dm-RePort will be recognized as ?dm-report.", - "bot_version": "2.20.1", - "title": "Case insensitive snippets", - "icon_url": "https://i.imgur.com/kaJYlMB.png", - "thumbnail_url": "https://i.imgur.com/kaJYlMB.png" - }, "close_message": { "repository": "python-discord/modmail-plugins", "branch": "main", @@ -35,15 +26,6 @@ "icon_url": "https://i.imgur.com/FtRQveT.png", "thumbnail_url": "https://i.imgur.com/FtRQveT.png" }, - "tagging": { - "repository": "python-discord/modmail-plugins", - "branch": "main", - "description": "Add a ?tag command capable of adding a $message| header to the channel name.", - "bot_version": "2.20.1", - "title": "Tagging", - "icon_url": "https://i.imgur.com/WajSLB1.png", - "thumbnail_url": "https://i.imgur.com/WajSLB1.png" - }, "dragory-migrate": { "repository": "kyb3r/modmail-plugins", "branch": "master", From fe11759e5b3e11dc5f7623904a7a98c5e6d61d09 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 6 Aug 2021 21:54:28 +0800 Subject: [PATCH 405/705] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d398e71f2f..28e5151b07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ v3.10 adds group conversations while resolving othre bugs and QOL changes. It is - `?contact` now works properly with both category and silent. ([GH #3076](https://github.com/kyb3r/modmail/issues/3076)) - `close_on_leave_reason` now works properly when `close_on_leave` is enabled. ([GH #3075](https://github.com/kyb3r/modmail/issues/3075)) - Invalid arguments are now properly catched and a proper error message is sent. +- Update database after resetting/purging all plugins. ([GH #3011](https://github.com/kyb3r/modmail/pull/3011)) ## Internal From 1a885bc56ef82e87fdec72ed540e3fb021567069 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:14:32 +0800 Subject: [PATCH 406/705] Use highest hoisted role as default tag, resolves #3014 --- CHANGELOG.md | 3 ++- README.md | 2 +- bot.py | 2 +- cogs/modmail.py | 4 ++-- core/thread.py | 5 +++-- core/utils.py | 8 ++++++++ pyproject.toml | 2 +- 7 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28e5151b07..a18c8d8eb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev4 +# v3.10.0-dev5 v3.10 adds group conversations while resolving othre bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. @@ -18,6 +18,7 @@ v3.10 adds group conversations while resolving othre bugs and QOL changes. It is - Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) - Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080)) +- Default tags now use top hoisted role. ([GH #3014](https://github.com/kyb3r/modmail/issues/3014)) ## Fixed diff --git a/README.md b/README.md index 7659898399..42a8f812ec 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 26fac619d2..9a61101707 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "v3.10.0-dev4" +__version__ = "v3.10.0-dev5" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index 74b99dde76..c7be64e046 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -891,7 +891,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, tag = self.bot.config["mod_tag"] if tag is None: - tag = str(ctx.author.top_role) + tag = str(get_top_hoisted_role(ctx.author)) name = self.bot.config["anon_username"] if name is None: name = tag @@ -976,7 +976,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro tag = self.bot.config["mod_tag"] if tag is None: - tag = str(ctx.author.top_role) + tag = str(get_top_hoisted_role(ctx.author)) name = self.bot.config["anon_username"] if name is None: name = tag diff --git a/core/thread.py b/core/thread.py index 91f30417a8..b2adbffe76 100644 --- a/core/thread.py +++ b/core/thread.py @@ -22,6 +22,7 @@ match_other_recipients, truncate, format_channel_name, + get_top_hoisted_role, ) logger = getLogger(__name__) @@ -888,7 +889,7 @@ async def send( # Anonymously sending to the user. tag = self.bot.config["mod_tag"] if tag is None: - tag = str(author.top_role) + tag = str(get_top_hoisted_role(author)) name = self.bot.config["anon_username"] if name is None: name = tag @@ -1005,7 +1006,7 @@ async def send( elif not anonymous: mod_tag = self.bot.config["mod_tag"] if mod_tag is None: - mod_tag = str(message.author.top_role) + mod_tag = str(get_top_hoisted_role(message.author)) embed.set_footer(text=mod_tag) # Normal messages else: embed.set_footer(text=self.bot.config["anon_tag"]) diff --git a/core/utils.py b/core/utils.py index 173eda25d5..8f4e1a01ff 100644 --- a/core/utils.py +++ b/core/utils.py @@ -32,6 +32,7 @@ "escape_code_block", "format_channel_name", "tryint", + "get_top_hoisted_role", ] @@ -394,3 +395,10 @@ def tryint(x): return int(x) except (ValueError, TypeError): return x + + +def get_top_hoisted_role(member: discord.Member): + roles = sorted(member.roles, key=lambda r: r.position, reverse=True) + for role in roles: + if role.hoist: + return role diff --git a/pyproject.toml b/pyproject.toml index e038685a61..1d97e42e33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev4' +version = '3.10.0-dev5' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 3407e0510208a5b509d3f5059ef5f3d6598edc11 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:24:11 +0800 Subject: [PATCH 407/705] Reload thread cache only when it's the first on_ready trigger. Resolves #3037 --- CHANGELOG.md | 1 + bot.py | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a18c8d8eb7..d8768247c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ v3.10 adds group conversations while resolving othre bugs and QOL changes. It is - `thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. Potentially breaking if plugins depend on this behaviour. - Fix return types, type hints, and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) +- Reload thread cache only when it's the first on_ready trigger. ([GH #3037](https://github.com/kyb3r/modmail/issues/3037)) # v3.9.5 diff --git a/bot.py b/bot.py index 9a61101707..8aa3f00d1a 100644 --- a/bot.py +++ b/bot.py @@ -74,6 +74,7 @@ def __init__(self): self.loaded_cogs = ["cogs.modmail", "cogs.plugins", "cogs.utility"] self._connected = asyncio.Event() self.start_time = datetime.utcnow() + self._started = False self.config = ConfigManager(self) self.config.populate_cache() @@ -534,6 +535,13 @@ async def on_ready(self): logger.error("Logging out due to invalid GUILD_ID.") return await self.close() + if self._started: + # Bot has started before + logger.line() + logger.warning("Bot restarted due to internal discord reloading.") + logger.line() + return + logger.line() logger.debug("Client ready.") logger.info("Logged in as: %s", self.user) @@ -634,6 +642,8 @@ async def on_ready(self): ) logger.warning("If the external servers are valid, you may ignore this message.") + self._started = True + async def convert_emoji(self, name: str) -> str: ctx = SimpleNamespace(bot=self, guild=self.modmail_guild) converter = commands.EmojiConverter() From 20b31f8e8b5497943513997fef788d72ae668438 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:48:35 +0800 Subject: [PATCH 408/705] Resolve linked messages issues, improve group functionality (bugfixes), resolves #3041 --- CHANGELOG.md | 1 + bot.py | 17 ++--- core/thread.py | 165 +++++++++++++++++++++++++++++-------------------- core/utils.py | 79 +++++++++++++++++++++-- 4 files changed, 179 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8768247c9..6952839164 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ v3.10 adds group conversations while resolving othre bugs and QOL changes. It is - `close_on_leave_reason` now works properly when `close_on_leave` is enabled. ([GH #3075](https://github.com/kyb3r/modmail/issues/3075)) - Invalid arguments are now properly catched and a proper error message is sent. - Update database after resetting/purging all plugins. ([GH #3011](https://github.com/kyb3r/modmail/pull/3011)) +- `thread_auto_close` timer now only resets on non-note and replies from mods. ([GH #3030](https://github.com/kyb3r/modmail/issues/3030)) ## Internal diff --git a/bot.py b/bot.py index 8aa3f00d1a..b1b4ad046c 100644 --- a/bot.py +++ b/bot.py @@ -1265,7 +1265,7 @@ async def handle_reaction_events(self, payload): if not thread.recipient.dm_channel: await thread.recipient.create_dm() try: - linked_message = await thread.find_linked_message_from_dm(message, either_direction=True) + linked_messages = await thread.find_linked_message_from_dm(message, either_direction=True) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return @@ -1274,19 +1274,19 @@ async def handle_reaction_events(self, payload): if not thread: return try: - _, *linked_message = await thread.find_linked_messages(message.id, either_direction=True) + _, *linked_messages = await thread.find_linked_messages(message.id, either_direction=True) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return - if self.config["transfer_reactions"] and linked_message is not [None]: + if self.config["transfer_reactions"] and linked_messages is not [None]: if payload.event_type == "REACTION_ADD": - for msg in linked_message: + for msg in linked_messages: await self.add_reaction(msg, reaction) await self.add_reaction(message, reaction) else: try: - for msg in linked_message: + for msg in linked_messages: await msg.remove_reaction(reaction, self.user) await message.remove_reaction(reaction, self.user) except (discord.HTTPException, discord.InvalidArgument) as e: @@ -1432,13 +1432,6 @@ async def on_message_delete(self, message): if not thread: return - audit_logs = self.modmail_guild.audit_logs(limit=10, action=discord.AuditLogAction.message_delete) - - entry = await audit_logs.find(lambda a: a.target == self.user) - - if entry is None: - return - try: await thread.delete_message(message, note=False) embed = discord.Embed(description="Successfully deleted message.", color=self.main_color) diff --git a/core/thread.py b/core/thread.py index b2adbffe76..89cdceb903 100644 --- a/core/thread.py +++ b/core/thread.py @@ -21,8 +21,9 @@ match_user_id, match_other_recipients, truncate, - format_channel_name, get_top_hoisted_role, + create_thread_channel, + get_joint_id, ) logger = getLogger(__name__) @@ -36,7 +37,7 @@ def __init__( manager: "ThreadManager", recipient: typing.Union[discord.Member, discord.User, int], channel: typing.Union[discord.DMChannel, discord.TextChannel] = None, - other_recipients: typing.List[typing.Union[discord.Member, discord.User]] = [], + other_recipients: typing.List[typing.Union[discord.Member, discord.User]] = None, ): self.manager = manager self.bot = manager.bot @@ -48,7 +49,7 @@ def __init__( raise CommandError("Recipient cannot be a bot.") self._id = recipient.id self._recipient = recipient - self._other_recipients = other_recipients + self._other_recipients = other_recipients or [] self._channel = channel self.genesis_message = None self._ready_event = asyncio.Event() @@ -127,9 +128,13 @@ async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChann else: recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id) - other_recipients = match_other_recipients(channel.topic) - for n, uid in enumerate(other_recipients): - other_recipients[n] = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid) + other_recipients = [] + for uid in match_other_recipients(channel.topic): + try: + other_recipient = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid) + except discord.NotFound: + continue + other_recipients.append(other_recipient) thread = cls(manager, recipient or recipient_id, channel, other_recipients) @@ -149,33 +154,19 @@ async def setup(self, *, creator=None, category=None, initial_message=None): overwrites = None try: - channel = await self.bot.modmail_guild.create_text_channel( - name=format_channel_name(self.bot, recipient), - category=category, - overwrites=overwrites, - reason="Creating a thread channel.", - ) - except discord.HTTPException as e: - # try again but null-discrim (name could be banned) - try: - channel = await self.bot.modmail_guild.create_text_channel( - name=format_channel_name(self.bot, recipient, force_null=True), - category=category, - overwrites=overwrites, - reason="Creating a thread channel.", - ) - except discord.HTTPException as e: # Failed to create due to missing perms. - logger.critical("An error occurred while creating a thread.", exc_info=True) - self.manager.cache.pop(self.id) + channel = await create_thread_channel(self.bot, recipient, category, overwrites) + except discord.HTTPException as e: # Failed to create due to missing perms. + logger.critical("An error occurred while creating a thread.", exc_info=True) + self.manager.cache.pop(self.id) - embed = discord.Embed(color=self.bot.error_color) - embed.title = "Error while trying to create a thread." - embed.description = str(e) - embed.add_field(name="Recipient", value=recipient.mention) + embed = discord.Embed(color=self.bot.error_color) + embed.title = "Error while trying to create a thread." + embed.description = str(e) + embed.add_field(name="Recipient", value=recipient.mention) - if self.bot.log_channel is not None: - await self.bot.log_channel.send(embed=embed) - return + if self.bot.log_channel is not None: + await self.bot.log_channel.send(embed=embed) + return self._channel = channel @@ -209,7 +200,7 @@ async def send_genesis_message(): logger.error("Failed unexpectedly:", exc_info=True) async def send_recipient_genesis_message(): - # Once thread is ready, tell the recipient. + # Once thread is ready, tell the recipient (don't send if using contact on others) thread_creation_response = self.bot.config["thread_creation_response"] embed = discord.Embed( @@ -585,7 +576,7 @@ async def find_linked_messages( either_direction: bool = False, message1: discord.Message = None, note: bool = True, - ) -> typing.Tuple[discord.Message, typing.Optional[discord.Message]]: + ) -> typing.Tuple[discord.Message, typing.List[typing.Optional[discord.Message]]]: if message1 is not None: if not message1.embeds or not message1.embeds[0].author.url or message1.author != self.bot.user: raise ValueError("Malformed thread message.") @@ -698,49 +689,84 @@ async def delete_message( if tasks: await asyncio.gather(*tasks) - async def find_linked_message_from_dm(self, message, either_direction=False): - if either_direction and message.embeds and message.embeds[0].author.url: - compare_url = message.embeds[0].author.url - compare_id = compare_url.split("#")[-1] - else: - compare_url = None - compare_id = None + async def find_linked_message_from_dm( + self, message, either_direction=False + ) -> typing.List[discord.Message]: + + joint_id = None + if either_direction: + joint_id = get_joint_id(message) + # could be None too, if that's the case we'll reassign this variable from + # thread message we fetch in the next step + linked_messages = [] if self.channel is not None: - async for linked_message in self.channel.history(): - if not linked_message.embeds: + async for msg in self.channel.history(): + if not msg.embeds: continue - url = linked_message.embeds[0].author.url - if not url: - continue - if url == compare_url: - return linked_message - msg_id = url.split("#")[-1] - if not msg_id.isdigit(): + msg_joint_id = get_joint_id(msg) + if msg_joint_id is None: continue - msg_id = int(msg_id) - if int(msg_id) == message.id: - return linked_message - if compare_id is not None and compare_id.isdigit(): - if int(msg_id) == int(compare_id): - return linked_message + if msg_joint_id == message.id: + linked_messages.append(msg) + break + if joint_id is not None and msg_joint_id == joint_id: + linked_messages.append(msg) + break + else: + raise ValueError("Thread channel message not found.") + else: raise ValueError("Thread channel message not found.") + if joint_id is None: + joint_id = get_joint_id(linked_messages[0]) + if joint_id is None: + # still None, supress this and return the thread message + logger.error("Malformed thread message.") + return linked_messages + + for user in self.recipients: + if user.dm_channel == message.channel: + continue + async for other_msg in user.history(): + if either_direction: + if other_msg.id == joint_id: + linked_messages.append(other_msg) + break + + if not other_msg.embeds: + continue + + other_joint_id = get_joint_id(other_msg) + if other_joint_id is not None and other_joint_id == joint_id: + linked_messages.append(other_msg) + break + else: + logger.error("Linked message from recipient %s not found.", user) + + return linked_messages + async def edit_dm_message(self, message: discord.Message, content: str) -> None: try: - linked_message = await self.find_linked_message_from_dm(message) + linked_messages = await self.find_linked_message_from_dm(message) except ValueError: logger.warning("Failed to edit message.", exc_info=True) raise - embed = linked_message.embeds[0] - embed.add_field(name="**Edited, former message:**", value=embed.description) - embed.description = content - await asyncio.gather(self.bot.api.edit_message(message.id, content), linked_message.edit(embed=embed)) - async def note(self, message: discord.Message, persistent=False, thread_creation=False) -> None: + for msg in linked_messages: + embed = msg.embeds[0] + if isinstance(msg.channel, discord.TextChannel): + # just for thread channel, we put the old message in embed field + embed.add_field(name="**Edited, former message:**", value=embed.description) + embed.description = content + await asyncio.gather(self.bot.api.edit_message(message.id, content), msg.edit(embed=embed)) + + async def note( + self, message: discord.Message, persistent=False, thread_creation=False + ) -> discord.Message: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) @@ -758,7 +784,9 @@ async def note(self, message: discord.Message, persistent=False, thread_creation return msg - async def reply(self, message: discord.Message, anonymous: bool = False, plain: bool = False) -> None: + async def reply( + self, message: discord.Message, anonymous: bool = False, plain: bool = False + ) -> typing.Tuple[discord.Message, discord.Message]: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): @@ -854,7 +882,8 @@ async def send( thread_creation: bool = False, ) -> None: - self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close + if not note and from_mod: + self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close if self.close_task is not None: # cancel closing if a thread message is sent. @@ -1208,9 +1237,13 @@ async def _find_from_channel(self, channel): except discord.NotFound: recipient = None - other_recipients = match_other_recipients(channel.topic) - for n, uid in enumerate(other_recipients): - other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + other_recipients = [] + for uid in match_other_recipients(channel.topic): + try: + other_recipient = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + except discord.NotFound: + continue + other_recipients.append(other_recipient) if recipient is None: thread = Thread(self, user_id, channel, other_recipients) diff --git a/core/utils.py b/core/utils.py index 8f4e1a01ff..3b75e11014 100644 --- a/core/utils.py +++ b/core/utils.py @@ -33,6 +33,7 @@ "format_channel_name", "tryint", "get_top_hoisted_role", + "get_joint_id", ] @@ -224,7 +225,7 @@ def cleanup_code(content: str) -> str: TOPIC_UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) -def match_title(text: str) -> int: +def match_title(text: str) -> str: """ Matches a title in the format of "Title: XXXX" @@ -236,7 +237,7 @@ def match_title(text: str) -> int: Returns ------- Optional[str] - The title if found + The title if found. """ match = TOPIC_TITLE_REGEX.search(text) if match is not None: @@ -263,7 +264,7 @@ def match_user_id(text: str) -> int: return -1 -def match_other_recipients(text: str) -> int: +def match_other_recipients(text: str) -> typing.List[int]: """ Matches a title in the format of "Other Recipients: XXXX,XXXX" @@ -274,8 +275,8 @@ def match_other_recipients(text: str) -> int: Returns ------- - Optional[str] - The title if found + List[int] + The list of other recipients IDs. """ match = TOPIC_OTHER_RECIPIENTS_REGEX.search(text) if match is not None: @@ -402,3 +403,71 @@ def get_top_hoisted_role(member: discord.Member): for role in roles: if role.hoist: return role + + +async def create_thread_channel(bot, recipient, category, overwrites, *, name=None, errors_raised=[]): + name = name or format_channel_name(bot, recipient) + try: + channel = await bot.modmail_guild.create_text_channel( + name=name, + category=category, + overwrites=overwrites, + reason="Creating a thread channel.", + ) + except discord.HTTPException as e: + if (e.text, (category, name)) in errors_raised: + # Just raise the error to prevent infinite recursion after retrying + raise + + errors_raised.append((e.text, (category, name))) + + if "Maximum number of channels in category reached" in e.text: + fallback_id = bot.config["fallback_category_id"] + if fallback_id: + fallback = discord.utils.get(cat.guild.categories, id=int(fallback_id)) + if fallback and len(fallback.channels) < 49: + category = fallback + + if not category: + category = await category.clone(name="Fallback Modmail") + bot.config.set("fallback_category_id", str(category.id)) + await bot.config.update() + + return await create_thread_channel( + bot, recipient, category, overwrites, errors_raised=errors_raised + ) + + if "Contains words not allowed" in e.text: + # try again but null-discrim (name could be banned) + return await create_thread_channel( + bot, + recipient, + category, + overwrites, + name=format_channel_name(bot, recipient, force_null=True), + errors_raised=errors_raised, + ) + + raise + + return channel + + +def get_joint_id(message: discord.Message) -> typing.Optional[int]: + """ + Get the joint ID from `discord.Embed().author.url`. + Parameters + ----------- + message : discord.Message + The discord.Message object. + Returns + ------- + int + The joint ID if found. Otherwise, None. + """ + if message.embeds: + try: + return int(getattr(message.embeds[0].author, "url", "").split("#")[-1]) + except ValueError: + pass + return None From ddbee35bc15e858e5b22e622f86ea6b9ea639213 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 21:23:24 +0800 Subject: [PATCH 409/705] Persistent notes are now properly deleted,resolve #3013 --- CHANGELOG.md | 2 ++ core/thread.py | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6952839164..e7dc84c3d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ v3.10 adds group conversations while resolving othre bugs and QOL changes. It is - Invalid arguments are now properly catched and a proper error message is sent. - Update database after resetting/purging all plugins. ([GH #3011](https://github.com/kyb3r/modmail/pull/3011)) - `thread_auto_close` timer now only resets on non-note and replies from mods. ([GH #3030](https://github.com/kyb3r/modmail/issues/3030)) +- Deleted messages are now deleted on both ends. ([GH #3041](https://github.com/kyb3r/modmail/issues/3041), [@JerrieAries](https://github.com/kyb3r/modmail/commit/20b31f8e8b5497943513997fef788d72ae668438)) +- Persistent notes are now properly deleted from the database. ([GH #3013](https://github.com/kyb3r/modmail/issues/3013)) ## Internal diff --git a/core/thread.py b/core/thread.py index 89cdceb903..b34e14ed01 100644 --- a/core/thread.py +++ b/core/thread.py @@ -679,13 +679,17 @@ async def delete_message( else: message1, *message2 = await self.find_linked_messages(message, note=note) tasks = [] + if not isinstance(message, discord.Message): tasks += [message1.delete()] - elif message2 is not [None]: - for m2 in message2: + + for m2 in message2: + if m2 is not None: tasks += [m2.delete()] - elif message1.embeds[0].author.name.startswith("Persistent Note"): + + if message1.embeds[0].author.name.startswith("Persistent Note"): tasks += [self.bot.api.delete_note(message1.id)] + if tasks: await asyncio.gather(*tasks) From a71c1c79fa183be387dbe3cea274fa327ab89e35 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 21:32:24 +0800 Subject: [PATCH 410/705] Fix changelog formatting --- CHANGELOG.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7dc84c3d1..1ba3fd326b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,19 +8,20 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v3.10.0-dev5 -v3.10 adds group conversations while resolving othre bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. +v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. -## Breaking +### Breaking - `Thread.recipient` (`str`) is now `Thread.recipients` (`List[str]`). +- `thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. -## Added +### Added - Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) - Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080)) - Default tags now use top hoisted role. ([GH #3014](https://github.com/kyb3r/modmail/issues/3014)) -## Fixed +### Fixed - Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) - Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/kyb3r/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/kyb3r/modmail/pull/3027)) @@ -34,15 +35,14 @@ v3.10 adds group conversations while resolving othre bugs and QOL changes. It is - Deleted messages are now deleted on both ends. ([GH #3041](https://github.com/kyb3r/modmail/issues/3041), [@JerrieAries](https://github.com/kyb3r/modmail/commit/20b31f8e8b5497943513997fef788d72ae668438)) - Persistent notes are now properly deleted from the database. ([GH #3013](https://github.com/kyb3r/modmail/issues/3013)) -## Internal - -- `thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. Potentially breaking if plugins depend on this behaviour. -- Fix return types, type hints, and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) +### Internal +def c +- Fix return types, type hints and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) - Reload thread cache only when it's the first on_ready trigger. ([GH #3037](https://github.com/kyb3r/modmail/issues/3037)) # v3.9.5 -## Internal +### Internal - Bumped discord.py to v1.7.3, updated all other packages to latest. - More debug log files are now kept. @@ -50,28 +50,28 @@ v3.10 adds group conversations while resolving othre bugs and QOL changes. It is # v3.9.4 -## Fixed +### Fixed - Certain cases where fallback categories were not working as intended. ([GH #3002](https://github.com/kyb3r/modmail/issues/3002), [PR #3003](https://github.com/kyb3r/modmail/pull/3003)) - There is now a proper message when trying to contact a bot. -## Improved +### Improved - `?mention` can now be disabled with `?mention disable`. ([PR #2993](https://github.com/kyb3r/modmail/pull/2993/files)) - `?mention` now allows vague entries such as `everyone` or `all`. ([PR #2993](https://github.com/kyb3r/modmail/pull/2993/files)) -## Internal +### Internal - Change heroku python version to 3.9.4 ([PR #3001](https://github.com/kyb3r/modmail/pull/3001)) # v3.9.3 -## Added +### Added - New config: `use_user_id_channel_name`, when set to TRUE, channel names would get created with the recipient's ID instead of their name and discriminator. - This is now an option to better suit the needs of servers in Server Discovery -## Internal +### Internal - Signature of `format_channel_name` in core/util.py changed to: - `format_channel_name(bot, author, exclude_channel=None, force_null=False)` From 476994a7cb22c586dc2d44ef85b1d2ac36446eb4 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 21:33:54 +0800 Subject: [PATCH 411/705] Fix changelog formatting --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ba3fd326b..cfdb98fce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,6 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is - Persistent notes are now properly deleted from the database. ([GH #3013](https://github.com/kyb3r/modmail/issues/3013)) ### Internal -def c - Fix return types, type hints and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) - Reload thread cache only when it's the first on_ready trigger. ([GH #3037](https://github.com/kyb3r/modmail/issues/3037)) From 68ede9d5d41448a76666ca47ffd816fa83f3fc2d Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 21:34:03 +0800 Subject: [PATCH 412/705] Fix changelog formatting --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfdb98fce3..5cfaddb926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is - Persistent notes are now properly deleted from the database. ([GH #3013](https://github.com/kyb3r/modmail/issues/3013)) ### Internal + - Fix return types, type hints and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) - Reload thread cache only when it's the first on_ready trigger. ([GH #3037](https://github.com/kyb3r/modmail/issues/3037)) From daf04b053be29b615b783e92992ec16dc5df2297 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 22:06:50 +0800 Subject: [PATCH 413/705] New thread related config, resolves #3072 --- CHANGELOG.md | 3 +- README.md | 2 +- bot.py | 2 +- cogs/modmail.py | 16 +++++---- core/config.py | 15 +++++--- core/config_help.json | 79 ++++++++++++++++++++++++++++++++++++++++--- core/thread.py | 31 ++++++++++------- pyproject.toml | 2 +- 8 files changed, 119 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cfaddb926..93ee687cf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev5 +# v3.10.0-dev6 v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. @@ -20,6 +20,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is - Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) - Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080)) - Default tags now use top hoisted role. ([GH #3014](https://github.com/kyb3r/modmail/issues/3014)) +- New thread-related config - `thread_show_roles`, `thread_show_account_age`, `thread_show_join_age`, `thread_cancelled`, `thread_creation_contact_title`, `thread_creation_self_contact_response`, `thread_creation_contact_response`. ([GH #3072](https://github.com/kyb3r/modmail/issues/3072)) ### Fixed diff --git a/README.md b/README.md index 42a8f812ec..2751e10fe0 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index b1b4ad046c..dd7dbd32f0 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "v3.10.0-dev5" +__version__ = "v3.10.0-dev6" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index c7be64e046..5e9813423c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -720,7 +720,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str if not silent: description = self.bot.formatter.format( - self.bot.config["private_added_to_group_description"], moderator=ctx.author + self.bot.config["private_added_to_group_response"], moderator=ctx.author ) em = discord.Embed( title=self.bot.config["private_added_to_group_title"], @@ -734,7 +734,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str await u.send(embed=em) description = self.bot.formatter.format( - self.bot.config["public_added_to_group_description"], + self.bot.config["public_added_to_group_response"], moderator=ctx.author, users=", ".join(u.name for u in users), ) @@ -799,7 +799,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, if not silent: description = self.bot.formatter.format( - self.bot.config["private_removed_from_group_description"], moderator=ctx.author + self.bot.config["private_removed_from_group_response"], moderator=ctx.author ) em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], @@ -813,7 +813,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, await u.send(embed=em) description = self.bot.formatter.format( - self.bot.config["public_removed_from_group_description"], + self.bot.config["public_removed_from_group_response"], moderator=ctx.author, users=", ".join(u.name for u in users), ) @@ -1385,12 +1385,14 @@ async def contact( if not silent and not self.bot.config.get("thread_contact_silently"): if creator.id == user.id: - description = "You have opened a Modmail thread." + description = self.bot.config["thread_creation_self_contact_response"] else: - description = f"{creator.name} has opened a Modmail thread." + description = self.bot.formatter.format( + self.bot.config["thread_creation_contact_response"], creator=creator + ) em = discord.Embed( - title="New Thread", + title=self.bot.config["thread_creation_contact_title"], description=description, color=self.bot.main_color, ) diff --git a/core/config.py b/core/config.py index 829ce7ff3b..cb350b0b76 100644 --- a/core/config.py +++ b/core/config.py @@ -52,6 +52,10 @@ class ConfigManager: "close_emoji": "\N{LOCK}", "use_user_id_channel_name": False, "recipient_thread_close": False, + "thread_show_roles": True, + "thread_show_account_age": True, + "thread_show_join_age": True, + "thread_cancelled": "Cancelled", "thread_auto_close_silently": False, "thread_auto_close": isodate.Duration(), "thread_auto_close_response": "This thread has been closed automatically due to inactivity after {timeout}.", @@ -59,6 +63,9 @@ class ConfigManager: "thread_creation_footer": "Your message has been sent", "thread_contact_silently": False, "thread_self_closable_creation_footer": "Click the lock to close the thread", + "thread_creation_contact_title": "New Thread", + "thread_creation_self_contact_response": "You have opened a Modmail thread.", + "thread_creation_contact_response": "{creator.name} has opened a Modmail thread.", "thread_creation_title": "Thread Created", "thread_close_footer": "Replying will create a new thread", "thread_close_title": "Thread Closed", @@ -85,16 +92,16 @@ class ConfigManager: "anonymous_snippets": False, # group conversations "private_added_to_group_title": "New Thread (Group)", - "private_added_to_group_description": "{moderator.name} has added you to a Modmail thread.", + "private_added_to_group_response": "{moderator.name} has added you to a Modmail thread.", "private_added_to_group_description_anon": "A moderator has added you to a Modmail thread.", "public_added_to_group_title": "New User", - "public_added_to_group_description": "{moderator.name} has added {users} to the Modmail thread.", + "public_added_to_group_response": "{moderator.name} has added {users} to the Modmail thread.", "public_added_to_group_description_anon": "A moderator has added {users} to the Modmail thread.", "private_removed_from_group_title": "Removed From Thread (Group)", - "private_removed_from_group_description": "{moderator.name} has removed you from the Modmail thread.", + "private_removed_from_group_response": "{moderator.name} has removed you from the Modmail thread.", "private_removed_from_group_description_anon": "A moderator has removed you from the Modmail thread.", "public_removed_from_group_title": "User Removed", - "public_removed_from_group_description": "{moderator.name} has removed {users} from the Modmail thread.", + "public_removed_from_group_response": "{moderator.name} has removed {users} from the Modmail thread.", "public_removed_from_group_description_anon": "A moderator has removed {users} from the Modmail thread.", # moderation "recipient_color": str(discord.Color.gold()), diff --git a/core/config_help.json b/core/config_help.json index d6a4627d96..a679ba1c7c 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -266,6 +266,36 @@ "See also: `close_emoji`." ] }, + "thread_show_roles": { + "default": "Yes", + "description": "Shows roles on first message sent in thread channels to mods", + "examples":[ + "`{prefix}config set thread_show_roles no`" + ], + "notes": [ + "See also: `thread_show_account_age`, `thread_show_join_age`." + ] + }, + "thread_show_account_age": { + "default": "Yes", + "description": "Shows account age on first message sent in thread channels to mods", + "examples":[ + "`{prefix}config set thread_show_account_age no`" + ], + "notes": [ + "See also: `thread_show_roles`, `thread_show_join_age`." + ] + }, + "thread_show_join_age": { + "default": "Yes", + "description": "Shows join age on first message sent in thread channels to mods", + "examples":[ + "`{prefix}config set thread_show_join_age no`" + ], + "notes": [ + "See also: `thread_show_account_age`, `thread_show_roles`." + ] + }, "thread_auto_close_silently": { "default": "No", "description": "Setting this configuration will close silently when the thread auto-closes.", @@ -302,6 +332,14 @@ "To disable thread cooldown, do `{prefix}config del thread_cooldown`." ] }, + "thread_cancelled": { + "default": "\"Cancelled\"", + "description": "This is the message to display when a thread times out and creation is cancelled.", + "examples": [ + "`{prefix}config set thread_cancelled Gone.`" + ], + "notes": [] + }, "thread_auto_close_response": { "default": "\"This thread has been closed automatically due to inactivity after {{timeout}}.\"", "description": "This is the message to display when the thread when the thread auto-closes.", @@ -359,6 +397,39 @@ "See also: `thread_creation_title`, `thread_creation_response`, `thread_creation_footer`." ] }, + "thread_creation_contact_title": { + "default": "\"New Thread\"", + "description": "This is the message embed title sent to recipients when contacted.", + "examples": [ + "`{prefix}config set thread_creation_contact_title New Message!`" + ], + "notes": [ + "See also: `thread_creation_self_contact_response`, `thread_creation_contact_response`." + ] + }, + "thread_creation_self_contact_response": { + "default": "\"You have opened a Modmail thread.\"", + "description": "This is the message embed description sent to recipients when self-contacted.", + "examples": [ + "`{prefix}config set thread_creation_contact_title You contacted yourself.`" + ], + "notes": [ + "`thread_creation_contact_response` is used when contacted by another user.", + "See also: `thread_creation_contact_title`, `thread_creation_contact_response`." + ] + }, + "thread_creation_contact_response": { + "default": "\"{creator.name} has opened a Modmail thread.\"", + "description": "This is the message embed description sent to recipients when contacted by a mod.", + "examples": [ + "`{prefix}config set thread_creation_contact_response New thread opened.`" + ], + "notes": [ + "You may use the `{{creator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that created the thread.", + "`thread_creation_self_contact_response` is used when contacted by self.", + "See also: `thread_creation_contact_title`, `thread_creation_self_contact_response`." + ] + }, "thread_creation_title": { "default": "\"Thread Created\"", "description": "This is the message embed title sent to the recipient upon the creation of a new thread.", @@ -722,7 +793,7 @@ "See also: `private_added_to_group_description`, `public_added_to_group_title`" ] }, - "private_added_to_group_description": { + "private_added_to_group_response": { "default": "\"{{moderator.name}} has added you to a Modmail thread.\"", "description": "This is the message embed content sent to the recipient that is just added to a thread.", "examples": [ @@ -758,7 +829,7 @@ "See also: `private_added_to_group_title`, `private_added_to_group_title`" ] }, - "public_added_to_group_description": { + "public_added_to_group_response": { "default": "\"{{moderator.name}} has added {{users}} to the Modmail thread.\"", "description": "This is the message embed content sent to all other recipients when someone is added to the thread.", "examples": [ @@ -794,7 +865,7 @@ "See also: `private_removed_from_group_description`, `public_removed_from_group_title`" ] }, - "private_removed_from_group_description": { + "private_removed_from_group_response": { "default": "\"{{moderator.name}} has removed you from the Modmail thread.\"", "description": "This is the message embed content sent to the recipient that is just removed from a thread.", "examples": [ @@ -830,7 +901,7 @@ "See also: `private_removed_from_group_title`, `private_removed_from_group_title`" ] }, - "public_removed_from_group_description": { + "public_removed_from_group_response": { "default": "\"{{moderator.name}} has removed {{users}} from the Modmail thread.\"", "description": "This is the message embed content sent to all other recipients when someone is removed from the thread.", "examples": [ diff --git a/core/thread.py b/core/thread.py index b34e14ed01..a013ed8eff 100644 --- a/core/thread.py +++ b/core/thread.py @@ -286,7 +286,7 @@ def _format_info_embed(self, user, log_url, log_count, color): # key = log_url.split('/')[-1] role_names = "" - if member is not None: + if member is not None and self.bot.config["thread_show_roles"]: sep_server = self.bot.using_multiple_server_setup separator = ", " if sep_server else " " @@ -309,13 +309,11 @@ def _format_info_embed(self, user, log_url, log_count, color): role_names = separator.join(roles) created = str((time - user.created_at).days) - embed = discord.Embed( - color=color, description=f"{user.mention} was created {days(created)}", timestamp=time - ) + user_info = [] + if self.bot.config["thread_show_account_age"]: + user_info.append(f"was created {days(created)}") - # if not role_names: - # embed.add_field(name='Mention', value=user.mention) - # embed.add_field(name='Registered', value=created + days(created)) + embed = discord.Embed(color=color, description=user.mention, timestamp=time) if user.dm_channel: footer = f"User ID: {user.id} • DM ID: {user.dm_channel.id}" @@ -328,7 +326,8 @@ def _format_info_embed(self, user, log_url, log_count, color): if member is not None: joined = str((time - member.joined_at).days) # embed.add_field(name='Joined', value=joined + days(joined)) - embed.description += f", joined {days(joined)}" + if self.bot.config["thread_show_join_age"]: + user_info.append(f"joined {days(joined)}") if member.nick: embed.add_field(name="Nickname", value=member.nick, inline=True) @@ -338,10 +337,12 @@ def _format_info_embed(self, user, log_url, log_count, color): else: embed.set_footer(text=f"{footer} • (not in main server)") + embed.description += ", ".join(user_info) + if log_count is not None: - # embed.add_field(name="Past logs", value=f"{log_count}") + connector = "with" if user_info else "has" thread = "thread" if log_count == 1 else "threads" - embed.description += f" with **{log_count or 'no'}** past {thread}." + embed.description += f" {connector} **{log_count or 'no'}** past {thread}." else: embed.description += "." @@ -1336,7 +1337,9 @@ async def create( self.bot.loop.create_task( destination.send( embed=discord.Embed( - title="Cancelled", description="Timed out", color=self.bot.error_color + title=self.bot.config["thread_cancelled"], + description="Timed out", + color=self.bot.error_color, ) ) ) @@ -1344,7 +1347,11 @@ async def create( if str(r.emoji) == deny_emoji: thread.cancelled = True self.bot.loop.create_task( - destination.send(embed=discord.Embed(title="Cancelled", color=self.bot.error_color)) + destination.send( + embed=discord.Embed( + title=self.bot.config["thread_cancelled"], color=self.bot.error_color + ) + ) ) async def remove_reactions(): diff --git a/pyproject.toml b/pyproject.toml index 1d97e42e33..20e1a16ac4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev5' +version = '3.10.0-dev6' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 145788e5e46a909f3c0e4224dce1ba3c89c16c11 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 22:11:54 +0800 Subject: [PATCH 414/705] Resolve issues with deleting messages --- bot.py | 3 ++- core/thread.py | 6 +++++- core/utils.py | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index dd7dbd32f0..33508e5eab 100644 --- a/bot.py +++ b/bot.py @@ -1415,11 +1415,12 @@ async def on_message_delete(self, message): if not thread: return try: - message = await thread.find_linked_message_from_dm(message) + message = await thread.find_linked_message_from_dm(message, get_thread_channel=True) except ValueError as e: if str(e) != "Thread channel message not found.": logger.debug("Failed to find linked message to delete: %s", e) return + message = message[0] embed = message.embeds[0] embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=embed.footer.icon_url) await message.edit(embed=embed) diff --git a/core/thread.py b/core/thread.py index a013ed8eff..700654e314 100644 --- a/core/thread.py +++ b/core/thread.py @@ -695,7 +695,7 @@ async def delete_message( await asyncio.gather(*tasks) async def find_linked_message_from_dm( - self, message, either_direction=False + self, message, either_direction=False, get_thread_channel=False ) -> typing.List[discord.Message]: joint_id = None @@ -726,6 +726,10 @@ async def find_linked_message_from_dm( else: raise ValueError("Thread channel message not found.") + if get_thread_channel: + # end early as we only want the main message from thread channel + return linked_messages + if joint_id is None: joint_id = get_joint_id(linked_messages[0]) if joint_id is None: diff --git a/core/utils.py b/core/utils.py index 3b75e11014..30948f1b0a 100644 --- a/core/utils.py +++ b/core/utils.py @@ -467,7 +467,9 @@ def get_joint_id(message: discord.Message) -> typing.Optional[int]: """ if message.embeds: try: - return int(getattr(message.embeds[0].author, "url", "").split("#")[-1]) + url = getattr(message.embeds[0].author, "url", "") + if url: + return int(url.split("#")[-1]) except ValueError: pass return None From 93432988e7fc0cdbcc4489dcf7ef1d0e2514ac06 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 22:20:06 +0800 Subject: [PATCH 415/705] use_timestamp_channel_name config --- core/config.py | 6 ++++++ core/utils.py | 3 +++ 2 files changed, 9 insertions(+) diff --git a/core/config.py b/core/config.py index cb350b0b76..d8593a02ef 100644 --- a/core/config.py +++ b/core/config.py @@ -51,6 +51,7 @@ class ConfigManager: "blocked_emoji": "\N{NO ENTRY SIGN}", "close_emoji": "\N{LOCK}", "use_user_id_channel_name": False, + "use_timestamp_channel_name": False, "recipient_thread_close": False, "thread_show_roles": True, "thread_show_account_age": True, @@ -179,6 +180,7 @@ class ConfigManager: booleans = { "use_user_id_channel_name", + "use_timestamp_channel_name", "user_typing", "mod_typing", "reply_without_command", @@ -203,6 +205,10 @@ class ConfigManager: "update_notifications", "thread_contact_silently", "anonymous_snippets", + "recipient_thread_close", + "thread_show_roles", + "thread_show_account_age", + "thread_show_join_age", } enums = { diff --git a/core/utils.py b/core/utils.py index 30948f1b0a..5ae1977f6e 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,4 +1,5 @@ import base64 +from datetime import datetime import functools import re import string @@ -373,6 +374,8 @@ def format_channel_name(bot, author, exclude_channel=None, force_null=False): else: if bot.config["use_user_id_channel_name"]: name = new_name = str(author.id) + elif bot.config["use_timestamp_channel_name"]: + name = new_name = datetime.utcnow().isoformat(sep='-', timesep='minutes') else: name = author.name.lower() if force_null: From 0ebf364a8350a64c60be3994601d87fa9945dafc Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 22:20:17 +0800 Subject: [PATCH 416/705] formatting --- core/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/utils.py b/core/utils.py index 5ae1977f6e..cf5aac5ec2 100644 --- a/core/utils.py +++ b/core/utils.py @@ -375,7 +375,7 @@ def format_channel_name(bot, author, exclude_channel=None, force_null=False): if bot.config["use_user_id_channel_name"]: name = new_name = str(author.id) elif bot.config["use_timestamp_channel_name"]: - name = new_name = datetime.utcnow().isoformat(sep='-', timesep='minutes') + name = new_name = datetime.utcnow().isoformat(sep="-", timesep="minutes") else: name = author.name.lower() if force_null: From fcc3fad65c411c5d012b19c4741695de51af354a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 7 Aug 2021 22:27:16 +0800 Subject: [PATCH 417/705] add documentation and fix timestamp related bugs --- CHANGELOG.md | 1 + core/config_help.json | 17 ++++++++++++++++- core/utils.py | 3 +-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93ee687cf6..1febcceb03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is - Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080)) - Default tags now use top hoisted role. ([GH #3014](https://github.com/kyb3r/modmail/issues/3014)) - New thread-related config - `thread_show_roles`, `thread_show_account_age`, `thread_show_join_age`, `thread_cancelled`, `thread_creation_contact_title`, `thread_creation_self_contact_response`, `thread_creation_contact_response`. ([GH #3072](https://github.com/kyb3r/modmail/issues/3072)) +- `use_timestamp_channel_name` config to create thread channels by timestamp. ### Fixed diff --git a/core/config_help.json b/core/config_help.json index a679ba1c7c..1a57d3a3e8 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -105,7 +105,22 @@ "`{prefix}config set use_user_id_channel_name no`" ], "notes": [ - "This config is suitable for servers in Server Discovery to comply with channel name restrictions." + "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", + "This cannot be applied with `use_timestamp_channel_name`.", + "See also: `use_timestamp_channel_name`." + ] + }, + "use_timestamp_channel_name": { + "default": "No", + "description": "When this is set to `yes`, new thread channels will be named with the recipient's account creation date instead of the recipient's name.", + "examples": [ + "`{prefix}config set use_timestamp_channel_name yes`", + "`{prefix}config set use_timestamp_channel_name no`" + ], + "notes": [ + "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", + "This cannot be applied with `use_user_id_channel_name`.", + "See also: `use_user_id_channel_name`." ] }, "mod_typing": { diff --git a/core/utils.py b/core/utils.py index cf5aac5ec2..474bc9db4f 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,5 +1,4 @@ import base64 -from datetime import datetime import functools import re import string @@ -375,7 +374,7 @@ def format_channel_name(bot, author, exclude_channel=None, force_null=False): if bot.config["use_user_id_channel_name"]: name = new_name = str(author.id) elif bot.config["use_timestamp_channel_name"]: - name = new_name = datetime.utcnow().isoformat(sep="-", timesep="minutes") + name = new_name = author.created_at.isoformat(sep="-", timespec="minutes") else: name = author.name.lower() if force_null: From 55b311f294bb7570d2b5ae5b77eccea4e0518cd6 Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Sat, 7 Aug 2021 19:44:29 -0700 Subject: [PATCH 418/705] Initial commit --- bot.py | 28 +++++++++++++++++++++++++--- cogs/modmail.py | 3 +++ cogs/utility.py | 18 ++++++++++++++++++ core/thread.py | 1 + 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index 1c4fdd5354..12e28c8571 100644 --- a/bot.py +++ b/bot.py @@ -1010,6 +1010,7 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if trigger: invoker = trigger.lower() + print("looking for auto trigger", trigger, self.auto_triggers[trigger]) alias = self.auto_triggers[trigger] ctxs = [] @@ -1019,24 +1020,45 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if not aliases: logger.warning("Alias %s is invalid as called in autotrigger.", invoker) + print("Aliases", aliases) + for alias in aliases: view = StringView(invoked_prefix + alias) + invoked_with = view.get_word().lower() + invoked_with = invoked_with[1:] + print("Looking for", invoked_with) + found_command = self.all_commands.get(invoked_with) + + # Check for alias + if not found_command: + print("INVOKED WITH", invoked_with) + command_alias = self.aliases.get(invoked_with)[1:-1] + view = StringView(invoked_prefix + command_alias) + split_cmd = command_alias.split(" ") + found_command = self.all_commands.get(split_cmd[0]) + ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) + ctx_.command = found_command + ctx_.invoked_with = invoked_with ctx_.thread = thread discord.utils.find(view.skip_string, await self.get_prefix()) - ctx_.invoked_with = view.get_word().lower() - ctx_.command = self.all_commands.get(ctx_.invoked_with) + + print("Command info:", view, ctx_, ctx_.thread, ctx_.invoked_with, ctx_.command) ctxs += [ctx_] for ctx in ctxs: if ctx.command: + print("Found command") old_checks = copy.copy(ctx.command.checks) + print("Old checks set") ctx.command.checks = [checks.has_permissions(PermissionLevel.INVALID)] - + print("Command checks added, invoking...", ctx) await self.invoke(ctx) ctx.command.checks = old_checks continue + else: + print("unable to find command") async def get_context(self, message, *, cls=commands.Context): """ diff --git a/cogs/modmail.py b/cogs/modmail.py index 0e41b76677..35e80bdf9b 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -818,7 +818,10 @@ async def reply(self, ctx, *, msg: str = ""): Supports attachments and images as well as automatically embedding image URLs. """ + ctx.message.content = msg + print("MSG IS", msg) + print("Sending", ctx.message, msg) async with ctx.typing(): await ctx.thread.reply(ctx.message) diff --git a/cogs/utility.py b/cogs/utility.py index 759b573748..d068b6cc1e 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1750,6 +1750,16 @@ async def autotrigger_add(self, ctx, keyword, *, command): print(self.bot.get_command(" ".join(split_cmd[0:n]))) valid = True break + + print("Split command", split_cmd, "Range", range(1, len(split_cmd) + 1), self.bot.aliases) + + if not valid and self.bot.aliases: + for n in range(1, len(split_cmd) + 1): + print(" ".join(split_cmd[0:n]), self.bot.aliases.get(" ".join(split_cmd[0:n]))) + if self.bot.aliases.get(" ".join(split_cmd[0:n])): + print(self.bot.aliases.get(" ".join(split_cmd[0:n]))) + valid = True + break if valid: self.bot.auto_triggers[keyword] = command @@ -1784,6 +1794,14 @@ async def autotrigger_edit(self, ctx, keyword, *, command): valid = True break + if not valid and self.bot.aliases: + for n in range(1, len(split_cmd) + 1): + print(" ".join(split_cmd[0:n]), self.bot.aliases.get(" ".join(split_cmd[0:n]))) + if self.bot.aliases.get(" ".join(split_cmd[0:n])): + print(self.bot.aliases.get(" ".join(split_cmd[0:n]))) + valid = True + break + if valid: self.bot.auto_triggers[keyword] = command await self.bot.config.update() diff --git a/core/thread.py b/core/thread.py index 41d2cd96ba..a494891965 100644 --- a/core/thread.py +++ b/core/thread.py @@ -241,6 +241,7 @@ class Author: async def activate_auto_triggers(): if initial_message: message = DummyMessage(copy.copy(initial_message)) + try: return await self.bot.trigger_auto_triggers(message, channel) except RuntimeError: From 115ccfadb797d876b8d7cbba91f311576695365a Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:17:11 -0700 Subject: [PATCH 419/705] Bug fixes and debug removal --- bot.py | 22 +++++++--------------- cogs/modmail.py | 5 ++--- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/bot.py b/bot.py index 12e28c8571..8c9d20dd87 100644 --- a/bot.py +++ b/bot.py @@ -1010,7 +1010,6 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if trigger: invoker = trigger.lower() - print("looking for auto trigger", trigger, self.auto_triggers[trigger]) alias = self.auto_triggers[trigger] ctxs = [] @@ -1020,39 +1019,32 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if not aliases: logger.warning("Alias %s is invalid as called in autotrigger.", invoker) - print("Aliases", aliases) - for alias in aliases: + print("Initial view", invoked_prefix + alias) view = StringView(invoked_prefix + alias) - invoked_with = view.get_word().lower() - invoked_with = invoked_with[1:] - print("Looking for", invoked_with) + invoked_with = view.get_word().lower()[1:] found_command = self.all_commands.get(invoked_with) # Check for alias if not found_command: - print("INVOKED WITH", invoked_with) - command_alias = self.aliases.get(invoked_with)[1:-1] - view = StringView(invoked_prefix + command_alias) - split_cmd = command_alias.split(" ") - found_command = self.all_commands.get(split_cmd[0]) + invoked_with = self.aliases.get(invoked_with)[1:-1] # Get command linked to alias + view = StringView(invoked_prefix + invoked_with) # Create StringView for new command + invoked_with = view.get_word().lower()[1:] # Parse the new command + found_command = self.all_commands.get(invoked_with) # Get the command function ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) ctx_.command = found_command + ctx_.invoked_with = invoked_with ctx_.thread = thread discord.utils.find(view.skip_string, await self.get_prefix()) - print("Command info:", view, ctx_, ctx_.thread, ctx_.invoked_with, ctx_.command) ctxs += [ctx_] for ctx in ctxs: if ctx.command: - print("Found command") old_checks = copy.copy(ctx.command.checks) - print("Old checks set") ctx.command.checks = [checks.has_permissions(PermissionLevel.INVALID)] - print("Command checks added, invoking...", ctx) await self.invoke(ctx) ctx.command.checks = old_checks diff --git a/cogs/modmail.py b/cogs/modmail.py index 35e80bdf9b..66d2f675da 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -818,10 +818,9 @@ async def reply(self, ctx, *, msg: str = ""): Supports attachments and images as well as automatically embedding image URLs. """ - + print("MSG IS", msg, ctx.message.content) ctx.message.content = msg - print("MSG IS", msg) - print("Sending", ctx.message, msg) + async with ctx.typing(): await ctx.thread.reply(ctx.message) From a24cae3dd6c0a0b6a88e2bdb405374458d8e12d3 Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:18:22 -0700 Subject: [PATCH 420/705] Remove debug --- bot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bot.py b/bot.py index 8c9d20dd87..20b8483128 100644 --- a/bot.py +++ b/bot.py @@ -1020,7 +1020,6 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) logger.warning("Alias %s is invalid as called in autotrigger.", invoker) for alias in aliases: - print("Initial view", invoked_prefix + alias) view = StringView(invoked_prefix + alias) invoked_with = view.get_word().lower()[1:] found_command = self.all_commands.get(invoked_with) From 4c0d8717192da6d57dbb13bfc8e4890849e6ef24 Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:20:27 -0700 Subject: [PATCH 421/705] Remove additional debug --- bot.py | 2 -- cogs/modmail.py | 2 +- cogs/utility.py | 3 --- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/bot.py b/bot.py index 20b8483128..a9b463fb0d 100644 --- a/bot.py +++ b/bot.py @@ -1048,8 +1048,6 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) ctx.command.checks = old_checks continue - else: - print("unable to find command") async def get_context(self, message, *, cls=commands.Context): """ diff --git a/cogs/modmail.py b/cogs/modmail.py index 66d2f675da..efbb90c0b1 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -818,7 +818,7 @@ async def reply(self, ctx, *, msg: str = ""): Supports attachments and images as well as automatically embedding image URLs. """ - print("MSG IS", msg, ctx.message.content) + ctx.message.content = msg async with ctx.typing(): diff --git a/cogs/utility.py b/cogs/utility.py index d068b6cc1e..3c3318cb6d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1750,12 +1750,9 @@ async def autotrigger_add(self, ctx, keyword, *, command): print(self.bot.get_command(" ".join(split_cmd[0:n]))) valid = True break - - print("Split command", split_cmd, "Range", range(1, len(split_cmd) + 1), self.bot.aliases) if not valid and self.bot.aliases: for n in range(1, len(split_cmd) + 1): - print(" ".join(split_cmd[0:n]), self.bot.aliases.get(" ".join(split_cmd[0:n]))) if self.bot.aliases.get(" ".join(split_cmd[0:n])): print(self.bot.aliases.get(" ".join(split_cmd[0:n]))) valid = True From ed0631c07cb3b551c5b2862de9a68b65afd56a44 Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:21:40 -0700 Subject: [PATCH 422/705] Update bot.py --- bot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot.py b/bot.py index a9b463fb0d..01e9503c46 100644 --- a/bot.py +++ b/bot.py @@ -1044,6 +1044,7 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if ctx.command: old_checks = copy.copy(ctx.command.checks) ctx.command.checks = [checks.has_permissions(PermissionLevel.INVALID)] + await self.invoke(ctx) ctx.command.checks = old_checks From 25cba86522b261ac6be406728313e31a416adb85 Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:24:16 -0700 Subject: [PATCH 423/705] Edit error message --- cogs/utility.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 3c3318cb6d..59e5d507dd 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1771,7 +1771,7 @@ async def autotrigger_add(self, ctx, keyword, *, command): embed = discord.Embed( title="Error", color=self.bot.error_color, - description="Invalid command. Note that autotriggers do not work with aliases.", + description="Invalid command. Please provide a valid command or alias.", ) await ctx.send(embed=embed) @@ -1812,7 +1812,7 @@ async def autotrigger_edit(self, ctx, keyword, *, command): embed = discord.Embed( title="Error", color=self.bot.error_color, - description="Invalid command. Note that autotriggers do not work with aliases.", + description="Invalid command. Please provide a valid command or alias.", ) await ctx.send(embed=embed) From bc451185aaabb1d97b510d82bb4894e9537ffce2 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 8 Aug 2021 15:27:14 +0800 Subject: [PATCH 424/705] move format_channel_name to Bot, resolve #2982 --- CHANGELOG.md | 5 +++-- bot.py | 32 +++++++++++++++++++++++++++++++- cogs/modmail.py | 2 +- core/utils.py | 34 ++-------------------------------- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1febcceb03..e7be4a292f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,14 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev6 +# v3.10.0-dev7 v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. ### Breaking - `Thread.recipient` (`str`) is now `Thread.recipients` (`List[str]`). -- `thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. +- `Thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. ### Added @@ -41,6 +41,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is - Fix return types, type hints and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) - Reload thread cache only when it's the first on_ready trigger. ([GH #3037](https://github.com/kyb3r/modmail/issues/3037)) +- `format_channel_name` is now extendable to plugins. Modify `Bot.format_channel_name(bot, author, exclude_channel=None, force_null=False):`. ([GH #2982](https://github.com/kyb3r/modmail/issues/2982)) # v3.9.5 diff --git a/bot.py b/bot.py index 33508e5eab..4ec694a1a5 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "v3.10.0-dev6" +__version__ = "3.10.0-dev7" import asyncio @@ -1645,6 +1645,36 @@ async def before_autoupdate(self): logger.warning("Autoupdates disabled.") self.autoupdate_loop.cancel() + def format_channel_name(self, author, exclude_channel=None, force_null=False): + """Sanitises a username for use with text channel names + + Placed in main bot class to be extendable to plugins""" + guild = self.modmail_guild + + if force_null: + name = new_name = "null" + else: + if self.config["use_user_id_channel_name"]: + name = new_name = str(author.id) + elif self.config["use_timestamp_channel_name"]: + name = new_name = author.created_at.isoformat(sep="-", timespec="minutes") + else: + name = author.name.lower() + if force_null: + name = "null" + + name = new_name = ( + "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" + ) + f"-{author.discriminator}" + + counter = 1 + existed = set(c.name for c in guild.text_channels if c != exclude_channel) + while new_name in existed: + new_name = f"{name}_{counter}" # multiple channels with same name + counter += 1 + + return new_name + def main(): try: diff --git a/cogs/modmail.py b/cogs/modmail.py index 5e9813423c..57f7f017d6 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1829,7 +1829,7 @@ async def repair(self, ctx): ) if len(users) == 1: user = users.pop() - name = format_channel_name(self.bot, user, exclude_channel=ctx.channel) + name = self.bot.format_channel_name(user, exclude_channel=ctx.channel) recipient = self.bot.get_user(user.id) if user.id in self.bot.threads.cache: thread = self.bot.threads.cache[user.id] diff --git a/core/utils.py b/core/utils.py index 474bc9db4f..717b683546 100644 --- a/core/utils.py +++ b/core/utils.py @@ -30,7 +30,6 @@ "format_description", "trigger_typing", "escape_code_block", - "format_channel_name", "tryint", "get_top_hoisted_role", "get_joint_id", @@ -364,35 +363,6 @@ def escape_code_block(text): return re.sub(r"```", "`\u200b``", text) -def format_channel_name(bot, author, exclude_channel=None, force_null=False): - """Sanitises a username for use with text channel names""" - guild = bot.modmail_guild - - if force_null: - name = new_name = "null" - else: - if bot.config["use_user_id_channel_name"]: - name = new_name = str(author.id) - elif bot.config["use_timestamp_channel_name"]: - name = new_name = author.created_at.isoformat(sep="-", timespec="minutes") - else: - name = author.name.lower() - if force_null: - name = "null" - - name = new_name = ( - "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" - ) + f"-{author.discriminator}" - - counter = 1 - existed = set(c.name for c in guild.text_channels if c != exclude_channel) - while new_name in existed: - new_name = f"{name}_{counter}" # multiple channels with same name - counter += 1 - - return new_name - - def tryint(x): try: return int(x) @@ -408,7 +378,7 @@ def get_top_hoisted_role(member: discord.Member): async def create_thread_channel(bot, recipient, category, overwrites, *, name=None, errors_raised=[]): - name = name or format_channel_name(bot, recipient) + name = name or bot.format_channel_name(recipient) try: channel = await bot.modmail_guild.create_text_channel( name=name, @@ -446,7 +416,7 @@ async def create_thread_channel(bot, recipient, category, overwrites, *, name=No recipient, category, overwrites, - name=format_channel_name(bot, recipient, force_null=True), + name=bot.format_channel_name(recipient, force_null=True), errors_raised=errors_raised, ) From cc890c4b5fb1b642c34874a9c8cb4c37c12325f4 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 8 Aug 2021 15:28:02 +0800 Subject: [PATCH 425/705] Formatting --- bot.py | 12 ++++++------ cogs/modmail.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bot.py b/bot.py index 01e9503c46..e066bc068a 100644 --- a/bot.py +++ b/bot.py @@ -1026,14 +1026,14 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) # Check for alias if not found_command: - invoked_with = self.aliases.get(invoked_with)[1:-1] # Get command linked to alias - view = StringView(invoked_prefix + invoked_with) # Create StringView for new command - invoked_with = view.get_word().lower()[1:] # Parse the new command - found_command = self.all_commands.get(invoked_with) # Get the command function + invoked_with = self.aliases.get(invoked_with)[1:-1] # Get command linked to alias + view = StringView(invoked_prefix + invoked_with) # Create StringView for new command + invoked_with = view.get_word().lower()[1:] # Parse the new command + found_command = self.all_commands.get(invoked_with) # Get the command function ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) ctx_.command = found_command - + ctx_.invoked_with = invoked_with ctx_.thread = thread discord.utils.find(view.skip_string, await self.get_prefix()) @@ -1044,7 +1044,7 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if ctx.command: old_checks = copy.copy(ctx.command.checks) ctx.command.checks = [checks.has_permissions(PermissionLevel.INVALID)] - + await self.invoke(ctx) ctx.command.checks = old_checks diff --git a/cogs/modmail.py b/cogs/modmail.py index efbb90c0b1..367c30f3c8 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -820,7 +820,7 @@ async def reply(self, ctx, *, msg: str = ""): """ ctx.message.content = msg - + async with ctx.typing(): await ctx.thread.reply(ctx.message) From f3c22461d4a4eaf331ae637fbae9f017fa0270d6 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 8 Aug 2021 15:57:24 +0800 Subject: [PATCH 426/705] bump ver --- README.md | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2751e10fe0..e71432b5ca 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/pyproject.toml b/pyproject.toml index 20e1a16ac4..1c3ba056de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev6' +version = '3.10.0-dev7' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 8ab48fc935f0597819d6227f2760356c44cb2100 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 8 Aug 2021 18:49:23 +0800 Subject: [PATCH 427/705] Bug fixes --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 3 ++- core/utils.py | 3 +-- pyproject.toml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7be4a292f..b1745e32aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev7 +# v3.10.0-dev8 v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. diff --git a/README.md b/README.md index e71432b5ca..21e655a23c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 4ec694a1a5..8f581ab4e3 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.0-dev7" +__version__ = "3.10.0-dev8" import asyncio @@ -7,6 +7,7 @@ import os import re import signal +import string import sys import typing from datetime import datetime diff --git a/core/utils.py b/core/utils.py index 717b683546..0fa74e457a 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,7 +1,6 @@ import base64 import functools import re -import string import typing from difflib import get_close_matches from distutils.util import strtobool as _stb # pylint: disable=import-error @@ -396,7 +395,7 @@ async def create_thread_channel(bot, recipient, category, overwrites, *, name=No if "Maximum number of channels in category reached" in e.text: fallback_id = bot.config["fallback_category_id"] if fallback_id: - fallback = discord.utils.get(cat.guild.categories, id=int(fallback_id)) + fallback = discord.utils.get(category.guild.categories, id=int(fallback_id)) if fallback and len(fallback.channels) < 49: category = fallback diff --git a/pyproject.toml b/pyproject.toml index 1c3ba056de..67a9dbd4f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev7' +version = '3.10.0-dev8' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 736863b49f981992f2e9f13add9552231f0d8c9b Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Sun, 8 Aug 2021 19:39:57 -0700 Subject: [PATCH 428/705] Redo alias conversion --- bot.py | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/bot.py b/bot.py index e066bc068a..e5008d51d1 100644 --- a/bot.py +++ b/bot.py @@ -1013,32 +1013,20 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) alias = self.auto_triggers[trigger] ctxs = [] + if alias is not None: ctxs = [] aliases = normalize_alias(alias) if not aliases: logger.warning("Alias %s is invalid as called in autotrigger.", invoker) - for alias in aliases: - view = StringView(invoked_prefix + alias) - invoked_with = view.get_word().lower()[1:] - found_command = self.all_commands.get(invoked_with) - - # Check for alias - if not found_command: - invoked_with = self.aliases.get(invoked_with)[1:-1] # Get command linked to alias - view = StringView(invoked_prefix + invoked_with) # Create StringView for new command - invoked_with = view.get_word().lower()[1:] # Parse the new command - found_command = self.all_commands.get(invoked_with) # Get the command function + message.author = thread.recipient # Allow for get_contexts to work - ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) - ctx_.command = found_command - - ctx_.invoked_with = invoked_with - ctx_.thread = thread - discord.utils.find(view.skip_string, await self.get_prefix()) + for alias in aliases: + message.content = invoked_prefix + alias + ctxs += await self.get_contexts(message) - ctxs += [ctx_] + message.author = self.modmail_guild.me # Fix message so commands execute properly for ctx in ctxs: if ctx.command: From e31cc7681c2ea7ec23ca0e8b5fb696206a3bfe01 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 10 Aug 2021 23:07:44 +0800 Subject: [PATCH 429/705] Remove redundant category checks --- core/thread.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/core/thread.py b/core/thread.py index 700654e314..4d627226b7 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1294,20 +1294,6 @@ async def create( self.cache[recipient.id] = thread - # Schedule thread setup for later - cat = self.bot.main_category - if category is None and len(cat.channels) >= 49: - fallback_id = self.bot.config["fallback_category_id"] - if fallback_id: - fallback = discord.utils.get(cat.guild.categories, id=int(fallback_id)) - if fallback and len(fallback.channels) < 49: - category = fallback - - if not category: - category = await cat.clone(name="Fallback Modmail") - self.bot.config.set("fallback_category_id", str(category.id)) - await self.bot.config.update() - if (message or not manual_trigger) and self.bot.config["confirm_thread_creation"]: if not manual_trigger: destination = recipient From 0110130600ce86240a197dcd719e892dfc47c09b Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 17 Aug 2021 15:01:20 +0800 Subject: [PATCH 430/705] ?contact accepts multiple users, or role #3082 --- CHANGELOG.md | 9 ++- README.md | 2 +- bot.py | 2 +- cogs/modmail.py | 155 +++++++++++++++++++++++++++++------------------- cogs/utility.py | 6 +- pyproject.toml | 2 +- 6 files changed, 107 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1745e32aa..18d56cc081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,23 +6,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev8 +# v3.10.0-dev9 v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. ### Breaking - `Thread.recipient` (`str`) is now `Thread.recipients` (`List[str]`). -- `Thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple. +- `Thread.reply` now returns `mod_message, user_message1, user_message2`... It is no longer limited at a size 2 tuple. ### Added -- Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) +- Ability to have group conversations with up to 5 users. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) - Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080)) - Default tags now use top hoisted role. ([GH #3014](https://github.com/kyb3r/modmail/issues/3014)) - New thread-related config - `thread_show_roles`, `thread_show_account_age`, `thread_show_join_age`, `thread_cancelled`, `thread_creation_contact_title`, `thread_creation_self_contact_response`, `thread_creation_contact_response`. ([GH #3072](https://github.com/kyb3r/modmail/issues/3072)) - `use_timestamp_channel_name` config to create thread channels by timestamp. +### Improved +- `?contact` now accepts a role or multiple users (creates a group conversation). ([GH #3082](https://github.com/kyb3r/modmail/issues/3082)) + ### Fixed - Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) diff --git a/README.md b/README.md index 21e655a23c..d45da9823e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 8f581ab4e3..f8fa9e2b35 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.0-dev8" +__version__ = "3.10.0-dev9" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index 57f7f017d6..2c8dedcbe7 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -718,6 +718,16 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str ctx.command.reset_cooldown(ctx) return + if len(users + ctx.thread.recipients) > 5: + em = discord.Embed( + title="Error", + description="Only 5 users are allowed in a group conversation", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + if not silent: description = self.bot.formatter.format( self.bot.config["private_added_to_group_response"], moderator=ctx.author @@ -1308,14 +1318,14 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): @checks.has_permissions(PermissionLevel.REGULAR) async def selfcontact(self, ctx): """Creates a thread with yourself""" - await ctx.invoke(self.contact, user=ctx.author) + await ctx.invoke(self.contact, users=[ctx.author]) @commands.command(usage=" [category] [options]") @checks.has_permissions(PermissionLevel.SUPPORTER) async def contact( self, ctx, - user: Union[discord.Member, discord.User], + users: commands.Greedy[Union[discord.Member, discord.User, discord.Role]], *, category: Union[SimilarCategoryConverter, str] = None, manual_trigger=True, @@ -1327,7 +1337,8 @@ async def contact( will be created in that specified category. `category`, if specified, may be a category ID, mention, or name. - `user` may be a user ID, mention, or name. + `users` may be a user ID, mention, or name. If multiple users are specified, a group thread will start. + A maximum of 5 users are allowed. `options` can be `silent` or `silently`. """ silent = False @@ -1345,75 +1356,99 @@ async def contact( if isinstance(category, str): category = None - if user.bot: - embed = discord.Embed(color=self.bot.error_color, description="Cannot start a thread with a bot.") - return await ctx.send(embed=embed, delete_after=3) + errors = [] + for u in list(users): + if isinstance(u, discord.Role): + users += u.members + users.remove(u) - exists = await self.bot.threads.find(recipient=user) - if exists: - desc = "A thread for this user already exists" - if exists.channel: - desc += f" in {exists.channel.mention}" - desc += "." - embed = discord.Embed(color=self.bot.error_color, description=desc) - await ctx.channel.send(embed=embed, delete_after=3) + for u in list(users): + exists = await self.bot.threads.find(recipient=u) + if exists: + errors.append(f"A thread for {u} already exists.") + if exists.channel: + errors[-1] += f" in {exists.channel.mention}" + errors[-1] += "." + users.remove(u) + elif u.bot: + errors.append(f"{u} is a bot, cannot add to thread.") + users.remove(u) + elif await self.bot.is_blocked(u): + ref = f"{u.mention} is" if ctx.author != u else "You are" + errors.append(f"{ref} currently blocked from contacting {self.bot.user.name}.") + users.remove(u) - else: - creator = ctx.author if manual_trigger else user - if await self.bot.is_blocked(user): - if not manual_trigger: # react to contact - return + if len(users) > 5: + errors.append("Group conversations only support 5 users.") + users = [] - ref = f"{user.mention} is" if creator != user else "You are" - embed = discord.Embed( - color=self.bot.error_color, - description=f"{ref} currently blocked from contacting {self.bot.user.name}.", - ) - return await ctx.send(embed=embed) + if errors or not users: + if not users: + # no users left + title = "Thread not created" + else: + title = None - thread = await self.bot.threads.create( - recipient=user, - creator=creator, - category=category, - manual_trigger=manual_trigger, - ) - if thread.cancelled: + if manual_trigger: # not react to contact + embed = discord.Embed(title=title, color=self.bot.error_color, description="\n".join(errors)) + await ctx.send(embed=embed, delete_after=10) + + if not users: + # end return - if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): - logger.info("Contacting user %s when Modmail DM is disabled.", user) + creator = ctx.author if manual_trigger else users[0] - if not silent and not self.bot.config.get("thread_contact_silently"): - if creator.id == user.id: - description = self.bot.config["thread_creation_self_contact_response"] - else: - description = self.bot.formatter.format( - self.bot.config["thread_creation_contact_response"], creator=creator - ) + thread = await self.bot.threads.create( + recipient=users[0], + creator=creator, + category=category, + manual_trigger=manual_trigger, + ) - em = discord.Embed( - title=self.bot.config["thread_creation_contact_title"], - description=description, - color=self.bot.main_color, + if thread.cancelled: + return + + if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): + logger.info("Contacting user %s when Modmail DM is disabled.", users[0]) + + if not silent and not self.bot.config.get("thread_contact_silently"): + if creator.id == users[0].id: + description = self.bot.config["thread_creation_self_contact_response"] + else: + description = self.bot.formatter.format( + self.bot.config["thread_creation_contact_response"], creator=creator ) - if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{creator}", icon_url=creator.avatar_url) - await user.send(embed=em) - embed = discord.Embed( - title="Created Thread", - description=f"Thread started by {creator.mention} for {user.mention}.", + em = discord.Embed( + title=self.bot.config["thread_creation_contact_title"], + description=description, color=self.bot.main_color, ) - await thread.wait_until_ready() - await thread.channel.send(embed=embed) - - if manual_trigger: - sent_emoji, _ = await self.bot.retrieve_emoji() - await self.bot.add_reaction(ctx.message, sent_emoji) - await asyncio.sleep(5) - await ctx.message.delete() + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() + em.set_footer(text=f"{creator}", icon_url=creator.avatar_url) + + for u in users: + await u.send(embed=em) + + embed = discord.Embed( + title="Created Thread", + description=f"Thread started by {creator.mention} for {', '.join(u.mention for u in users)}.", + color=self.bot.main_color, + ) + await thread.wait_until_ready() + + if users[1:]: + await thread.add_users(users[1:]) + + await thread.channel.send(embed=embed) + + if manual_trigger: + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + await asyncio.sleep(5) + await ctx.message.delete() @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.MODERATOR) diff --git a/cogs/utility.py b/cogs/utility.py index db3fa8e746..41bf5ce655 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -695,7 +695,7 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, option = user_or_role[0].lower() if option == "disable": embed = discord.Embed( - description=f"Disabled mention on thread creation.", + description="Disabled mention on thread creation.", color=self.bot.main_color, ) self.bot.config["mention"] = None @@ -893,7 +893,7 @@ async def config_help(self, ctx, key: str.lower = None): description=f"`{key}` is an invalid key.", ) if closest: - embed.add_field(name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) + embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) return await ctx.send(embed=embed) config_help = self.bot.config.config_help @@ -1850,7 +1850,7 @@ async def autotrigger_test(self, ctx, *, text): embed = discord.Embed( title="Keyword Not Found", color=self.bot.error_color, - description=f"No autotrigger keyword found.", + description="No autotrigger keyword found.", ) return await ctx.send(embed=embed) diff --git a/pyproject.toml b/pyproject.toml index 67a9dbd4f7..8288e6dd2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev8' +version = '3.10.0-dev9' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 936585a5ba96bd61cde91ffc69edce5c542e27ac Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 21 Aug 2021 12:18:19 +0800 Subject: [PATCH 431/705] Changelog and fix bot perm level --- CHANGELOG.md | 4 +++- README.md | 2 +- bot.py | 2 +- cogs/utility.py | 3 --- core/checks.py | 2 +- pyproject.toml | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d56cc081..d965aa8b18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev9 +# v3.10.0-dev10 v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. @@ -25,6 +25,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is ### Improved - `?contact` now accepts a role or multiple users (creates a group conversation). ([GH #3082](https://github.com/kyb3r/modmail/issues/3082)) +- Aliases are now supported in autotrigger. ([GH #3081](https://github.com/kyb3r/modmail/pull/3081)) ### Fixed @@ -39,6 +40,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is - `thread_auto_close` timer now only resets on non-note and replies from mods. ([GH #3030](https://github.com/kyb3r/modmail/issues/3030)) - Deleted messages are now deleted on both ends. ([GH #3041](https://github.com/kyb3r/modmail/issues/3041), [@JerrieAries](https://github.com/kyb3r/modmail/commit/20b31f8e8b5497943513997fef788d72ae668438)) - Persistent notes are now properly deleted from the database. ([GH #3013](https://github.com/kyb3r/modmail/issues/3013)) +- Modmail Bot is now recognized to have `OWNER` permission level. This affects what can be run in autotriggers. ### Internal diff --git a/README.md b/README.md index d45da9823e..62e9496873 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 27231da3cc..98af158c5a 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.0-dev9" +__version__ = "3.10.0-dev10" import asyncio diff --git a/cogs/utility.py b/cogs/utility.py index ca5c9acfae..b0b2a344fc 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1755,7 +1755,6 @@ async def autotrigger_add(self, ctx, keyword, *, command): if not valid and self.bot.aliases: for n in range(1, len(split_cmd) + 1): if self.bot.aliases.get(" ".join(split_cmd[0:n])): - print(self.bot.aliases.get(" ".join(split_cmd[0:n]))) valid = True break @@ -1794,9 +1793,7 @@ async def autotrigger_edit(self, ctx, keyword, *, command): if not valid and self.bot.aliases: for n in range(1, len(split_cmd) + 1): - print(" ".join(split_cmd[0:n]), self.bot.aliases.get(" ".join(split_cmd[0:n]))) if self.bot.aliases.get(" ".join(split_cmd[0:n])): - print(self.bot.aliases.get(" ".join(split_cmd[0:n]))) valid = True break diff --git a/core/checks.py b/core/checks.py index 3f3666538d..15dcb098da 100644 --- a/core/checks.py +++ b/core/checks.py @@ -39,7 +39,7 @@ async def setup(ctx): async def check_permissions(ctx, command_name) -> bool: """Logic for checking permissions for a command for a user""" - if await ctx.bot.is_owner(ctx.author): + if await ctx.bot.is_owner(ctx.author) or ctx.author.id == ctx.bot.user.id: # Bot owner(s) (and creator) has absolute power over the bot return True diff --git a/pyproject.toml b/pyproject.toml index 8288e6dd2f..d06f3ea7c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev9' +version = '3.10.0-dev10' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 7a4582d65df21eca107c967ebe0f098614afc6dc Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 21 Aug 2021 12:19:22 +0800 Subject: [PATCH 432/705] Remove extra loop.close --- bot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bot.py b/bot.py index 98af158c5a..9894913126 100644 --- a/bot.py +++ b/bot.py @@ -286,7 +286,6 @@ def _cancel_tasks(): loop.run_until_complete(loop.shutdown_asyncgens()) finally: logger.info("Closing the event loop.") - # loop.close() if not future.cancelled(): try: From 4e54fd45d3e9cc84d3890994eac22a58a8cb4784 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 00:24:45 +0800 Subject: [PATCH 433/705] Push version to 3.10 --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d965aa8b18..6164ce1dbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.10.0-dev10 +# v3.10.0 v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. diff --git a/README.md b/README.md index 62e9496873..a57b07f33b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 9894913126..0f178989cd 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.0-dev10" +__version__ = "3.10.0" import asyncio diff --git a/pyproject.toml b/pyproject.toml index d06f3ea7c4..2c5870d4a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0-dev10' +version = '3.10.0' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From b30e0d7634e7ec3ddac329904c242ff65c329e29 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 00:36:21 +0800 Subject: [PATCH 434/705] Quick bugfix on config help and debug hastebin --- cogs/utility.py | 1 - core/config_help.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index b0b2a344fc..bc813e9d6e 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -444,7 +444,6 @@ async def debug_hastebin(self, ctx): with open( os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), "rb+", - encoding="utf-8", ) as f: logs = BytesIO(f.read().strip()) diff --git a/core/config_help.json b/core/config_help.json index 1a57d3a3e8..ee91e3d37d 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -434,7 +434,7 @@ ] }, "thread_creation_contact_response": { - "default": "\"{creator.name} has opened a Modmail thread.\"", + "default": "\"{{creator.name}} has opened a Modmail thread.\"", "description": "This is the message embed description sent to recipients when contacted by a mod.", "examples": [ "`{prefix}config set thread_creation_contact_response New thread opened.`" From 4ef803337b5c6359d6711cbd71f3c5188ec54918 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 00:44:00 +0800 Subject: [PATCH 435/705] Fix bug where snippet add did not check command name --- cogs/modmail.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index c4244a5b12..bb3860bfde 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -206,7 +206,13 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte {prefix}snippet add "two word" this is a two word snippet. ``` """ - if name in self.bot.snippets: + if self.bot.get_command(name): + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"A command with the same name already exists: `{name}`.", + ) + elif name in self.bot.snippets: embed = discord.Embed( title="Error", color=self.bot.error_color, From 83225e939b514d3e7b1b9baab6d692a26410e453 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 01:06:29 +0800 Subject: [PATCH 436/705] v3.10.1 - fix edit cmd --- CHANGELOG.md | 9 +++++++++ README.md | 2 +- bot.py | 2 +- core/thread.py | 2 +- pyproject.toml | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6164ce1dbf..73cafb190f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.10.1 + +This is a hotfix for the edit command. + +### Fixed + +- `?edit` now works properly. + # v3.10.0 v3.10 adds group conversations while resolving other bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads. @@ -24,6 +32,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is - `use_timestamp_channel_name` config to create thread channels by timestamp. ### Improved + - `?contact` now accepts a role or multiple users (creates a group conversation). ([GH #3082](https://github.com/kyb3r/modmail/issues/3082)) - Aliases are now supported in autotrigger. ([GH #3081](https://github.com/kyb3r/modmail/pull/3081)) diff --git a/README.md b/README.md index a57b07f33b..2604990a87 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 0f178989cd..7917bb73cf 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.0" +__version__ = "3.10.1" import asyncio diff --git a/core/thread.py b/core/thread.py index 1cde667c6a..54509cdc36 100644 --- a/core/thread.py +++ b/core/thread.py @@ -665,7 +665,7 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> tasks = [self.bot.api.edit_message(message1.id, message), message1.edit(embed=embed1)] if message2 is not [None]: for m2 in message2: - embed2 = message2.embeds[0] + embed2 = m2.embeds[0] embed2.description = message tasks += [m2.edit(embed=embed2)] elif message1.embeds[0].author.name.startswith("Persistent Note"): diff --git a/pyproject.toml b/pyproject.toml index 2c5870d4a2..ec51bb12a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.0' +version = '3.10.1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From a2f57311ade38a6554579dad0b4259d7bc4f5469 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 01:19:48 +0800 Subject: [PATCH 437/705] Fix contact --- bot.py | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index 7917bb73cf..20b7b05cb7 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.1" +__version__ = "3.10.0" import asyncio @@ -1329,7 +1329,7 @@ async def handle_react_to_contact(self, payload): return await member.send(embed=embed) ctx = await self.get_context(message) - await ctx.invoke(self.get_command("contact"), user=member, manual_trigger=False) + await ctx.invoke(self.get_command("contact"), users=[member], manual_trigger=False) async def on_raw_reaction_add(self, payload): await asyncio.gather( diff --git a/pyproject.toml b/pyproject.toml index ec51bb12a4..1d60fc9d97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,5 +34,5 @@ repository = 'https://github.com/kyb3r/modmail' homepage = 'https://github.com/kyb3r/modmail' keywords = ['discord', 'modmail'] -[tool.pylint.format] +[tool.pylint.format]react_to_contact_message max-line-length = "110" From ed7a2ae7031b78cc647db9979b1a7bb885562c16 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 01:21:03 +0800 Subject: [PATCH 438/705] bump ver --- CHANGELOG.md | 7 +++++++ README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73cafb190f..af6e0cc407 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.10.2 +This is a hotfix for react to contact. + +### Fixed + +- React to contact now works properly. + # v3.10.1 This is a hotfix for the edit command. diff --git a/README.md b/README.md index 2604990a87..f4b8e8d2ff 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 20b7b05cb7..7d4248173c 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.0" +__version__ = "3.10.2" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 1d60fc9d97..e7438ca373 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.1' +version = '3.10.2' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 2682d58d20145aa0d462f732cc361d29d85e65ab Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 01:21:34 +0800 Subject: [PATCH 439/705] oops --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e7438ca373..4dc7d411a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,5 +34,5 @@ repository = 'https://github.com/kyb3r/modmail' homepage = 'https://github.com/kyb3r/modmail' keywords = ['discord', 'modmail'] -[tool.pylint.format]react_to_contact_message +[tool.pylint.format] max-line-length = "110" From 778574ef52de95b593e22014c9aa36f402ae0b27 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 5 Sep 2021 01:21:46 +0800 Subject: [PATCH 440/705] oops --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e7438ca373..4dc7d411a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,5 +34,5 @@ repository = 'https://github.com/kyb3r/modmail' homepage = 'https://github.com/kyb3r/modmail' keywords = ['discord', 'modmail'] -[tool.pylint.format]react_to_contact_message +[tool.pylint.format] max-line-length = "110" From e311828d32cd13ab0ce6a33d3362cd52ea49b69d Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 6 Sep 2021 01:10:18 +0800 Subject: [PATCH 441/705] Improved UI for group conversations, LOG_DISCORD, snippet fix --- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- bot.py | 11 ++++++++++- cogs/modmail.py | 11 +++++++++++ core/thread.py | 37 +++++++++++++++++++++++++++++++++++-- pyproject.toml | 2 +- 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af6e0cc407..85fc813322 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.10.3 + +### Improved + +- Thread genesis message now shows other recipients. + +### Fixed + +- `?snippet add` now properly blocks command names. + +### Internal + +- Set `LOG_DISCORD` environment variable to the logger level and log discord events. + # v3.10.2 This is a hotfix for react to contact. diff --git a/README.md b/README.md index f4b8e8d2ff..9730cd1339 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 7d4248173c..86ef132b40 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.2" +__version__ = "3.10.3" import asyncio @@ -1694,6 +1694,15 @@ def main(): ) sys.exit(0) + if os.environ.get("LOG_DISCORD"): + logger.debug(f"Discord logging enabled: {os.environ['LOG_DISCORD'].upper()}") + d_logger = logging.getLogger("discord") + + d_logger.setLevel(os.environ["LOG_DISCORD"].upper()) + handler = logging.FileHandler(filename="discord.log", encoding="utf-8", mode="w") + handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s")) + d_logger.addHandler(handler) + bot = ModmailBot() bot.run() diff --git a/cogs/modmail.py b/cogs/modmail.py index bb3860bfde..4a974b26cc 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -212,6 +212,7 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte color=self.bot.error_color, description=f"A command with the same name already exists: `{name}`.", ) + return await ctx.send(embed=embed) elif name in self.bot.snippets: embed = discord.Embed( title="Error", @@ -813,6 +814,16 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ctx.command.reset_cooldown(ctx) return + if not users: + em = discord.Embed( + title="Error", + description="No valid users to remove.", + color=self.bot.error_color, + ) + await ctx.send(embed=em) + ctx.command.reset_cooldown(ctx) + return + if not silent: description = self.bot.formatter.format( self.bot.config["private_removed_from_group_response"], moderator=ctx.author diff --git a/core/thread.py b/core/thread.py index 54509cdc36..fc48f88f5b 100644 --- a/core/thread.py +++ b/core/thread.py @@ -51,7 +51,7 @@ def __init__( self._recipient = recipient self._other_recipients = other_recipients or [] self._channel = channel - self.genesis_message = None + self._genesis_message = None self._ready_event = asyncio.Event() self.wait_tasks = [] self.close_task = None @@ -140,6 +140,15 @@ async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChann return thread + async def get_genesis_message(self) -> discord.Message: + if self._genesis_message is None: + async for m in self.channel.history(limit=5, oldest_first=True): + if m.author == self.bot.user: + if m.embeds and m.embeds[0].fields and m.embeds[0].fields[0].name == "Roles": + self._genesis_message = m + + return self._genesis_message + async def setup(self, *, creator=None, category=None, initial_message=None): """Create the thread channel and other io related initialisation tasks""" self.bot.dispatch("thread_initiate", self, creator, category, initial_message) @@ -195,7 +204,7 @@ async def send_genesis_message(): try: msg = await channel.send(mention, embed=info_embed) self.bot.loop.create_task(msg.pin()) - self.genesis_message = msg + self._genesis_message = msg except Exception: logger.error("Failed unexpectedly:", exc_info=True) @@ -1131,6 +1140,26 @@ async def set_title(self, title: str) -> None: await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + async def _update_users_genesis(self): + genesis_message = await self.get_genesis_message() + embed = genesis_message.embeds[0] + value = " ".join(x.mention for x in self._other_recipients) + index = None + for n, field in enumerate(embed.fields): + if field.name == "Other Recipients": + index = n + break + + if index is None and value: + embed.add_field(name="Other Recipients", value=value, inline=False) + else: + if value: + embed.set_field_at(index, value=value) + else: + embed.remove_field(index) + + await genesis_message.edit(embed=embed) + async def add_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: title = match_title(self.channel.topic) user_id = match_user_id(self.channel.topic) @@ -1139,6 +1168,8 @@ async def add_users(self, users: typing.List[typing.Union[discord.Member, discor ids = ",".join(str(i.id) for i in self._other_recipients) await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + await self._update_users_genesis() + async def remove_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: title = match_title(self.channel.topic) user_id = match_user_id(self.channel.topic) @@ -1148,6 +1179,8 @@ async def remove_users(self, users: typing.List[typing.Union[discord.Member, dis ids = ",".join(str(i.id) for i in self._other_recipients) await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + await self._update_users_genesis() + class ThreadManager: """Class that handles storing, finding and creating Modmail threads.""" diff --git a/pyproject.toml b/pyproject.toml index 4dc7d411a5..341e506413 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.2' +version = '3.10.3' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 6431ab04980eae662151e7d7d4ed3ea02d08c280 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 6 Sep 2021 01:20:22 +0800 Subject: [PATCH 442/705] Fix typo in config_help --- core/config_help.json | 2 +- core/thread.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/config_help.json b/core/config_help.json index ee91e3d37d..1bfd65a92b 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -426,7 +426,7 @@ "default": "\"You have opened a Modmail thread.\"", "description": "This is the message embed description sent to recipients when self-contacted.", "examples": [ - "`{prefix}config set thread_creation_contact_title You contacted yourself.`" + "`{prefix}config set thread_creation_self_contact_response You contacted yourself.`" ], "notes": [ "`thread_creation_contact_response` is used when contacted by another user.", diff --git a/core/thread.py b/core/thread.py index fc48f88f5b..e17a581630 100644 --- a/core/thread.py +++ b/core/thread.py @@ -805,7 +805,8 @@ async def note( async def reply( self, message: discord.Message, anonymous: bool = False, plain: bool = False - ) -> typing.Tuple[discord.Message, discord.Message]: + ) -> typing.Tuple[typing.List[discord.Message], discord.Message]: + """Returns List[user_dm_msg] and thread_channel_msg""" if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): From fc156f9601798246b2dca04764f0c861069d1ec2 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 6 Sep 2021 01:22:20 +0800 Subject: [PATCH 443/705] Fix syntax --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index e17a581630..6bc7adc6cb 100644 --- a/core/thread.py +++ b/core/thread.py @@ -806,7 +806,7 @@ async def note( async def reply( self, message: discord.Message, anonymous: bool = False, plain: bool = False ) -> typing.Tuple[typing.List[discord.Message], discord.Message]: - """Returns List[user_dm_msg] and thread_channel_msg""" + """Returns List[user_dm_msg] and thread_channel_msg""" if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): From 68827f7ad13f6842dfe19f4715d1f63c479c1cf7 Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 7 Sep 2021 09:01:53 +0800 Subject: [PATCH 444/705] Fix `?contact` command bug where the channel is created inside random category when `silent` or `silently` is passed in. Resolve #3091 --- cogs/modmail.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 4a974b26cc..937ef61ca5 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1362,9 +1362,16 @@ async def contact( """ silent = False if isinstance(category, str): - if "silent" in category or "silently" in category: + category = category.split() + + # just check the last element in the list + if category[-1].lower() in ("silent", "silently"): silent = True - category = category.strip("silently").strip("silent").strip() + # remove the last element as we no longer need it + category.pop() + + category = " ".join(category) + if category: try: category = await SimilarCategoryConverter().convert( ctx, category From 7922a97939c1d78da4a57bf8ed793527572c36b1 Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Tue, 7 Sep 2021 13:09:44 +1000 Subject: [PATCH 445/705] Allow top role's hoisted check to be configurable. --- cogs/modmail.py | 4 ++-- core/config.py | 2 ++ core/thread.py | 6 +++--- core/utils.py | 6 ++++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 4a974b26cc..fdbc27429b 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -918,7 +918,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, tag = self.bot.config["mod_tag"] if tag is None: - tag = str(get_top_hoisted_role(ctx.author)) + tag = str(get_top_role(ctx.author, self.bot.config["use_hoisted_top_role"])) name = self.bot.config["anon_username"] if name is None: name = tag @@ -1003,7 +1003,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro tag = self.bot.config["mod_tag"] if tag is None: - tag = str(get_top_hoisted_role(ctx.author)) + tag = str(get_top_role(ctx.author, self.bot.config["use_hoisted_top_role"])) name = self.bot.config["anon_username"] if name is None: name = tag diff --git a/core/config.py b/core/config.py index d8593a02ef..e9de7d516d 100644 --- a/core/config.py +++ b/core/config.py @@ -123,6 +123,7 @@ class ConfigManager: "confirm_thread_creation_deny": "\N{NO ENTRY SIGN}", # regex "use_regex_autotrigger": False, + "use_hoisted_top_role": True, } private_keys = { @@ -209,6 +210,7 @@ class ConfigManager: "thread_show_roles", "thread_show_account_age", "thread_show_join_age", + "use_hoisted_top_role", } enums = { diff --git a/core/thread.py b/core/thread.py index 6bc7adc6cb..e20a7d1110 100644 --- a/core/thread.py +++ b/core/thread.py @@ -21,7 +21,7 @@ match_user_id, match_other_recipients, truncate, - get_top_hoisted_role, + get_top_role, create_thread_channel, get_joint_id, ) @@ -938,7 +938,7 @@ async def send( # Anonymously sending to the user. tag = self.bot.config["mod_tag"] if tag is None: - tag = str(get_top_hoisted_role(author)) + tag = str(get_top_role(author, self.bot.config["use_hoisted_top_role"])) name = self.bot.config["anon_username"] if name is None: name = tag @@ -1055,7 +1055,7 @@ async def send( elif not anonymous: mod_tag = self.bot.config["mod_tag"] if mod_tag is None: - mod_tag = str(get_top_hoisted_role(message.author)) + mod_tag = str(get_top_role(message.author, self.bot.config["use_hoisted_top_role"])) embed.set_footer(text=mod_tag) # Normal messages else: embed.set_footer(text=self.bot.config["anon_tag"]) diff --git a/core/utils.py b/core/utils.py index 0fa74e457a..44df043938 100644 --- a/core/utils.py +++ b/core/utils.py @@ -30,7 +30,7 @@ "trigger_typing", "escape_code_block", "tryint", - "get_top_hoisted_role", + "get_top_role", "get_joint_id", ] @@ -369,9 +369,11 @@ def tryint(x): return x -def get_top_hoisted_role(member: discord.Member): +def get_top_role(member: discord.Member, hoisted=True): roles = sorted(member.roles, key=lambda r: r.position, reverse=True) for role in roles: + if not hoisted: + return role if role.hoist: return role From 655e063e7ba200fcce770b4d8d3d103f236d7e1d Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Tue, 7 Sep 2021 18:55:32 +1000 Subject: [PATCH 446/705] Add use_hoisted_top_role config help details. --- core/config_help.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/config_help.json b/core/config_help.json index 1bfd65a92b..d7bbcf5da8 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -1121,5 +1121,16 @@ "notes": [ "This configuration can only to be set through `.env` file or environment (config) variables." ] + }, + "use_hoisted_top_role": { + "default": "Yes", + "description": "Controls if only hoisted roles are evaluated when finding top role.", + "examples": [ + ], + "notes": [ + "Top role is displayed in embeds when replying or adding/removing users to a thread in the case mod_tag and anon_username are not set.", + "If this configuration is enabled, only roles that are hoisted (displayed seperately in member list) will be used. If a user has no hoisted roles, it will return 'None'.", + "If you would like to display the top role of a user regardless of if it's hoisted or not, disable `use_hoisted_top_role`." + ] } } From c5b311ba6c545627304c43c432628f5ccb14d299 Mon Sep 17 00:00:00 2001 From: Andy <49132750+matrix2113@users.noreply.github.com> Date: Wed, 8 Sep 2021 20:23:16 -0400 Subject: [PATCH 447/705] Fix typo --- core/config_help.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config_help.json b/core/config_help.json index ee91e3d37d..88d0e2e47e 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -227,7 +227,7 @@ "default": "Yes", "description": "This is the channel where update notifications are sent to.", "examples": [ - "`{prefix}config set update_notifications no" + "`{prefix}config set update_notifications no`" ], "notes": [ "This has no effect unless `disable_autoupdates` is set to no.", From c65a5b785473786e96949c5237e688ca5c46b6a9 Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Tue, 21 Sep 2021 21:26:48 +0530 Subject: [PATCH 448/705] Fetch thread closers if needed. --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 7d4248173c..a04661cc5f 100644 --- a/bot.py +++ b/bot.py @@ -582,7 +582,7 @@ async def on_ready(self): continue await thread.close( - closer=self.get_user(items["closer_id"]), + closer=self.get_user(items["closer_id"]) or await self.fetch_user(items["closer_id"]), after=after, silent=items["silent"], delete_channel=items["delete_channel"], From e87669c214ece58558e2cf9566e632e21f826634 Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Tue, 21 Sep 2021 21:27:08 +0530 Subject: [PATCH 449/705] Add the get_or_fetch_user method. --- bot.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bot.py b/bot.py index a04661cc5f..8cafda33b0 100644 --- a/bot.py +++ b/bot.py @@ -656,6 +656,15 @@ async def convert_emoji(self, name: str) -> str: raise return name + async def get_or_fetch_user(self, id: int) -> discord.User: + """ + Retrieve a User based on their ID. + + This tries getting the user from the cache and falls back to making + an API call if they're not found in the cache. + """ + return self.get_user(id) or await self.fetch_user(id) + async def retrieve_emoji(self) -> typing.Tuple[str, str]: sent_emoji = self.config["sent_emoji"] From 0e4c3749e4ccd4aa05837f9531b506d052fec781 Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Tue, 21 Sep 2021 21:34:41 +0530 Subject: [PATCH 450/705] Use the method where possible to tidy up code. --- bot.py | 2 +- cogs/modmail.py | 19 ++++++++----------- core/thread.py | 8 ++++---- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/bot.py b/bot.py index 8cafda33b0..f19725a954 100644 --- a/bot.py +++ b/bot.py @@ -582,7 +582,7 @@ async def on_ready(self): continue await thread.close( - closer=self.get_user(items["closer_id"]) or await self.fetch_user(items["closer_id"]), + closer=await self.get_or_fetch_user(items["closer_id"]), after=after, silent=items["silent"], delete_channel=items["delete_channel"], diff --git a/cogs/modmail.py b/cogs/modmail.py index bb3860bfde..814113f617 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1042,7 +1042,7 @@ async def logs(self, ctx, *, user: User = None): thread = ctx.thread if not thread: raise commands.MissingRequiredArgument(SimpleNamespace(name="member")) - user = thread.recipient or await self.bot.fetch_user(thread.id) + user = thread.recipient or await self.bot.get_or_fetch_user(thread.id) default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png" icon_url = getattr(user, "avatar_url", default_avatar) @@ -1492,15 +1492,12 @@ async def blocked(self, ctx): logger.debug("No longer blocked, user %s.", id_) continue - user = self.bot.get_user(int(id_)) - if user: - users.append((user.mention, reason)) + try: + user = await self.bot.get_or_fetch_user(int(id_)) + except discord.NotFound: + users.append((id_, reason)) else: - try: - user = await self.bot.fetch_user(id_) - users.append((user.mention, reason)) - except discord.NotFound: - users.append((id_, reason)) + users.append((user.mention, reason)) blocked_roles = list(self.bot.blocked_roles.items()) for id_, reason in blocked_roles: @@ -1840,7 +1837,7 @@ async def repair(self, ctx): user_id = match_user_id(message.embeds[0].footer.text) other_recipients = match_other_recipients(ctx.channel.topic) for n, uid in enumerate(other_recipients): - other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + other_recipients[n] = await self.bot.get_or_fetch_user(uid) if user_id != -1: recipient = self.bot.get_user(user_id) @@ -1893,7 +1890,7 @@ async def repair(self, ctx): other_recipients = match_other_recipients(ctx.channel.topic) for n, uid in enumerate(other_recipients): - other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + other_recipients[n] = await self.bot.get_or_fetch_user(uid) if recipient is None: self.bot.threads.cache[user.id] = thread = Thread( diff --git a/core/thread.py b/core/thread.py index 54509cdc36..c4fa7bbf07 100644 --- a/core/thread.py +++ b/core/thread.py @@ -126,12 +126,12 @@ async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChann if recipient_id in manager.cache: thread = manager.cache[recipient_id] else: - recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id) + recipient = await manager.bot.get_or_fetch_user(recipient_id) other_recipients = [] for uid in match_other_recipients(channel.topic): try: - other_recipient = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid) + other_recipient = await manager.bot.get_or_fetch_user(uid) except discord.NotFound: continue other_recipients.append(other_recipient) @@ -1243,14 +1243,14 @@ async def _find_from_channel(self, channel): return self.cache[user_id] try: - recipient = self.bot.get_user(user_id) or await self.bot.fetch_user(user_id) + recipient = await self.bot.get_or_fetch_user(user_id) except discord.NotFound: recipient = None other_recipients = [] for uid in match_other_recipients(channel.topic): try: - other_recipient = self.bot.get_user(uid) or await self.bot.fetch_user(uid) + other_recipient = await self.bot.get_or_fetch_user(uid) except discord.NotFound: continue other_recipients.append(other_recipient) From 9d0014284b8d31df96aa983a74e2a1ed1ec0f79a Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 3 Oct 2021 03:16:09 +0800 Subject: [PATCH 451/705] Rename `category` to `fallback` due to shadowing names. --- core/utils.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/utils.py b/core/utils.py index 0fa74e457a..aaaf7e463d 100644 --- a/core/utils.py +++ b/core/utils.py @@ -393,19 +393,20 @@ async def create_thread_channel(bot, recipient, category, overwrites, *, name=No errors_raised.append((e.text, (category, name))) if "Maximum number of channels in category reached" in e.text: + fallback = None fallback_id = bot.config["fallback_category_id"] if fallback_id: fallback = discord.utils.get(category.guild.categories, id=int(fallback_id)) - if fallback and len(fallback.channels) < 49: - category = fallback + if fallback and len(fallback.channels) >= 49: + fallback = None - if not category: - category = await category.clone(name="Fallback Modmail") + if not fallback: + fallback = await category.clone(name="Fallback Modmail") bot.config.set("fallback_category_id", str(category.id)) await bot.config.update() return await create_thread_channel( - bot, recipient, category, overwrites, errors_raised=errors_raised + bot, recipient, fallback, overwrites, errors_raised=errors_raised ) if "Contains words not allowed" in e.text: From 8b69b67f22430b2adf719d5c6f0fa0ba1d605943 Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Wed, 6 Oct 2021 01:55:59 +0800 Subject: [PATCH 452/705] Forgot to update the reference in `.config.set()`. --- core/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/utils.py b/core/utils.py index aaaf7e463d..2c58fe69d6 100644 --- a/core/utils.py +++ b/core/utils.py @@ -402,7 +402,7 @@ async def create_thread_channel(bot, recipient, category, overwrites, *, name=No if not fallback: fallback = await category.clone(name="Fallback Modmail") - bot.config.set("fallback_category_id", str(category.id)) + bot.config.set("fallback_category_id", str(fallback.id)) await bot.config.update() return await create_thread_channel( From b388f0eeca0ccf1200684cb278a0747fa6ada239 Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Wed, 6 Oct 2021 01:57:01 +0800 Subject: [PATCH 453/705] Change default value for `errors_raised` parameter to `None`. --- core/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/utils.py b/core/utils.py index 2c58fe69d6..1fa1a95e61 100644 --- a/core/utils.py +++ b/core/utils.py @@ -376,8 +376,10 @@ def get_top_hoisted_role(member: discord.Member): return role -async def create_thread_channel(bot, recipient, category, overwrites, *, name=None, errors_raised=[]): +async def create_thread_channel(bot, recipient, category, overwrites, *, name=None, errors_raised=None): name = name or bot.format_channel_name(recipient) + errors_raised = errors_raised or [] + try: channel = await bot.modmail_guild.create_text_channel( name=name, From 3f393e03a550c1137ac66e3170cdf9145669b28c Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 10 Oct 2021 00:47:01 +0800 Subject: [PATCH 454/705] New regex to properly match/parse channel topics. --- cogs/modmail.py | 2 +- core/thread.py | 52 +++++++++++++++++++++++------------- core/utils.py | 71 ++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 91 insertions(+), 34 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 4a974b26cc..e3c19d8182 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1848,7 +1848,7 @@ async def repair(self, ctx): and message.embeds[0].color.value == self.bot.main_color and message.embeds[0].footer.text ): - user_id = match_user_id(message.embeds[0].footer.text) + user_id = match_user_id(message.embeds[0].footer.text, any_string=True) other_recipients = match_other_recipients(ctx.channel.topic) for n, uid in enumerate(other_recipients): other_recipients[n] = self.bot.get_user(uid) or await self.bot.fetch_user(uid) diff --git a/core/thread.py b/core/thread.py index 6bc7adc6cb..5bb5ad577b 100644 --- a/core/thread.py +++ b/core/thread.py @@ -17,9 +17,9 @@ from core.utils import ( is_image_url, days, + parse_channel_topic, match_title, match_user_id, - match_other_recipients, truncate, get_top_hoisted_role, create_thread_channel, @@ -119,9 +119,8 @@ def cancelled(self, flag: bool): @classmethod async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChannel) -> "Thread": - recipient_id = match_user_id( - channel.topic - ) # there is a chance it grabs from another recipient's main thread + # there is a chance it grabs from another recipient's main thread + _, recipient_id, other_ids = parse_channel_topic(channel.topic) if recipient_id in manager.cache: thread = manager.cache[recipient_id] @@ -129,7 +128,7 @@ async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChann recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id) other_recipients = [] - for uid in match_other_recipients(channel.topic): + for uid in other_ids: try: other_recipient = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid) except discord.NotFound: @@ -1162,23 +1161,31 @@ async def _update_users_genesis(self): await genesis_message.edit(embed=embed) async def add_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: - title = match_title(self.channel.topic) - user_id = match_user_id(self.channel.topic) + title, user_id, _ = parse_channel_topic(self.channel.topic) + if title is not None: + title = f"Title: {title}\n" + else: + title = "" + self._other_recipients += users ids = ",".join(str(i.id) for i in self._other_recipients) - await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + await self.channel.edit(topic=f"{title}User ID: {user_id}\nOther Recipients: {ids}") await self._update_users_genesis() async def remove_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: - title = match_title(self.channel.topic) - user_id = match_user_id(self.channel.topic) + title, user_id, _ = parse_channel_topic(self.channel.topic) + if title is not None: + title = f"Title: {title}\n" + else: + title = "" + for u in users: self._other_recipients.remove(u) ids = ",".join(str(i.id) for i in self._other_recipients) - await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + await self.channel.edit(topic=f"{title}User ID: {user_id}\nOther Recipients: {ids}") await self._update_users_genesis() @@ -1240,16 +1247,24 @@ async def find( await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: + + def check(topic): + _, user_id, other_ids = parse_channel_topic(topic) + return recipient_id == user_id or recipient_id in other_ids + channel = discord.utils.find( - lambda x: str(recipient_id) in x.topic if x.topic else False, + lambda x: (check(x.topic)) if x.topic else False, self.bot.modmail_guild.text_channels, ) if channel: thread = await Thread.from_channel(self, channel) if thread.recipient: - # only save if data is valid - self.cache[recipient_id] = thread + # only save if data is valid. + # also the recipient_id here could belong to other recipient, + # it would be wrong if we set it as the dict key, + # so we use the thread id instead + self.cache[thread.id] = thread thread.ready = True if thread and recipient_id not in [x.id for x in thread.recipients]: @@ -1265,10 +1280,11 @@ async def _find_from_channel(self, channel): searching channel history for genesis embed and extracts user_id from that. """ - user_id = -1 - if channel.topic: - user_id = match_user_id(channel.topic) + if not channel.topic: + return None + + _, user_id, other_ids = parse_channel_topic(channel.topic) if user_id == -1: return None @@ -1282,7 +1298,7 @@ async def _find_from_channel(self, channel): recipient = None other_recipients = [] - for uid in match_other_recipients(channel.topic): + for uid in other_ids: try: other_recipient = self.bot.get_user(uid) or await self.bot.fetch_user(uid) except discord.NotFound: diff --git a/core/utils.py b/core/utils.py index 0fa74e457a..c87635b861 100644 --- a/core/utils.py +++ b/core/utils.py @@ -20,9 +20,11 @@ "human_join", "days", "cleanup_code", + "parse_channel_topic", "match_title", "match_user_id", "match_other_recipients", + "create_thread_channel", "create_not_found_embed", "parse_alias", "normalize_alias", @@ -218,9 +220,45 @@ def cleanup_code(content: str) -> str: return content.strip("` \n") -TOPIC_OTHER_RECIPIENTS_REGEX = re.compile(r"Other Recipients:\s*((?:\d{17,21},*)+)", flags=re.IGNORECASE) -TOPIC_TITLE_REGEX = re.compile(r"\bTitle: (.*)\n(?:User ID: )\b", flags=re.IGNORECASE | re.DOTALL) -TOPIC_UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) +TOPIC_REGEX = re.compile( + r"\b(Title: (?P.*)\n)?" + r"\bUser ID:\s*(?P<user_id>\d{17,21})\b" + r"(\nOther Recipients:\s*(?P<other_ids>(\d{17,21},?)+))?", + flags=re.IGNORECASE | re.DOTALL, +) +UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) + + +def parse_channel_topic(text: str) -> typing.Tuple[typing.Optional[str], int, typing.List[int]]: + """ + A helper to parse channel topics and respectivefully returns all the required values + at once. + + Parameters + ---------- + text : str + The text of channel topic. + + Returns + ------- + Tuple[Optional[str], int, List[int]] + A tuple of title, user ID, and other recipients IDs. + """ + title, user_id, other_ids = None, -1, [] + match = TOPIC_REGEX.search(text) + if match is not None: + groupdict = match.groupdict() + title = groupdict["title"] + + # user ID string is the required one in regex, so if match is found + # the value of this won't be None + user_id = int(groupdict["user_id"]) + + oth_ids = groupdict["other_ids"] + if oth_ids: + other_ids = list(map(int, oth_ids.split(","))) + + return title, user_id, other_ids def match_title(text: str) -> str: @@ -237,12 +275,10 @@ def match_title(text: str) -> str: Optional[str] The title if found. """ - match = TOPIC_TITLE_REGEX.search(text) - if match is not None: - return match.group(1) + return parse_channel_topic(text)[0] -def match_user_id(text: str) -> int: +def match_user_id(text: str, any_string: bool = False) -> int: """ Matches a user ID in the format of "User ID: 12345". @@ -250,16 +286,24 @@ def match_user_id(text: str) -> int: ---------- text : str The text of the user ID. + any_string: bool + Whether to search any string that matches the UID_REGEX, e.g. not from channel topic. + Defaults to False. Returns ------- int The user ID if found. Otherwise, -1. """ - match = TOPIC_UID_REGEX.search(text) - if match is not None: - return int(match.group(1)) - return -1 + user_id = -1 + if any_string: + match = UID_REGEX.search(text) + if match is not None: + user_id = int(match.group(1)) + else: + user_id = parse_channel_topic(text)[1] + + return user_id def match_other_recipients(text: str) -> typing.List[int]: @@ -276,10 +320,7 @@ def match_other_recipients(text: str) -> typing.List[int]: List[int] The list of other recipients IDs. """ - match = TOPIC_OTHER_RECIPIENTS_REGEX.search(text) - if match is not None: - return list(map(int, match.group(1).split(","))) - return [] + return parse_channel_topic(text)[2] def create_not_found_embed(word, possibilities, name, n=2, cutoff=0.6) -> discord.Embed: From 219ef56e512273561497998b0f61c2959a789e38 Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Mon, 11 Oct 2021 07:09:39 +0800 Subject: [PATCH 455/705] Only add title and other recipients strings in channel topic if any. --- core/thread.py | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/core/thread.py b/core/thread.py index 5bb5ad577b..2a2a243ba1 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1135,10 +1135,16 @@ def get_notifications(self) -> str: return " ".join(set(mentions)) async def set_title(self, title: str) -> None: + topic = f"Title: {title}\n" + user_id = match_user_id(self.channel.topic) - ids = ",".join(i.id for i in self._other_recipients) + topic += f"User ID: {user_id}" + + if self._other_recipients: + ids = ",".join(str(i.id) for i in self._other_recipients) + topic += f"\nOther Recipients: {ids}" - await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}") + await self.channel.edit(topic=topic) async def _update_users_genesis(self): genesis_message = await self.get_genesis_message() @@ -1161,32 +1167,37 @@ async def _update_users_genesis(self): await genesis_message.edit(embed=embed) async def add_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: + topic = "" title, user_id, _ = parse_channel_topic(self.channel.topic) if title is not None: - title = f"Title: {title}\n" - else: - title = "" + topic += f"Title: {title}\n" - self._other_recipients += users + topic += f"User ID: {user_id}" + self._other_recipients += users ids = ",".join(str(i.id) for i in self._other_recipients) - await self.channel.edit(topic=f"{title}User ID: {user_id}\nOther Recipients: {ids}") + topic += f"\nOther Recipients: {ids}" + + await self.channel.edit(topic=topic) await self._update_users_genesis() async def remove_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: + topic = "" title, user_id, _ = parse_channel_topic(self.channel.topic) if title is not None: - title = f"Title: {title}\n" - else: - title = "" + topic += f"Title: {title}\n" + + topic += f"User ID: {user_id}" for u in users: self._other_recipients.remove(u) - ids = ",".join(str(i.id) for i in self._other_recipients) - await self.channel.edit(topic=f"{title}User ID: {user_id}\nOther Recipients: {ids}") + if self._other_recipients: + ids = ",".join(str(i.id) for i in self._other_recipients) + topic += f"\nOther Recipients: {ids}" + await self.channel.edit(topic=topic) await self._update_users_genesis() From 3d494bb32b7b0578406c5a8f5e62b1c20d642791 Mon Sep 17 00:00:00 2001 From: kato <78689486+TheDiscordHistorian@users.noreply.github.com> Date: Thu, 21 Oct 2021 09:39:16 +0600 Subject: [PATCH 456/705] Add phish checker plugin --- plugins/registry.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index b39ac345bd..ad8dbebaf9 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -247,5 +247,13 @@ "title": "Claim Thread", "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" + }, + "phishchecker": { + "repository": "TheDiscordHistorian/historian-cogs", + "branch": "main", + "description": "Deletes scam links from your server and optionally kick / ban the user.", + "title": "Scam Link Detector", + "icon_url": "https://cdn.discordapp.com/attachments/576521645540245505/895661244743299102/antifish.png", + "thumbnail_url": "https://cdn.discordapp.com/attachments/576521645540245505/895661244743299102/antifish.png" } } From 7be70c0150ad94881335623ff58eb20025a9dfed Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Tue, 2 Nov 2021 07:56:59 +0800 Subject: [PATCH 457/705] Fix regex to offer a bit more flexibility. Suggested by @Taaku18 --- core/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/utils.py b/core/utils.py index c87635b861..9f99333cca 100644 --- a/core/utils.py +++ b/core/utils.py @@ -221,9 +221,9 @@ def cleanup_code(content: str) -> str: TOPIC_REGEX = re.compile( - r"\b(Title: (?P<title>.*)\n)?" + r"(?:\bTitle:\s*(?P<title>.*)\n)?" r"\bUser ID:\s*(?P<user_id>\d{17,21})\b" - r"(\nOther Recipients:\s*(?P<other_ids>(\d{17,21},?)+))?", + r"(?:\nOther Recipients:\s*(?P<other_ids>\d{17,21}(?:(?:\s*,\s*)\d{17,21})*)\b)?", flags=re.IGNORECASE | re.DOTALL, ) UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) From b02934dc64ad4fd272bd37370eb613ab66b94ef4 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Nov 2021 18:05:15 -0800 Subject: [PATCH 458/705] Added sponsor --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index f4b8e8d2ff..2b4f44ea62 100644 --- a/README.md +++ b/README.md @@ -190,12 +190,20 @@ Real Madrid: </a> <br> <br> +Advertise Your Server: +<br> +<a href='https://discord.gg/zP8KcF4VQz'> + <img height=100 src='https://user-images.githubusercontent.com/45324516/140673115-dd3e873c-36b6-4383-9eb4-db42e1986ab3.png' style='margin:5px'> +</a> +<br> +<br> Discord Advice Center: <br> <a href='https://discord.gg/zmwZy5fd9v'> <img height=100 src='https://i.imgur.com/1hrjcHd.png' style='margin:5px'> </a> + Become a sponsor on [Patreon](https://patreon.com/kyber). ## Plugins From 80dafcad0c689888d3e1a8e86f99b04f045ab7ed Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Sun, 7 Nov 2021 18:14:07 -0800 Subject: [PATCH 459/705] Update SPONSORS.json --- SPONSORS.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/SPONSORS.json b/SPONSORS.json index 30081e24e5..a1ec35d6dd 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -90,5 +90,20 @@ } ] } + }, + { + "embed": { + "title": "Advertise Your Server", + "description": "Advertise Your Server is the leading advertising and growth Discord Server. With over 60,000 members we can help grow your community with our range of services.\n\n__**Advertise Your Server offers everything you need to grow and find servers:**__\n\n:chart_with_upwards_trend: **Discord Growth Experts** to give you advice on how to __grow your server.__ (server/advert reviews, growth tips)\n:dividers: Over 40 different channels for **different server categories.**\n:robot: Our own __custom__ **bump bot.** (Liam)\n:bar_chart: Currently the __BIGGEST__ advertising server on Discord.\n:computer: Our own server __Listing Site__!\n:ticket: Small Servers Program for servers with less than 300 members.\n:dvd: Weekly Podcast, Blog, Email Newsletter and YouTube Tutorials. \n\nhttps://discord.gg/zP8KcF4VQz\nhttps://aysdiscord.com", + "author": { + "name": "Advertise Your Server", + "icon_url": "https://cdn.discordapp.com/attachments/563522692418895872/907067815486427176/logo4.png" + }, + "color": 431075, + "footer": { + "text": "Grow Your Discord Server" + }, + "image": "https://cdn.discordapp.com/attachments/472811257913933834/907068966311166043/unknown_2.png" + } } ] From 08b27ce731d5ac4f80a0557e836ba6d75cf9e983 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 19 Nov 2021 16:53:57 +0800 Subject: [PATCH 460/705] Fix typos #3116 --- bot.py | 1 + core/thread.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 86ef132b40..b47a694042 100644 --- a/bot.py +++ b/bot.py @@ -1694,6 +1694,7 @@ def main(): ) sys.exit(0) + # Set up discord.py internal logging if os.environ.get("LOG_DISCORD"): logger.debug(f"Discord logging enabled: {os.environ['LOG_DISCORD'].upper()}") d_logger = logging.getLogger("discord") diff --git a/core/thread.py b/core/thread.py index 6bc7adc6cb..3b4a1ef224 100644 --- a/core/thread.py +++ b/core/thread.py @@ -321,7 +321,7 @@ def _format_info_embed(self, user, log_url, log_count, color): created = str((time - user.created_at).days) user_info = [] if self.bot.config["thread_show_account_age"]: - user_info.append(f"was created {days(created)}") + user_info.append(f" was created {days(created)}") embed = discord.Embed(color=color, description=user.mention, timestamp=time) From b15a77b502a6ec13637fc2ec4da1b3cf6eedd96b Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Fri, 19 Nov 2021 17:08:38 +0800 Subject: [PATCH 461/705] Update changelog for PR-based changes --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85fc813322..8f5fd59670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.11.0 + +### Added + +- `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/kyb3r/modmail/pull/3093)) + +### Fixed + +- Several minor typos. ([PR #3095](https://github.com/kyb3r/modmail/pull/3095), [PR #3116](https://github.com/kyb3r/modmail/pull/3116)) +- Certain cases where fallback categories were not working as intended. ([PR #3109](https://github.com/kyb3r/modmail/pull/3109)) +- `?contact` would create in a random category in silent mode. ([GH #3091](https://github.com/kyb3r/modmail/issues/3091), [PR #3092](https://github.com/kyb3r/modmail/pull/3092)) +- Certain cases where `?close` would fail if closer isn't in cache. ([GH #3104](https://github.com/kyb3r/modmail/issues/3104), [PR #3105](https://github.com/kyb3r/modmail/pull/3105)) + +### Internal + +- Improve regex parsing of channel topics. ([PR #3111](https://github.com/kyb3r/modmail/pull/3111)) + # v3.10.3 ### Improved From 25ebb56605c576a0203875b62198f29f77be1d93 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:42:37 +0800 Subject: [PATCH 462/705] Update version --- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9730cd1339..75a3652454 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v3.10.3-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v3.11.0-dev1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index a0de88f8f7..432e6fdd11 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.3" +__version__ = "3.11.0-dev1" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 341e506413..797650d754 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.3' +version = '3.11.0-dev1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From f46d077ca7330d0c11ce537fcf17a8ce6e2d4d2a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 00:55:09 +0800 Subject: [PATCH 463/705] [BREAKING] Update discord.py to v2-master --- CHANGELOG.md | 6 + Pipfile | 2 +- Pipfile.lock | 733 ++++++++++++++++++++++++++-------------------- README.md | 6 +- bot.py | 96 +++--- cogs/modmail.py | 50 ++-- cogs/plugins.py | 2 +- cogs/utility.py | 29 +- core/changelog.py | 4 +- core/clients.py | 16 +- core/paginator.py | 16 +- core/thread.py | 34 +-- core/time.py | 10 +- core/utils.py | 6 +- requirements.txt | 18 +- 15 files changed, 570 insertions(+), 458 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f5fd59670..fe9ec8e3e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v3.11.0 +### Breaking + +- Upgraded to discord.py v2.0 master ([internal changes](https://gist.github.com/apple502j/f75b4f24652f04de85c7084ffd73ec58)). +- Python 3.8 or higher is required. + ### Added - `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/kyb3r/modmail/pull/3093)) @@ -22,6 +27,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Internal - Improve regex parsing of channel topics. ([PR #3111](https://github.com/kyb3r/modmail/pull/3111)) +- Add warning if deploying on a developmental version. # v3.10.3 diff --git a/Pipfile b/Pipfile index 4ed01f5b70..51569d26e5 100644 --- a/Pipfile +++ b/Pipfile @@ -11,7 +11,7 @@ pylint = "~=2.9.3" [packages] aiohttp = "==3.7.4.post0" colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 -"discord.py" = "==1.7.3" +"discord.py" = {ref = "45d498c1b76deaf3b394d17ccf56112fa691d160", git = "https://github.com/Rapptz/discord.py.git"} emoji = "~=1.2.0" isodate = "~=0.6.0" motor = "~=2.4.0" diff --git a/Pipfile.lock b/Pipfile.lock index a9f820119e..e1a77d86b5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0e726213f83b90d7c4e90a04cea6636dbdc5be2ad82049c96820535e5cc3d1ad" + "sha256": "aaa53487befe4f19feda64131fbc5bde140c1ec1a59ff2656d2ad1da2c50b390" }, "pipfile-spec": 6, "requires": { @@ -91,21 +91,21 @@ "index": "pypi", "version": "==0.4.4" }, + "discord-py": { + "git": "https://github.com/Rapptz/discord.py.git", + "ref": "45d498c1b76deaf3b394d17ccf56112fa691d160" + }, "discord.py": { - "hashes": [ - "sha256:462cd0fe307aef8b29cbfa8dd613e548ae4b2cb581d46da9ac0d46fb6ea19408", - "sha256:c6f64db136de0e18e090f6752ea68bdd4ab0a61b82dfe7acecefa22d6477bb0c" - ], - "index": "pypi", - "version": "==1.7.3" + "git": "https://github.com/Rapptz/discord.py.git", + "ref": "45d498c1b76deaf3b394d17ccf56112fa691d160" }, "dnspython": { "hashes": [ - "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", - "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d" + "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216", + "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "version": "==2.1.0" }, "emoji": { "hashes": [ @@ -117,11 +117,11 @@ }, "idna": { "hashes": [ - "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", - "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3" + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], "markers": "python_version >= '3.5'", - "version": "==3.2" + "version": "==3.3" }, "isodate": { "hashes": [ @@ -141,46 +141,81 @@ }, "multidict": { "hashes": [ - "sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a", - "sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93", - "sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632", - "sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656", - "sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79", - "sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7", - "sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d", - "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5", - "sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224", - "sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26", - "sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea", - "sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348", - "sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6", - "sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76", - "sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1", - "sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f", - "sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952", - "sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a", - "sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37", - "sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9", - "sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359", - "sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8", - "sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da", - "sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3", - "sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d", - "sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf", - "sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841", - "sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d", - "sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93", - "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f", - "sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647", - "sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635", - "sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456", - "sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda", - "sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5", - "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281", - "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80" + "sha256:06560fbdcf22c9387100979e65b26fba0816c162b888cb65b845d3def7a54c9b", + "sha256:067150fad08e6f2dd91a650c7a49ba65085303fcc3decbd64a57dc13a2733031", + "sha256:0a2cbcfbea6dc776782a444db819c8b78afe4db597211298dd8b2222f73e9cd0", + "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce", + "sha256:0fed465af2e0eb6357ba95795d003ac0bdb546305cc2366b1fc8f0ad67cc3fda", + "sha256:116347c63ba049c1ea56e157fa8aa6edaf5e92925c9b64f3da7769bdfa012858", + "sha256:1b4ac3ba7a97b35a5ccf34f41b5a8642a01d1e55454b699e5e8e7a99b5a3acf5", + "sha256:1c7976cd1c157fa7ba5456ae5d31ccdf1479680dc9b8d8aa28afabc370df42b8", + "sha256:246145bff76cc4b19310f0ad28bd0769b940c2a49fc601b86bfd150cbd72bb22", + "sha256:25cbd39a9029b409167aa0a20d8a17f502d43f2efebfe9e3ac019fe6796c59ac", + "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e", + "sha256:2d1d55cdf706ddc62822d394d1df53573d32a7a07d4f099470d3cb9323b721b6", + "sha256:2e77282fd1d677c313ffcaddfec236bf23f273c4fba7cdf198108f5940ae10f5", + "sha256:32fdba7333eb2351fee2596b756d730d62b5827d5e1ab2f84e6cbb287cc67fe0", + "sha256:35591729668a303a02b06e8dba0eb8140c4a1bfd4c4b3209a436a02a5ac1de11", + "sha256:380b868f55f63d048a25931a1632818f90e4be71d2081c2338fcf656d299949a", + "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55", + "sha256:38ba256ee9b310da6a1a0f013ef4e422fca30a685bcbec86a969bd520504e341", + "sha256:3bc3b1621b979621cee9f7b09f024ec76ec03cc365e638126a056317470bde1b", + "sha256:3d2d7d1fff8e09d99354c04c3fd5b560fb04639fd45926b34e27cfdec678a704", + "sha256:517d75522b7b18a3385726b54a081afd425d4f41144a5399e5abd97ccafdf36b", + "sha256:5f79c19c6420962eb17c7e48878a03053b7ccd7b69f389d5831c0a4a7f1ac0a1", + "sha256:5f841c4f14331fd1e36cbf3336ed7be2cb2a8f110ce40ea253e5573387db7621", + "sha256:637c1896497ff19e1ee27c1c2c2ddaa9f2d134bbb5e0c52254361ea20486418d", + "sha256:6ee908c070020d682e9b42c8f621e8bb10c767d04416e2ebe44e37d0f44d9ad5", + "sha256:77f0fb7200cc7dedda7a60912f2059086e29ff67cefbc58d2506638c1a9132d7", + "sha256:7878b61c867fb2df7a95e44b316f88d5a3742390c99dfba6c557a21b30180cac", + "sha256:78c106b2b506b4d895ddc801ff509f941119394b89c9115580014127414e6c2d", + "sha256:8b911d74acdc1fe2941e59b4f1a278a330e9c34c6c8ca1ee21264c51ec9b67ef", + "sha256:93de39267c4c676c9ebb2057e98a8138bade0d806aad4d864322eee0803140a0", + "sha256:9416cf11bcd73c861267e88aea71e9fcc35302b3943e45e1dbb4317f91a4b34f", + "sha256:94b117e27efd8e08b4046c57461d5a114d26b40824995a2eb58372b94f9fca02", + "sha256:9815765f9dcda04921ba467957be543423e5ec6a1136135d84f2ae092c50d87b", + "sha256:98ec9aea6223adf46999f22e2c0ab6cf33f5914be604a404f658386a8f1fba37", + "sha256:a37e9a68349f6abe24130846e2f1d2e38f7ddab30b81b754e5a1fde32f782b23", + "sha256:a43616aec0f0d53c411582c451f5d3e1123a68cc7b3475d6f7d97a626f8ff90d", + "sha256:a4771d0d0ac9d9fe9e24e33bed482a13dfc1256d008d101485fe460359476065", + "sha256:a5635bcf1b75f0f6ef3c8a1ad07b500104a971e38d3683167b9454cb6465ac86", + "sha256:a9acb76d5f3dd9421874923da2ed1e76041cb51b9337fd7f507edde1d86535d6", + "sha256:ac42181292099d91217a82e3fa3ce0e0ddf3a74fd891b7c2b347a7f5aa0edded", + "sha256:b227345e4186809d31f22087d0265655114af7cda442ecaf72246275865bebe4", + "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7", + "sha256:b70913cbf2e14275013be98a06ef4b412329fe7b4f83d64eb70dce8269ed1e1a", + "sha256:b9aad49466b8d828b96b9e3630006234879c8d3e2b0a9d99219b3121bc5cdb17", + "sha256:baf1856fab8212bf35230c019cde7c641887e3fc08cadd39d32a421a30151ea3", + "sha256:bd6c9c50bf2ad3f0448edaa1a3b55b2e6866ef8feca5d8dbec10ec7c94371d21", + "sha256:c1ff762e2ee126e6f1258650ac641e2b8e1f3d927a925aafcfde943b77a36d24", + "sha256:c30ac9f562106cd9e8071c23949a067b10211917fdcb75b4718cf5775356a940", + "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac", + "sha256:cdd68778f96216596218b4e8882944d24a634d984ee1a5a049b300377878fa7c", + "sha256:ce8cacda0b679ebc25624d5de66c705bc53dcc7c6f02a7fb0f3ca5e227d80422", + "sha256:cfde464ca4af42a629648c0b0d79b8f295cf5b695412451716531d6916461628", + "sha256:d3def943bfd5f1c47d51fd324df1e806d8da1f8e105cc7f1c76a1daf0f7e17b0", + "sha256:d9b668c065968c5979fe6b6fa6760bb6ab9aeb94b75b73c0a9c1acf6393ac3bf", + "sha256:da7d57ea65744d249427793c042094c4016789eb2562576fb831870f9c878d9e", + "sha256:dc3a866cf6c13d59a01878cd806f219340f3e82eed514485e094321f24900677", + "sha256:df23c83398715b26ab09574217ca21e14694917a0c857e356fd39e1c64f8283f", + "sha256:dfc924a7e946dd3c6360e50e8f750d51e3ef5395c95dc054bc9eab0f70df4f9c", + "sha256:e4a67f1080123de76e4e97a18d10350df6a7182e243312426d508712e99988d4", + "sha256:e5283c0a00f48e8cafcecadebfa0ed1dac8b39e295c7248c44c665c16dc1138b", + "sha256:e58a9b5cc96e014ddf93c2227cbdeca94b56a7eb77300205d6e4001805391747", + "sha256:e6453f3cbeb78440747096f239d282cc57a2997a16b5197c9bc839099e1633d0", + "sha256:e6c4fa1ec16e01e292315ba76eb1d012c025b99d22896bd14a66628b245e3e01", + "sha256:e7d81ce5744757d2f05fc41896e3b2ae0458464b14b5a2c1e87a6a9d69aefaa8", + "sha256:ea21d4d5104b4f840b91d9dc8cbc832aba9612121eaba503e54eaab1ad140eb9", + "sha256:ecc99bce8ee42dcad15848c7885197d26841cb24fa2ee6e89d23b8993c871c64", + "sha256:f0bb0973f42ffcb5e3537548e0767079420aefd94ba990b61cf7bb8d47f4916d", + "sha256:f19001e790013ed580abfde2a4465388950728861b52f0da73e8e8a9418533c0", + "sha256:f76440e480c3b2ca7f843ff8a48dc82446b86ed4930552d736c0bac507498a52", + "sha256:f9bef5cff994ca3026fcc90680e326d1a19df9841c5e3d224076407cc21471a1", + "sha256:fc66d4016f6e50ed36fb39cd287a3878ffcebfa90008535c62e0e90a7ab713ae", + "sha256:fd77c8f3cba815aa69cb97ee2b2ef385c7c12ada9c734b0f3b32e26bb88bbf1d" ], "markers": "python_version >= '3.6'", - "version": "==5.1.0" + "version": "==5.2.0" }, "natural": { "hashes": [ @@ -202,107 +237,116 @@ "srv" ], "hashes": [ - "sha256:02dc0b0f48ed3cd06c13b7e31b066bf91e00dac5f8147b0a0a45f9009bfab857", - "sha256:053b4ebf91c7395d1fcd2ce6a9edff0024575b7b2de6781554a4114448a8adc9", - "sha256:070a4ef689c9438a999ec3830e69b208ff0d12251846e064d947f97d819d1d05", - "sha256:072ba7cb65c8aa4d5c5659bf6722ee85781c9d7816dc00679b8b6f3dff1ddafc", - "sha256:0b6055e0ef451ff73c93d0348d122a0750dddf323b9361de5835dac2f6cf7fc1", - "sha256:11f9e0cfc84ade088a38df2708d0b958bb76360181df1b2e1e1a41beaa57952b", - "sha256:18290649759f9db660972442aa606f845c368db9b08c4c73770f6da14113569b", - "sha256:186104a94d39b8412f8e3de385acd990a628346a4402d4f3a288a82b8660bd22", - "sha256:1970cfe2aec1bf74b40cf30c130ad10cd968941694630386db33e1d044c22a2e", - "sha256:19d4bd0fc29aa405bb1781456c9cfff9fceabb68543741eb17234952dbc2bbb0", - "sha256:1bab889ae7640eba739f67fcbf8eff252dddc60d4495e6ddd3a87cd9a95fdb52", - "sha256:1bc6fe7279ff40c6818db002bf5284aa03ec181ea1b1ceaeee33c289d412afa7", - "sha256:208debdcf76ed39ebf24f38509f50dc1c100e31e8653817fedb8e1f867850a13", - "sha256:2399a85b54f68008e483b2871f4a458b4c980469c7fe921595ede073e4844f1e", - "sha256:246ec420e4c8744fceb4e259f906211b9c198e1f345e6158dcd7cbad3737e11e", - "sha256:24f8aeec4d6b894a6128844e50ff423dd02462ee83addf503c598ee3a80ddf3d", - "sha256:255a35bf29185f44b412e31a927d9dcedda7c2c380127ecc4fbf2f61b72fa978", - "sha256:2dbfbbded947a83a3dffc2bd1ec4750c17e40904692186e2c55a3ad314ca0222", - "sha256:2e92aa32300a0b5e4175caec7769f482b292769807024a86d674b3f19b8e3755", - "sha256:316c1b8723afa9870567cd6dff35d440b2afeda53aa13da6c5ab85f98ed6f5ca", - "sha256:333bfad77aa9cd11711febfb75eed0bb537a1d022e1c252714dad38993590240", - "sha256:39dafa2eaf577d1969f289dc9a44501859a1897eb45bd589e93ce843fc610800", - "sha256:3ce83f17f641a62a4dfb0ba1b8a3c1ced7c842f511b5450d90c030c7828e3693", - "sha256:46d5ec90276f71af3a29917b30f2aec2315a2759b5f8d45b3b63a07ca8a070a3", - "sha256:48d5bc80ab0af6b60c4163c5617f5cd23f2f880d7600940870ea5055816af024", - "sha256:4ba0def4abef058c0e5101e05e3d5266e6fffb9795bbf8be0fe912a7361a0209", - "sha256:5af390fa9faf56c93252dab09ea57cd020c9123aa921b63a0ed51832fdb492e7", - "sha256:5e574664f1468872cd40f74e4811e22b1aa4de9399d6bcfdf1ee6ea94c017fcf", - "sha256:625befa3bc9b40746a749115cc6a15bf20b9bd7597ca55d646205b479a2c99c7", - "sha256:6261bee7c5abadeac7497f8f1c43e521da78dd13b0a2439f526a7b0fc3788824", - "sha256:657ad80de8ec9ed656f28844efc801a0802961e8c6a85038d97ff6f555ef4919", - "sha256:6b89dc51206e4971c5568c797991eaaef5dc2a6118d67165858ad11752dba055", - "sha256:6e66780f14c2efaf989cd3ac613b03ee6a8e3a0ba7b96c0bb14adca71a427e55", - "sha256:6fb3f85870ae26896bb44e67db94045f2ebf00c5d41e6b66cdcbb5afd644fc18", - "sha256:701e08457183da70ed96b35a6b43e6ba1df0b47c837b063cde39a1fbe1aeda81", - "sha256:70761fd3c576b027eec882b43ee0a8e5b22ff9c20cdf4d0400e104bc29e53e34", - "sha256:73b400fdc22de84bae0dbf1a22613928a41612ec0a3d6ed47caf7ad4d3d0f2ff", - "sha256:7412a36798966624dc4c57d64aa43c2d1100b348abd98daaac8e99e57d87e1d7", - "sha256:78ecb8d42f50d393af912bfb1fb1dcc9aabe9967973efb49ee577e8f1cea494c", - "sha256:7c6a9948916a7bbcc6d3a9f6fb75db1acb5546078023bfb3db6efabcd5a67527", - "sha256:7c72d08acdf573455b2b9d2b75b8237654841d63a48bc2327dc102c6ee89b75a", - "sha256:7d98ce3c42921bb91566121b658e0d9d59a9082a9bd6f473190607ff25ab637f", - "sha256:845a8b83798b2fb11b09928413cb32692866bfbc28830a433d9fa4c8c3720dd0", - "sha256:94d38eba4d1b5eb3e6bfece0651b855a35c44f32fd91f512ab4ba41b8c0d3e66", - "sha256:9a13661681d17e43009bb3e85e837aa1ec5feeea1e3654682a01b8821940f8b3", - "sha256:a0e5dff6701fa615f165306e642709e1c1550d5b237c5a7a6ea299886828bd50", - "sha256:a2239556ff7241584ce57be1facf25081669bb457a9e5cbe68cce4aae6567aa1", - "sha256:a325600c83e61e3c9cebc0c2b1c8c4140fa887f789085075e8f44c8ff2547eb9", - "sha256:a3566acfbcde46911c52810374ecc0354fdb841284a3efef6ff7105bc007e9a8", - "sha256:a634a4730ce0b0934ed75e45beba730968e12b4dafbb22f69b3b2f616d9e644e", - "sha256:a6d055f01b83b1a4df8bb0c61983d3bdffa913764488910af3620e5c2450bf83", - "sha256:a752ecd1a26000a6d67be7c9a2e93801994a8b3f866ac95b672fbc00225ca91a", - "sha256:a9ba2a63777027b06b116e1ea8248e66fd1bedc2c644f93124b81a91ddbf6d88", - "sha256:aaa038eafb7186a4abbb311fcf20724be9363645882bbce540bef4797e812a7a", - "sha256:af586e85144023686fb0af09c8cdf672484ea182f352e7ceead3d832de381e1b", - "sha256:b0a0cf39f589e52d801fdef418305562bc030cdf8929217463c8433c65fd5c2f", - "sha256:b1c4874331ab960429caca81acb9d2932170d66d6d6f87e65dc4507a85aca152", - "sha256:b3b5b3cbc3fdf4fcfa292529df2a85b5d9c7053913a739d3069af1e12e12219f", - "sha256:b542d56ed1b8d5cf3bb36326f814bd2fbe8812dfd2582b80a15689ea433c0e35", - "sha256:b6ea08758b6673610b3c5bdf47189286cf9c58b1077558706a2f6f8744922527", - "sha256:b754240daafecd9d5fce426b0fbaaed03f4ebb130745c8a4ae9231fffb8d75e5", - "sha256:b772bab31cbd9cb911e41e1a611ebc9497f9a32a7348e2747c38210f75c00f41", - "sha256:b88d1742159bc93a078733f9789f563cef26f5e370eba810476a71aa98e5fbc2", - "sha256:b8bf42d3b32f586f4c9e37541769993783a534ad35531ce8a4379f6fa664fba9", - "sha256:bc9ac81e73573516070d24ce15da91281922811f385645df32bd3c8a45ab4684", - "sha256:c188db6cf9e14dbbb42f5254292be96f05374a35e7dfa087cc2140f0ff4f10f6", - "sha256:c55782a55f4a013a78ac5b6ee4b8731a192dea7ab09f1b6b3044c96d5128edd4", - "sha256:c5cab230e7cabdae9ff23c12271231283efefb944c1b79bed79a91beb65ba547", - "sha256:cbf8672edeb7b7128c4a939274801f0e32bbf5159987815e3d1eace625264a46", - "sha256:cc2894fe91f31a513860238ede69fe47fada21f9e7ddfe73f7f9fef93a971e41", - "sha256:cda9e628b1315beec8341e8c04aac9a0b910650b05e0751e42e399d5694aeacb", - "sha256:ceae3ab9e11a27aaab42878f1d203600dfd24f0e43678b47298219a0f10c0d30", - "sha256:ced944dcdd561476deef7cb7bfd4987c69fffbfeff6d02ca4d5d4fd592d559b7", - "sha256:d04ca462cb99077e6c059e97c072957caf2918e6e4191e3161c01c439e0193de", - "sha256:d1131562ddc2ea8a446f66c2648d7dabec2b3816fc818528eb978a75a6d23b2e", - "sha256:d1740776b70367277323fafb76bcf09753a5cc9824f5d705bac22a34ff3668ea", - "sha256:d6e11ffd43184d529d6752d6dcb62b994f903038a17ea2168ef1910c96324d26", - "sha256:d73e10772152605f6648ba4410318594f1043bbfe36d2fadee7c4b8912eff7c5", - "sha256:da8288bc4a7807c6715416deed1c57d94d5e03e93537889e002bf985be503f1a", - "sha256:db93608a246da44d728842b8fa9e45aa9782db76955f634a707739a8d53ff544", - "sha256:dcd3d0009fbb6e454d729f8b22d0063bd9171c31a55e0f0271119bd4f2700023", - "sha256:dd1f49f949a658c4e8f81ed73f9aad25fcc7d4f62f767f591e749e30038c4e1d", - "sha256:dd6ff2192f34bd622883c745a56f492b1c9ccd44e14953e8051c33024a2947d5", - "sha256:e018a4921657c2d3f89c720b7b90b9182e277178a04a7e9542cc79d7d787ca51", - "sha256:e2b7670c0c8c6b501464150dd49dd0d6be6cb7f049e064124911cec5514fa19e", - "sha256:e7a33322e08021c37e89cae8ff06327503e8a1719e97c69f32c31cbf6c30d72c", - "sha256:e8a82e35d52ad6f867e88096a1a2b9bdc7ec4d5e65c7b4976a248bf2d1a32a93", - "sha256:e9faf8d4712d5ea301d74abfcf6dafe4b7f4af7936e91f283b0ad7bf69ed3e3a", - "sha256:ec5ca7c0007ce268048bbe0ffc6846ed1616cf3d8628b136e81d5e64ff3f52a2", - "sha256:eee42a1cc06565f6b21caa1f504ec15e07de7ebfd520ab57f8cb3308bc118e22", - "sha256:f2acf9bbcd514e901f82c4ca6926bbd2ae61716728f110b4343eb0a69612d018", - "sha256:f55c1ddcc1f6050b07d468ce594f55dbf6107b459e16f735d26818d7be1e9538", - "sha256:f6977a520bd96e097c8a37a8cbb9faa1ea99d21bf84190195056e25f688af73d", - "sha256:f94c7d22fb36b184734dded7345a04ec5f95130421c775b8b0c65044ef073f34", - "sha256:fa8957e9a1b202cb45e6b839c241cd986c897be1e722b81d2f32e9c6aeee80b0", - "sha256:fd3854148005c808c485c754a184c71116372263709958b42aefbef2e5dd373a", - "sha256:fe5872ce6f9627deac8314bdffd3862624227c3de4c17ef0cc78bbf0402999eb", - "sha256:ffbae429ba9e42d0582d3ac63fdb410338892468a2107d8ff68228ec9a39a0ed" + "sha256:02e0c088f189ca69fac094cb5f851b43bbbd7cec42114495777d4d8f297f7f8a", + "sha256:138248c542051eb462f88b50b0267bd5286d6661064bab06faa0ef6ac30cdb4b", + "sha256:13a7c6d055af58a1e9c505e736da8b6a2e95ccc8cec10b008143f7a536e5de8a", + "sha256:13d74bf3435c1e58d8fafccc0d5e87f246ae2c6e9cbef4b35e32a1c3759e354f", + "sha256:15dae01341571d0af51526b7a21648ca575e9375e16ba045c9860848dfa8952f", + "sha256:17238115e6d37f5423b046cb829f1ca02c4ea7edb163f5b8b88e0c975dc3fec9", + "sha256:180b405e17b90a877ea5dbc5efe7f4c171af4c89323148e100c0f12cedb86f12", + "sha256:1821ce4e5a293313947fd017bbd2d2535aa6309680fa29b33d0442d15da296ec", + "sha256:1a7b138a04fdd17849930dc8bf664002e17db38448850bfb96d200c9c5a8b3a1", + "sha256:1c4e51a3b69789b6f468a8e881a13f2d1e8f5e99e41f80fd44845e6ec0f701e1", + "sha256:1d55982e5335925c55e2b87467043866ce72bd30ea7e7e3eeed6ec3d95a806d4", + "sha256:1fa6f08ddb6975371777f97592d35c771e713ee2250e55618148a5e57e260aff", + "sha256:2174d3279b8e2b6d7613b338f684cd78ff7adf1e7ec5b7b7bde5609a129c9898", + "sha256:2462a68f6675da548e333fa299d8e9807e00f95a4d198cfe9194d7be69f40c9b", + "sha256:25fd76deabe9ea37c8360c362b32f702cc095a208dd1c5328189938ca7685847", + "sha256:287c2a0063267c1458c4ddf528b44063ce7f376a6436eea5bccd7f625bbc3b5e", + "sha256:2d3abe548a280b49269c7907d5b71199882510c484d680a5ea7860f30c4a695f", + "sha256:2fa101bb23619120673899694a65b094364269e597f551a87c4bdae3a474d726", + "sha256:2fda3b3fb5c0d159195ab834b322a23808f1b059bcc7e475765abeddee6a2529", + "sha256:303531649fa45f96b694054c1aa02f79bda32ef57affe42c5c339336717eed74", + "sha256:36806ee53a85c3ba73939652f2ced2961e6a77cfbae385cd83f2e24cd97964b7", + "sha256:37a63da5ee623acdf98e6d511171c8a5827a6106b0712c18af4441ef4f11e6be", + "sha256:3a2fcbd04273a509fa85285d9eccf17ab65ce440bd4f5e5a58c978e563cd9e9a", + "sha256:3b40e36d3036bfe69ba63ec8e746a390721f75467085a0384b528e1dda532c69", + "sha256:4168b6c425d783e81723fc3dc382d374a228ff29530436a472a36d9f27593e73", + "sha256:444c00ebc20f2f9dc62e34f7dc9453dc2f5f5a72419c8dccad6e26d546c35712", + "sha256:45d6b47d70ed44e3c40bef618ed61866c48176e7e5dff80d06d8b1a6192e8584", + "sha256:460bdaa3f65ddb5b7474ae08589a1763b5da1a78b8348351b9ba1c63b459d67d", + "sha256:47ed77f62c8417a86f9ad158b803f3459a636386cb9d3d4e9e7d6a82d051f907", + "sha256:48722e91981bb22a16b0431ea01da3e1cc5b96805634d3b8d3c2a5315c1ce7f1", + "sha256:49b0d92724d3fce1174fd30b0b428595072d5c6b14d6203e46a9ea347ae7b439", + "sha256:4a2d73a9281faefb273a5448f6d25f44ebd311ada9eb79b6801ae890508fe231", + "sha256:4f4bc64fe9cbd70d46f519f1e88c9e4677f7af18ab9cd4942abce2bcfa7549c3", + "sha256:5067c04d3b19c820faac6342854d887ade58e8d38c3db79b68c2a102bbb100e7", + "sha256:51437c77030bed72d57d8a61e22758e3c389b13fea7787c808030002bb05ca39", + "sha256:515e4708d6567901ffc06476a38abe2c9093733f52638235d9f149579c1d3de0", + "sha256:5183b698d6542219e4135de583b57bc6286bd37df7f645b688278eb919bfa785", + "sha256:56feb80ea1f5334ccab9bd16a5161571ab70392e51fcc752fb8a1dc67125f663", + "sha256:573e2387d0686976642142c50740dfc4d3494cc627e2a7d22782b99f70879055", + "sha256:58a67b3800476232f9989e533d0244060309451b436d46670a53e6d189f1a7e7", + "sha256:5e3833c001a04aa06a28c6fd9628256862a654c09b0f81c07734b5629bc014ab", + "sha256:5f5fe59328838fa28958cc06ecf94be585726b97d637012f168bc3c7abe4fd81", + "sha256:6235bf2157aa46e53568ed79b70603aa8874baa202d5d1de82fa0eb917696e73", + "sha256:63be03f7ae1e15e72a234637ec7941ef229c7ab252c9ff6af48bba1e5418961c", + "sha256:65f159c445761cab04b665fc448b3fc008aebc98e54fdcbfd1aff195ef1b1408", + "sha256:67e0b2ad3692f6d0335ae231a40de55ec395b6c2e971ad6f55b162244d1ec542", + "sha256:68409171ab2aa7ccd6e8e839233e4b8ddeec246383c9a3698614e814739356f9", + "sha256:6a96c04ce39d66df60d9ce89f4c254c4967bc7d9e2e2c52adc58f47be826ee96", + "sha256:6ead0126fb4424c6c6a4fdc603d699a9db7c03cdb8eac374c352a75fec8a820a", + "sha256:6eb6789f26c398c383225e1313c8e75a7d290d323b8eaf65f3f3ddd0eb8a5a3c", + "sha256:6f07888e3b73c0dfa46f12d098760494f5f23fd66923a6615edfe486e6a7649c", + "sha256:6f0f0a10f128ea0898e607d351ebfabf70941494fc94e87f12c76e2894d8e6c4", + "sha256:704879b6a54c45ad76cea7c6789c1ae7185050acea7afd15b58318fa1932ed45", + "sha256:7117bfd8827cfe550f65a3c399dcd6e02226197a91c6d11a3540c3e8efc686d6", + "sha256:712de1876608fd5d76abc3fc8ec55077278dd5044073fbe9492631c9a2c58351", + "sha256:75c7ef67b4b8ec070e7a4740764f6c03ec9246b59d95e2ae45c029d41cb9efa1", + "sha256:77dddf596fb065de29fb39992fbc81301f7fd0003be649b7fa7448c77ca53bed", + "sha256:7abc87e45b572eb6d17a50422e69a9e5d6f13e691e821fe2312df512500faa50", + "sha256:7d8cdd2f070c71366e64990653522cce84b08dc26ab0d1fa19aa8d14ee0cf9ba", + "sha256:81ce5f871f5d8e82615c8bd0b34b68a9650204c8b1a04ce7890d58c98eb66e39", + "sha256:837cdef094f39c6f4a2967abc646a412999c2540fbf5d3cce1dd3b671f4b876c", + "sha256:849e641cfed05c75d772f9e9018f42c5fbd00655d43d52da1b9c56346fd3e4cc", + "sha256:87114b995506e7584cf3daf891e419b5f6e7e383e7df6267494da3a76312aa22", + "sha256:87db421c9eb915b8d9a9a13c5b2ee338350e36ee83e26ff0adfc48abc5db3ac3", + "sha256:8851544168703fb519e95556e3b463fca4beeef7ed3f731d81a68c8268515d9d", + "sha256:891f541c7ed29b95799da0cd249ae1db1842777b564e8205a197b038c5df6135", + "sha256:8f87f53c9cd89010ae45490ec2c963ff18b31f5f290dc08b04151709589fe8d9", + "sha256:9641be893ccce7d192a0094efd0a0d9f1783a1ebf314b4128f8a27bfadb8a77c", + "sha256:979e34db4f3dc5710c18db437aaf282f691092b352e708cb2afd4df287698c76", + "sha256:9b62d84478f471fdb0dcea3876acff38f146bd23cbdbed15074fb4622064ec2e", + "sha256:a472ca3d43d33e596ff5836c6cc71c3e61be33f44fe1cfdab4a1100f4af60333", + "sha256:a5dbeeea6a375fbd79448b48a54c46fc9351611a03ef8398d2a40b684ce46194", + "sha256:a7430f3987d232e782304c109be1d0e6fff46ca6405cb2479e4d8d08cd29541e", + "sha256:a81e52dbf95f236a0c89a5abcd2b6e1331da0c0312f471c73fae76c79d2acf6b", + "sha256:aa434534cc91f51a85e3099dc257ee8034b3d2be77f2ca58fb335a686e3a681f", + "sha256:ab27d6d7d41a66d9e54269a290d27cd5c74f08e9add0054a754b4821026c4f42", + "sha256:adb37bf22d25a51b84d989a2a5c770d4514ac590201eea1cb50ce8c9c5257f1d", + "sha256:afb16330ab6efbbf995375ad94e970fa2f89bb46bd10d854b7047620fdb0d67d", + "sha256:b1b06038c9940a49c73db0aeb0f6809b308e198da1326171768cf68d843af521", + "sha256:b1e6d1cf4bd6552b5f519432cce1530c09e6b0aab98d44803b991f7e880bd332", + "sha256:bf2d9d62178bb5c05e77d40becf89c309b1966fbcfb5c306238f81bf1ec2d6a2", + "sha256:bfd073fea04061019a103a288847846b5ef40dfa2f73b940ed61e399ca95314f", + "sha256:c04e84ccf590933a266180286d8b6a5fc844078a5d934432628301bd8b5f9ca7", + "sha256:c0947d7be30335cb4c3d5d0983d8ebc8294ae52503cf1d596c926f7e7183900b", + "sha256:c2a17752f97a942bdb4ff4a0516a67c5ade1658ebe1ab2edacdec0b42e39fa75", + "sha256:c4653830375ab019b86d218c749ad38908b74182b2863d09936aa8d7f990d30e", + "sha256:c660fd1e4a4b52f79f7d134a3d31d452948477b7f46ff5061074a534c5805ba6", + "sha256:cb48ff6cc6109190e1ccf8ea1fc71cc244c9185813ce7d1c415dce991cfb8709", + "sha256:cef2675004d85d85a4ccc24730b73a99931547368d18ceeed1259a2d9fcddbc1", + "sha256:d1b98539b0de822b6f717498e59ae3e5ae2e7f564370ab513e6d0c060753e447", + "sha256:d6c6989c10008ac70c2bb2ad2b940fcfe883712746c89f7e3308c14c213a70d7", + "sha256:db3efec9dcecd96555d752215797816da40315d61878f90ca39c8e269791bf17", + "sha256:dc4749c230a71b34db50ac2481d9008bb17b67c92671c443c3b40e192fbea78e", + "sha256:dcf906c1f7a33e4222e4bff18da1554d69323bc4dd95fe867a6fa80709ee5f93", + "sha256:e2bccadbe313b11704160aaba5eec95d2da1aa663f02f41d2d1520d02bbbdcd5", + "sha256:e30cce3cc86d6082c8596b3fbee0d4f54bc4d337a4fa1bf536920e2e319e24f0", + "sha256:e5d6428b8b422ba5205140e8be11722fa7292a0bedaa8bc80fb34c92eb19ba45", + "sha256:e841695b5dbea38909ab2dbf17e91e9a823412d8d88d1ef77f1b94a7bc551c0f", + "sha256:eb65ec0255a0fccc47c87d44e505ef5180bfd71690bd5f84161b1f23949fb209", + "sha256:ed20ec5a01c43254f6047c5d8124b70d28e39f128c8ad960b437644fe94e1827", + "sha256:ed751a20840a31242e7bea566fcf93ba75bc11b33afe2777bbf46069c1af5094", + "sha256:ef8b927813c27c3bdfc82c55682d7767403bcdadfd9f9c0fc49f4be4553a877b", + "sha256:f43cacda46fc188f998e6d308afe1c61ff41dcb300949f4cbf731e9a0a5eb2d3", + "sha256:f44bea60fd2178d7153deef9621c4b526a93939da30010bba24d3408a98b0f79", + "sha256:fcc021530b7c71069132fe4846d95a3cdd74d143adc2f7e398d5fabf610f111c", + "sha256:fe16517b275031d61261a4e3941c411fb7c46a9cd012f02381b56e7907cc9e06", + "sha256:fe3ae4294d593da54862f0140fdcc89d1aeeb94258ca97f094119ed7f0e5882d" ], "index": "pypi", - "version": "==3.12.0" + "version": "==3.12.1" }, "python-dateutil": { "hashes": [ @@ -330,70 +374,111 @@ }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed", + "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9" ], - "version": "==3.10.0.0" + "markers": "python_version >= '3.6'", + "version": "==4.0.0" }, "uvloop": { "hashes": [ - "sha256:0de811931e90ae2da9e19ce70ffad73047ab0c1dba7c6e74f9ae1a3aabeb89bd", - "sha256:1ff05116ede1ebdd81802df339e5b1d4cab1dfbd99295bf27e90b4cec64d70e9", - "sha256:2d8ffe44ae709f839c54bacf14ed283f41bee90430c3b398e521e10f8d117b3a", - "sha256:5cda65fc60a645470b8525ce014516b120b7057b576fa876cdfdd5e60ab1efbb", - "sha256:63a3288abbc9c8ee979d7e34c34e780b2fbab3e7e53d00b6c80271119f277399", - "sha256:7522df4e45e4f25b50adbbbeb5bb9847495c438a628177099d2721f2751ff825", - "sha256:7f4b8a905df909a407c5791fb582f6c03b0d3b491ecdc1cdceaefbc9bf9e08f6", - "sha256:905f0adb0c09c9f44222ee02f6b96fd88b493478fffb7a345287f9444e926030", - "sha256:ae2b325c0f6d748027f7463077e457006b4fdb35a8788f01754aadba825285ee", - "sha256:e71fb9038bfcd7646ca126c5ef19b17e48d4af9e838b2bcfda7a9f55a6552a32" + "sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450", + "sha256:089b4834fd299d82d83a25e3335372f12117a7d38525217c2258e9b9f4578897", + "sha256:1e5f2e2ff51aefe6c19ee98af12b4ae61f5be456cd24396953244a30880ad861", + "sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c", + "sha256:3a19828c4f15687675ea912cc28bbcb48e9bb907c801873bd1519b96b04fb805", + "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d", + "sha256:647e481940379eebd314c00440314c81ea547aa636056f554d491e40503c8464", + "sha256:6ccd57ae8db17d677e9e06192e9c9ec4bd2066b77790f9aa7dede2cc4008ee8f", + "sha256:772206116b9b57cd625c8a88f2413df2fcfd0b496eb188b82a43bed7af2c2ec9", + "sha256:8e0d26fa5875d43ddbb0d9d79a447d2ace4180d9e3239788208527c4784f7cab", + "sha256:98d117332cc9e5ea8dfdc2b28b0a23f60370d02e1395f88f40d1effd2cb86c4f", + "sha256:b572256409f194521a9895aef274cea88731d14732343da3ecdb175228881638", + "sha256:bd53f7f5db562f37cd64a3af5012df8cac2c464c97e732ed556800129505bd64", + "sha256:bd8f42ea1ea8f4e84d265769089964ddda95eb2bb38b5cbe26712b0616c3edee", + "sha256:e814ac2c6f9daf4c36eb8e85266859f42174a4ff0d71b99405ed559257750382", + "sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228" ], "markers": "sys_platform != 'win32'", - "version": "==0.15.3" + "version": "==0.16.0" }, "yarl": { "hashes": [ - "sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e", - "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434", - "sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366", - "sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3", - "sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec", - "sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959", - "sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e", - "sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c", - "sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6", - "sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a", - "sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6", - "sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424", - "sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e", - "sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f", - "sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50", - "sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2", - "sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc", - "sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4", - "sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970", - "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10", - "sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0", - "sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406", - "sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896", - "sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643", - "sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721", - "sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478", - "sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724", - "sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e", - "sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8", - "sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96", - "sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25", - "sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76", - "sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2", - "sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2", - "sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c", - "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a", - "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71" + "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac", + "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8", + "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e", + "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746", + "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98", + "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125", + "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d", + "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d", + "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986", + "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d", + "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec", + "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8", + "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee", + "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3", + "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1", + "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd", + "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b", + "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de", + "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0", + "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8", + "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6", + "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245", + "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23", + "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332", + "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1", + "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c", + "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4", + "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0", + "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8", + "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832", + "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58", + "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6", + "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1", + "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52", + "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92", + "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185", + "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d", + "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d", + "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b", + "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739", + "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05", + "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63", + "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d", + "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa", + "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913", + "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe", + "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b", + "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b", + "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656", + "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1", + "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4", + "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e", + "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63", + "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271", + "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed", + "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d", + "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda", + "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265", + "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f", + "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c", + "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba", + "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c", + "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b", + "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523", + "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a", + "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef", + "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95", + "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72", + "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794", + "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41", + "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576", + "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59" ], "markers": "python_version >= '3.6'", - "version": "==1.6.3" + "version": "==1.7.2" } }, "develop": { @@ -406,19 +491,19 @@ }, "astroid": { "hashes": [ - "sha256:7b963d1c590d490f60d2973e57437115978d3a2529843f160b5003b721e1e925", - "sha256:83e494b02d75d07d4e347b27c066fd791c0c74fc96c613d1ea3de0c82c48168f" + "sha256:3975a0bd5373bdce166e60c851cfcbaf21ee96de80ec518c1f4cb3e94c3fb334", + "sha256:ab7f36e8a78b8e54a62028ba6beef7561db4cdb6f2a5009ecc44a6f42b5697ef" ], "markers": "python_version ~= '3.6'", - "version": "==2.6.5" + "version": "==2.6.6" }, "bandit": { "hashes": [ - "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07", - "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608" + "sha256:a81b00b5436e6880fa8ad6799bc830e02032047713cbb143a12939ac67eb756c", + "sha256:f5acd838e59c038a159b5c621cf0f8270b279e884eadd7b782d7491c02add0d4" ], "index": "pypi", - "version": "==1.7.0" + "version": "==1.7.1" }, "black": { "hashes": [ @@ -430,11 +515,11 @@ }, "click": { "hashes": [ - "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a", - "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6" + "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", + "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" ], "markers": "python_version >= '3.6'", - "version": "==8.0.1" + "version": "==8.0.3" }, "colorama": { "hashes": [ @@ -446,27 +531,27 @@ }, "gitdb": { "hashes": [ - "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0", - "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005" + "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd", + "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa" ], - "markers": "python_version >= '3.4'", - "version": "==4.0.7" + "markers": "python_version >= '3.6'", + "version": "==4.0.9" }, "gitpython": { "hashes": [ - "sha256:b838a895977b45ab6f0cc926a9045c8d1c44e2b653c1fcc39fe91f42c6e8f05b", - "sha256:fce760879cd2aebd2991b3542876dc5c4a909b30c9d69dfc488e504a8db37ee8" + "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647", + "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5" ], - "markers": "python_version >= '3.6'", - "version": "==3.1.18" + "markers": "python_version >= '3.7'", + "version": "==3.1.24" }, "isort": { "hashes": [ - "sha256:eed17b53c3e7912425579853d078a0832820f023191561fcee9d7cae424e0813", - "sha256:f65ce5bd4cbc6abdfbe29afc2f0245538ab358c14590912df638033f157d555e" + "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", + "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" ], "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", - "version": "==5.9.2" + "version": "==5.10.1" }, "lazy-object-proxy": { "hashes": [ @@ -519,124 +604,128 @@ }, "pbr": { "hashes": [ - "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd", - "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4" + "sha256:176e8560eaf61e127817ef93d8a844803abb27a4d4637f0ff3bb783129be2e0a", + "sha256:672d8ebee84921862110f23fcec2acea191ef58543d34dfe9ef3d9f13c31cddf" ], "markers": "python_version >= '2.6'", - "version": "==5.6.0" + "version": "==5.8.0" }, "pylint": { "hashes": [ - "sha256:1f333dc72ef7f5ea166b3230936ebcfb1f3b722e76c980cb9fe6b9f95e8d3172", - "sha256:748f81e5776d6273a6619506e08f1b48ff9bcb8198366a56821cf11aac14fc87" + "sha256:2e1a0eb2e8ab41d6b5dbada87f066492bb1557b12b76c47c2ee8aa8a11186594", + "sha256:8b838c8983ee1904b2de66cce9d0b96649a91901350e956d78f289c3bc87b48e" ], "index": "pypi", - "version": "==2.9.5" + "version": "==2.9.6" }, "pyyaml": { "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", - "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", - "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", - "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" + "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", + "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", + "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", + "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", + "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", + "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", + "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", + "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", + "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", + "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", + "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", + "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", + "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", + "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", + "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", + "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", + "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", + "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", + "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", + "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", + "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", + "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", + "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", + "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", + "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", + "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", + "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==5.4.1" + "markers": "python_version >= '3.6'", + "version": "==6.0" }, "regex": { "hashes": [ - "sha256:0eb2c6e0fcec5e0f1d3bcc1133556563222a2ffd2211945d7b1480c1b1a42a6f", - "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad", - "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a", - "sha256:1c78780bf46d620ff4fff40728f98b8afd8b8e35c3efd638c7df67be2d5cddbf", - "sha256:2366fe0479ca0e9afa534174faa2beae87847d208d457d200183f28c74eaea59", - "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d", - "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895", - "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4", - "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3", - "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222", - "sha256:422dec1e7cbb2efbbe50e3f1de36b82906def93ed48da12d1714cabcd993d7f0", - "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c", - "sha256:4f64fc59fd5b10557f6cd0937e1597af022ad9b27d454e182485f1db3008f417", - "sha256:564a4c8a29435d1f2256ba247a0315325ea63335508ad8ed938a4f14c4116a5d", - "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d", - "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761", - "sha256:59c00bb8dd8775473cbfb967925ad2c3ecc8886b3b2d0c90a8e2707e06c743f0", - "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026", - "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854", - "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb", - "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d", - "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068", - "sha256:89e5528803566af4df368df2d6f503c84fbfb8249e6631c7b025fe23e6bd0cde", - "sha256:99d8ab206a5270c1002bfcf25c51bf329ca951e5a169f3b43214fdda1f0b5f0d", - "sha256:9a854b916806c7e3b40e6616ac9e85d3cdb7649d9e6590653deb5b341a736cec", - "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa", - "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd", - "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b", - "sha256:cbe23b323988a04c3e5b0c387fe3f8f363bf06c0680daf775875d979e376bd26", - "sha256:ccb3d2190476d00414aab36cca453e4596e8f70a206e2aa8db3d495a109153d2", - "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f", - "sha256:db2b7df831c3187a37f3bb80ec095f249fa276dbe09abd3d35297fc250385694", - "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0", - "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407", - "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874", - "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035", - "sha256:ed693137a9187052fc46eedfafdcb74e09917166362af4cc4fddc3b31560e93d", - "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c", - "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5", - "sha256:f9392a4555f3e4cb45310a65b403d86b589adc773898c25a39184b1ba4db8985", - "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58" - ], - "version": "==2021.7.6" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "sha256:05b7d6d7e64efe309972adab77fc2af8907bb93217ec60aa9fe12a0dad35874f", + "sha256:0617383e2fe465732af4509e61648b77cbe3aee68b6ac8c0b6fe934db90be5cc", + "sha256:07856afef5ffcc052e7eccf3213317fbb94e4a5cd8177a2caa69c980657b3cb4", + "sha256:162abfd74e88001d20cb73ceaffbfe601469923e875caf9118333b1a4aaafdc4", + "sha256:2207ae4f64ad3af399e2d30dde66f0b36ae5c3129b52885f1bffc2f05ec505c8", + "sha256:30ab804ea73972049b7a2a5c62d97687d69b5a60a67adca07eb73a0ddbc9e29f", + "sha256:3b5df18db1fccd66de15aa59c41e4f853b5df7550723d26aa6cb7f40e5d9da5a", + "sha256:3c5fb32cc6077abad3bbf0323067636d93307c9fa93e072771cf9a64d1c0f3ef", + "sha256:416c5f1a188c91e3eb41e9c8787288e707f7d2ebe66e0a6563af280d9b68478f", + "sha256:432bd15d40ed835a51617521d60d0125867f7b88acf653e4ed994a1f8e4995dc", + "sha256:4aaa4e0705ef2b73dd8e36eeb4c868f80f8393f5f4d855e94025ce7ad8525f50", + "sha256:537ca6a3586931b16a85ac38c08cc48f10fc870a5b25e51794c74df843e9966d", + "sha256:53db2c6be8a2710b359bfd3d3aa17ba38f8aa72a82309a12ae99d3c0c3dcd74d", + "sha256:5537f71b6d646f7f5f340562ec4c77b6e1c915f8baae822ea0b7e46c1f09b733", + "sha256:6650f16365f1924d6014d2ea770bde8555b4a39dc9576abb95e3cd1ff0263b36", + "sha256:666abff54e474d28ff42756d94544cdfd42e2ee97065857413b72e8a2d6a6345", + "sha256:68a067c11463de2a37157930d8b153005085e42bcb7ad9ca562d77ba7d1404e0", + "sha256:780b48456a0f0ba4d390e8b5f7c661fdd218934388cde1a974010a965e200e12", + "sha256:788aef3549f1924d5c38263104dae7395bf020a42776d5ec5ea2b0d3d85d6646", + "sha256:7ee1227cf08b6716c85504aebc49ac827eb88fcc6e51564f010f11a406c0a667", + "sha256:7f301b11b9d214f83ddaf689181051e7f48905568b0c7017c04c06dfd065e244", + "sha256:83ee89483672b11f8952b158640d0c0ff02dc43d9cb1b70c1564b49abe92ce29", + "sha256:85bfa6a5413be0ee6c5c4a663668a2cad2cbecdee367630d097d7823041bdeec", + "sha256:9345b6f7ee578bad8e475129ed40123d265464c4cfead6c261fd60fc9de00bcf", + "sha256:93a5051fcf5fad72de73b96f07d30bc29665697fb8ecdfbc474f3452c78adcf4", + "sha256:962b9a917dd7ceacbe5cd424556914cb0d636001e393b43dc886ba31d2a1e449", + "sha256:98ba568e8ae26beb726aeea2273053c717641933836568c2a0278a84987b2a1a", + "sha256:a3feefd5e95871872673b08636f96b61ebef62971eab044f5124fb4dea39919d", + "sha256:b43c2b8a330a490daaef5a47ab114935002b13b3f9dc5da56d5322ff218eeadb", + "sha256:b483c9d00a565633c87abd0aaf27eb5016de23fed952e054ecc19ce32f6a9e7e", + "sha256:ba05430e819e58544e840a68b03b28b6d328aff2e41579037e8bab7653b37d83", + "sha256:ca5f18a75e1256ce07494e245cdb146f5a9267d3c702ebf9b65c7f8bd843431e", + "sha256:d5ca078bb666c4a9d1287a379fe617a6dccd18c3e8a7e6c7e1eb8974330c626a", + "sha256:da1a90c1ddb7531b1d5ff1e171b4ee61f6345119be7351104b67ff413843fe94", + "sha256:dba70f30fd81f8ce6d32ddeef37d91c8948e5d5a4c63242d16a2b2df8143aafc", + "sha256:dd33eb9bdcfbabab3459c9ee651d94c842bc8a05fabc95edf4ee0c15a072495e", + "sha256:e0538c43565ee6e703d3a7c3bdfe4037a5209250e8502c98f20fea6f5fdf2965", + "sha256:e1f54b9b4b6c53369f40028d2dd07a8c374583417ee6ec0ea304e710a20f80a0", + "sha256:e32d2a2b02ccbef10145df9135751abea1f9f076e67a4e261b05f24b94219e36", + "sha256:e71255ba42567d34a13c03968736c5d39bb4a97ce98188fafb27ce981115beec", + "sha256:ed2e07c6a26ed4bea91b897ee2b0835c21716d9a469a96c3e878dc5f8c55bb23", + "sha256:eef2afb0fd1747f33f1ee3e209bce1ed582d1896b240ccc5e2697e3275f037c7", + "sha256:f23222527b307970e383433daec128d769ff778d9b29343fb3496472dc20dabe", + "sha256:f341ee2df0999bfdf7a95e448075effe0db212a59387de1a70690e4acb03d4c6", + "sha256:f7f325be2804246a75a4f45c72d4ce80d2443ab815063cdf70ee8fb2ca59ee1b", + "sha256:f8af619e3be812a2059b212064ea7a640aff0568d972cd1b9e920837469eb3cb", + "sha256:fa8c626d6441e2d04b6ee703ef2d1e17608ad44c7cb75258c09dd42bacdfc64b", + "sha256:fbb9dc00e39f3e6c0ef48edee202f9520dafb233e8b51b06b8428cfcb92abd30", + "sha256:fff55f3ce50a3ff63ec8e2a8d3dd924f1941b250b0aac3d3d42b687eeff07a8e" + ], + "version": "==2021.11.10" }, "smmap": { "hashes": [ - "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182", - "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2" + "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", + "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" ], - "markers": "python_version >= '3.5'", - "version": "==4.0.0" + "markers": "python_version >= '3.6'", + "version": "==5.0.0" }, "stevedore": { "hashes": [ - "sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee", - "sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a" + "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c", + "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335" ], "markers": "python_version >= '3.6'", - "version": "==3.3.0" + "version": "==3.5.0" }, "toml": { "hashes": [ @@ -646,6 +735,14 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, + "typing-extensions": { + "hashes": [ + "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed", + "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9" + ], + "markers": "python_version >= '3.6'", + "version": "==4.0.0" + }, "wrapt": { "hashes": [ "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" diff --git a/README.md b/README.md index 75a3652454..81cc75929c 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,11 @@ </a> <a href="https://patreon.com/kyber"> - <img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Python 3.7"> + <img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Python 3.8"> </a> <a href="https://www.python.org/downloads/"> - <img src="https://img.shields.io/badge/Made%20With-Python%203.7-blue.svg?style=for-the-badge&logo=Python" alt="Made with Python 3.7"> + <img src="https://img.shields.io/badge/Made%20With-Python%203.8-blue.svg?style=for-the-badge&logo=Python" alt="Made with Python 3.8"> </a> <a href="https://github.com/ambv/black"> @@ -108,7 +108,7 @@ If you don't want to go through the trouble of setting up your very own Modmail ### Locally -Local hosting of Modmail is also possible. First, you will need [`Python 3.7`](https://www.python.org/downloads/release/python-376/). +Local hosting of Modmail is also possible. First, you will need [`Python 3.8`](https://www.python.org/downloads/release/python-376/). Follow the [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) and disregard deploying the Heroku bot application. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. diff --git a/bot.py b/bot.py index 432e6fdd11..a0d4043b55 100644 --- a/bot.py +++ b/bot.py @@ -22,8 +22,6 @@ from emoji import UNICODE_EMOJI from pkg_resources import parse_version -from core.utils import tryint - try: # noinspection PyUnresolvedReferences @@ -48,7 +46,7 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import normalize_alias, truncate +from core.utils import normalize_alias, truncate, tryint logger = getLogger(__name__) @@ -69,12 +67,10 @@ def __init__(self): super().__init__(command_prefix=None, intents=intents) # implemented in `get_prefix` self._session = None self._api = None - self.metadata_loop = None - self.autoupdate_loop = None self.formatter = SafeFormatter() self.loaded_cogs = ["cogs.modmail", "cogs.plugins", "cogs.utility"] self._connected = asyncio.Event() - self.start_time = datetime.utcnow() + self.start_time = discord.utils.utcnow() self._started = False self.config = ConfigManager(self) @@ -90,7 +86,7 @@ def __init__(self): @property def uptime(self) -> str: - now = datetime.utcnow() + now = discord.utils.utcnow() delta = now - self.start_time hours, remainder = divmod(int(delta.total_seconds()), 3600) minutes, seconds = divmod(remainder, 60) @@ -241,11 +237,7 @@ def stop_loop_on_completion(f): loop.stop() def _cancel_tasks(): - if sys.version_info < (3, 8): - task_retriever = asyncio.Task.all_tasks - else: - task_retriever = asyncio.all_tasks - + task_retriever = asyncio.all_tasks tasks = {t for t in task_retriever(loop=loop) if not t.done()} if not tasks: @@ -557,6 +549,13 @@ async def on_ready(self): logger.info("Receiving guild ID: %s", self.modmail_guild.id) logger.line() + if "dev" in __version__: + logger.warning( + "You are running a developmental version. This should not be used in production. (v%s)", + __version__, + ) + logger.line() + await self.threads.populate_cache() # closures @@ -565,7 +564,7 @@ async def on_ready(self): logger.line() for recipient_id, items in tuple(closures.items()): - after = (datetime.fromisoformat(items["time"]) - datetime.utcnow()).total_seconds() + after = (datetime.fromisoformat(items["time"]) - discord.utils.utcnow()).total_seconds() if after <= 0: logger.debug("Closing thread for recipient %s.", recipient_id) after = 0 @@ -598,13 +597,13 @@ async def on_ready(self): { "open": False, "title": None, - "closed_at": str(datetime.utcnow()), + "closed_at": str(discord.utils.utcnow()), "close_message": "Channel has been deleted, no closer found.", "closer": { "id": str(self.user.id), "name": self.user.name, "discriminator": self.user.discriminator, - "avatar_url": str(self.user.avatar_url), + "avatar_url": self.user.display_avatar.url, "mod": True, }, }, @@ -614,25 +613,6 @@ async def on_ready(self): else: logger.debug("Failed to close thread with channel %s, skipping.", log["channel_id"]) - if self.config.get("data_collection"): - self.metadata_loop = tasks.Loop( - self.post_metadata, - seconds=0, - minutes=0, - hours=1, - count=None, - reconnect=True, - loop=None, - ) - self.metadata_loop.before_loop(self.before_post_metadata) - self.metadata_loop.start() - - self.autoupdate_loop = tasks.Loop( - self.autoupdate, seconds=0, minutes=0, hours=1, count=None, reconnect=True, loop=None - ) - self.autoupdate_loop.before_loop(self.before_autoupdate) - self.autoupdate_loop.start() - other_guilds = [guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild}] if any(other_guilds): logger.warning( @@ -690,7 +670,7 @@ async def retrieve_emoji(self) -> typing.Tuple[str, str]: def check_account_age(self, author: discord.Member) -> bool: account_age = self.config.get("account_age") - now = datetime.utcnow() + now = discord.utils.utcnow() try: min_account_age = author.created_at + account_age @@ -712,7 +692,7 @@ def check_account_age(self, author: discord.Member) -> bool: def check_guild_age(self, author: discord.Member) -> bool: guild_age = self.config.get("guild_age") - now = datetime.utcnow() + now = discord.utils.utcnow() if not hasattr(author, "joined_at"): logger.warning("Not in guild, cannot verify guild_age, %s.", author.name) @@ -742,7 +722,7 @@ def check_manual_blocked_roles(self, author: discord.Member) -> bool: if str(r.id) in self.blocked_roles: blocked_reason = self.blocked_roles.get(str(r.id)) or "" - now = datetime.utcnow() + now = discord.utils.utcnow() # etc "blah blah blah... until 2019-10-14T21:12:45.559948." end_time = re.search(r"until ([^`]+?)\.$", blocked_reason) @@ -772,7 +752,7 @@ def check_manual_blocked(self, author: discord.Member) -> bool: return True blocked_reason = self.blocked_users.get(str(author.id)) or "" - now = datetime.utcnow() + now = discord.utils.utcnow() if blocked_reason.startswith("System Message:"): # Met the limits already, otherwise it would've been caught by the previous checks @@ -861,7 +841,7 @@ async def is_blocked( async def get_thread_cooldown(self, author: discord.Member): thread_cooldown = self.config.get("thread_cooldown") - now = datetime.utcnow() + now = discord.utils.utcnow() if thread_cooldown == isodate.Duration(): return @@ -932,7 +912,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: color=self.error_color, description=self.config["disabled_new_thread_response"], ) - embed.set_footer(text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon_url) + embed.set_footer(text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon.url) logger.info("A new thread was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) @@ -947,7 +927,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: ) embed.set_footer( text=self.config["disabled_current_thread_footer"], - icon_url=self.guild.icon_url, + icon_url=self.guild.icon.url, ) logger.info("A message was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -982,7 +962,7 @@ async def get_contexts(self, message, *, cls=commands.Context): ctx = cls(prefix=self.prefix, view=view, bot=self, message=message) thread = await self.threads.find(channel=ctx.channel) - if self._skip_check(message.author.id, self.user.id): + if message.author.id == self.user.id: # type: ignore return [ctx] prefixes = await self.get_prefix() @@ -1139,7 +1119,7 @@ async def on_message(self, message): color=self.main_color, ) if self.config["show_timestamp"]: - em.timestamp = datetime.utcnow() + em.timestamp = discord.utils.utcnow() if not self.config["silent_alert_on_mention"]: content = self.config["mention"] @@ -1329,7 +1309,7 @@ async def handle_react_to_contact(self, payload): ) embed.set_footer( text=self.config["disabled_new_thread_footer"], - icon_url=self.guild.icon_url, + icon_url=self.guild.icon.url, ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", @@ -1431,7 +1411,13 @@ async def on_message_delete(self, message): return message = message[0] embed = message.embeds[0] - embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=embed.footer.icon_url) + + if embed.footer.icon: + icon_url = embed.footer.icon.url + else: + icon_url = discord.Embed.Empty + + embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=icon_url) await message.edit(embed=embed) return @@ -1521,21 +1507,23 @@ async def on_command_error(self, context, exception): else: logger.error("Unexpected exception:", exc_info=exception) + @tasks.loop(hours=1) async def post_metadata(self): info = await self.application_info() + delta = discord.utils.utcnow() - self.start_time data = { "bot_id": self.user.id, "bot_name": str(self.user), - "avatar_url": str(self.user.avatar_url), + "avatar_url": self.user.display_avatar.url, "guild_id": self.guild_id, "guild_name": self.guild.name, "member_count": len(self.guild.members), - "uptime": (datetime.utcnow() - self.start_time).total_seconds(), + "uptime": delta.total_seconds(), "latency": f"{self.ws.latency * 1000:.4f}", "version": str(self.version), "selfhosted": True, - "last_updated": str(datetime.utcnow()), + "last_updated": str(discord.utils.utcnow()), } if info.team is not None: @@ -1552,13 +1540,16 @@ async def post_metadata(self): async with self.session.post("https://api.modmail.dev/metadata", json=data): logger.debug("Uploading metadata to Modmail server.") + @post_metadata.before_loop async def before_post_metadata(self): await self.wait_for_connected() + if not self.config.get("data_collection") or not self.guild: + self.post_metadata.cancel() + logger.debug("Starting metadata loop.") logger.line("debug") - if not self.guild: - self.metadata_loop.cancel() + @tasks.loop(hours=1) async def autoupdate(self): changelog = await Changelog.from_url(self) latest = changelog.latest_version @@ -1637,6 +1628,7 @@ async def autoupdate(self): await channel.send(embed=embed) return await self.close() + @autoupdate.before_loop async def before_autoupdate(self): await self.wait_for_connected() logger.debug("Starting autoupdate loop") @@ -1696,9 +1688,9 @@ def main(): pass # check discord version - if discord.__version__ != "1.7.3": + if discord.__version__ != "2.0.0a": logger.error( - "Dependencies are not updated, run pipenv install. discord.py version expected 1.7.3, received %s", + "Dependencies are not updated, run pipenv install. discord.py version expected 2.0.0a, received %s", discord.__version__, ) sys.exit(0) diff --git a/cogs/modmail.py b/cogs/modmail.py index 6da8ce0772..60c18594ac 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -158,7 +158,7 @@ async def snippet(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any snippets at the moment." ) embed.set_footer(text=f'Check "{self.bot.prefix}help snippet add" to add a snippet.') - embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url) + embed.set_author(name="Snippets", icon_url=ctx.guild.icon.url) return await ctx.send(embed=embed) embeds = [] @@ -166,7 +166,7 @@ async def snippet(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): description = format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url) + embed.set_author(name="Snippets", icon_url=ctx.guild.icon.url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -396,7 +396,7 @@ async def close(self, ctx, *, after: UserFriendlyTime = None): thread = ctx.thread - now = datetime.utcnow() + now = discord.utils.utcnow() close_after = (after.dt - now).total_seconds() if after else 0 message = after.arg if after else None @@ -643,7 +643,7 @@ def format_log_embeds(self, logs, avatar_url): embed = discord.Embed(color=self.bot.main_color, timestamp=created_at) embed.set_author(name=f"{title} - {username}", icon_url=avatar_url, url=log_url) embed.url = log_url - embed.add_field(name="Created", value=duration(created_at, now=datetime.utcnow())) + embed.add_field(name="Created", value=duration(created_at, now=discord.utils.utcnow())) closer = entry.get("closer") if closer is None: closer_msg = "Unknown" @@ -745,8 +745,8 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=str(ctx.author), icon_url=ctx.author.avatar_url) + em.timestamp = discord.utils.utcnow() + em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) for u in users: await u.send(embed=em) @@ -761,8 +761,8 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) + em.timestamp = discord.utils.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) for i in ctx.thread.recipients: if i not in users: @@ -834,8 +834,8 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=str(ctx.author), icon_url=ctx.author.avatar_url) + em.timestamp = discord.utils.utcnow() + em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) for u in users: await u.send(embed=em) @@ -850,8 +850,8 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) + em.timestamp = discord.utils.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) for i in ctx.thread.recipients: if i not in users: @@ -914,7 +914,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() + em.timestamp = discord.utils.utcnow() tag = self.bot.config["mod_tag"] if tag is None: @@ -924,7 +924,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.guild.icon_url + avatar_url = self.bot.guild.icon.url em.set_footer(text=name, icon_url=avatar_url) for u in users: @@ -940,8 +940,8 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) + em.timestamp = discord.utils.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) for i in ctx.thread.recipients: if i not in users: @@ -999,7 +999,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() + em.timestamp = discord.utils.utcnow() tag = self.bot.config["mod_tag"] if tag is None: @@ -1009,7 +1009,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.guild.icon_url + avatar_url = self.bot.guild.icon.url em.set_footer(text=name, icon_url=avatar_url) for u in users: @@ -1025,8 +1025,8 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].avatar_url) + em.timestamp = discord.utils.utcnow() + em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) for i in ctx.thread.recipients: if i not in users: @@ -1086,7 +1086,7 @@ async def logs_closed_by(self, ctx, *, user: User = None): user = user if user is not None else ctx.author entries = await self.bot.api.search_closed_by(user.id) - embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) + embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon.url) if not embeds: embed = discord.Embed( @@ -1136,7 +1136,7 @@ async def logs_responded(self, ctx, *, user: User = None): entries = await self.bot.api.get_responded_logs(user.id) - embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) + embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon.url) if not embeds: embed = discord.Embed( @@ -1161,7 +1161,7 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): entries = await self.bot.api.search_by_text(query, limit) - embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) + embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon.url) if not embeds: embed = discord.Embed( @@ -1452,8 +1452,8 @@ async def contact( color=self.bot.main_color, ) if self.bot.config["show_timestamp"]: - em.timestamp = datetime.utcnow() - em.set_footer(text=f"{creator}", icon_url=creator.avatar_url) + em.timestamp = discord.utils.utcnow() + em.set_footer(text=f"{creator}", icon_url=creator.display_avatar.url) for u in users: await u.send(embed=em) diff --git a/cogs/plugins.py b/cogs/plugins.py index 4cdd0aba3f..e9adf2a240 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -730,7 +730,7 @@ async def plugins_registry_compact(self, ctx): for page in pages: embed = discord.Embed(color=self.bot.main_color, description=page) - embed.set_author(name="Plugin Registry", icon_url=self.bot.user.avatar_url) + embed.set_author(name="Plugin Registry", icon_url=self.bot.user.display_avatar.url) embeds.append(embed) paginator = EmbedPaginatorSession(ctx, *embeds) diff --git a/cogs/utility.py b/cogs/utility.py index bc813e9d6e..7278c350fc 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -5,7 +5,6 @@ import re import traceback from contextlib import redirect_stdout -from datetime import datetime from difflib import get_close_matches from io import BytesIO, StringIO from itertools import takewhile, zip_longest @@ -54,7 +53,7 @@ async def command_callback(self, ctx, *, command=None): async def format_cog_help(self, cog, *, no_cog=False): bot = self.context.bot - prefix = self.clean_prefix + prefix = self.context.clean_prefix formats = [""] for cmd in await self.filter_commands( @@ -92,7 +91,7 @@ async def format_cog_help(self, cog, *, no_cog=False): continued = " (Continued)" if embeds else "" name = cog.qualified_name + " - Help" if not no_cog else "Miscellaneous Commands" - embed.set_author(name=name + continued, icon_url=bot.user.avatar_url) + embed.set_author(name=name + continued, icon_url=bot.user.display_avatar.url) embed.set_footer( text=f'Type "{prefix}{self.command_attrs["name"]} command" ' @@ -102,7 +101,7 @@ async def format_cog_help(self, cog, *, no_cog=False): return embeds def process_help_msg(self, help_: str): - return help_.format(prefix=self.clean_prefix) if help_ else "No help message." + return help_.format(prefix=self.context.clean_prefix) if help_ else "No help message." async def send_bot_help(self, mapping): embeds = [] @@ -174,7 +173,7 @@ async def send_group_help(self, group): embed.add_field(name="Sub Command(s)", value=format_[:1024], inline=False) embed.set_footer( - text=f'Type "{self.clean_prefix}{self.command_attrs["name"]} command" ' + text=f'Type "{self.context.clean_prefix}{self.command_attrs["name"]} command" ' "for more info on a command." ) @@ -216,7 +215,7 @@ async def send_error_message(self, error): embed.add_field(name=f"Step {i}:", value=val) embed.set_footer( - text=f'Type "{self.clean_prefix}{self.command_attrs["name"]} alias" ' + text=f'Type "{self.context.clean_prefix}{self.command_attrs["name"]} alias" ' "for more details on aliases." ) return await self.get_destination().send(embed=embed) @@ -238,7 +237,7 @@ async def send_error_message(self, error): else: embed.title = "Cannot find command or category" embed.set_footer( - text=f'Type "{self.clean_prefix}{self.command_attrs["name"]}" ' + text=f'Type "{self.context.clean_prefix}{self.command_attrs["name"]}" ' "for a list of all available commands." ) await self.get_destination().send(embed=embed) @@ -303,13 +302,13 @@ async def changelog(self, ctx, version: str.lower = ""): @utils.trigger_typing async def about(self, ctx): """Shows information about this bot.""" - embed = discord.Embed(color=self.bot.main_color, timestamp=datetime.utcnow()) + embed = discord.Embed(color=self.bot.main_color, timestamp=discord.utils.utcnow()) embed.set_author( name="Modmail - About", - icon_url=self.bot.user.avatar_url, + icon_url=self.bot.user.display_avatar.url, url="https://discord.gg/F34cRU8", ) - embed.set_thumbnail(url=self.bot.user.avatar_url) + embed.set_thumbnail(url=self.bot.user.display_avatar.url) desc = "This is an open source Discord bot that serves as a means for " desc += "members to easily communicate with server administrators in " @@ -848,7 +847,7 @@ async def config_get(self, ctx, *, key: str.lower = None): if key in keys: desc = f"`{key}` is set to `{self.bot.config[key]}`" embed = discord.Embed(color=self.bot.main_color, description=desc) - embed.set_author(name="Config variable", icon_url=self.bot.user.avatar_url) + embed.set_author(name="Config variable", icon_url=self.bot.user.display_avatar.url) else: embed = discord.Embed( @@ -865,7 +864,7 @@ async def config_get(self, ctx, *, key: str.lower = None): color=self.bot.main_color, description="Here is a list of currently set configuration variable(s).", ) - embed.set_author(name="Current config(s):", icon_url=self.bot.user.avatar_url) + embed.set_author(name="Current config(s):", icon_url=self.bot.user.display_avatar.url) config = self.bot.config.filter_default(self.bot.config) for name, value in config.items(): @@ -1006,7 +1005,7 @@ async def alias(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any aliases at the moment." ) embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') - embed.set_author(name="Aliases", icon_url=ctx.guild.icon_url) + embed.set_author(name="Aliases", icon_url=ctx.guild.icon.url) return await ctx.send(embed=embed) embeds = [] @@ -1014,7 +1013,7 @@ async def alias(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.aliases)),) * 15)): description = utils.format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Command Aliases", icon_url=ctx.guild.icon_url) + embed.set_author(name="Command Aliases", icon_url=ctx.guild.icon.url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1595,7 +1594,7 @@ async def permissions_get( for name, level in takewhile(lambda x: x is not None, items) ) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Permission Overrides", icon_url=ctx.guild.icon_url) + embed.set_author(name="Permission Overrides", icon_url=ctx.guild.icon.url) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) diff --git a/core/changelog.py b/core/changelog.py index 7c9af2e1bb..4ede9f09f1 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -90,14 +90,14 @@ def embed(self) -> Embed: embed = Embed(color=self.bot.main_color, description=self.description) embed.set_author( name=f"v{self.version} - Changelog", - icon_url=self.bot.user.avatar_url, + icon_url=self.bot.user.display_avatar.url, url=self.url, ) for name, value in self.fields.items(): embed.add_field(name=name, value=truncate(value, 1024), inline=False) embed.set_footer(text=f"Current version: v{self.bot.version}") - embed.set_thumbnail(url=self.bot.user.avatar_url) + embed.set_thumbnail(url=self.bot.user.display_avatar.url) return embed diff --git a/core/clients.py b/core/clients.py index 489954e3e4..5caf58f4d2 100644 --- a/core/clients.py +++ b/core/clients.py @@ -1,9 +1,9 @@ import secrets import sys -from datetime import datetime from json import JSONDecodeError from typing import Union, Optional +import discord from discord import Member, DMChannel, TextChannel, Message from discord.ext import commands @@ -507,7 +507,7 @@ async def create_log_entry(self, recipient: Member, channel: TextChannel, creato "_id": key, "key": key, "open": True, - "created_at": str(datetime.utcnow()), + "created_at": str(discord.utils.utcnow()), "closed_at": None, "channel_id": str(channel.id), "guild_id": str(self.bot.guild_id), @@ -516,14 +516,14 @@ async def create_log_entry(self, recipient: Member, channel: TextChannel, creato "id": str(recipient.id), "name": recipient.name, "discriminator": recipient.discriminator, - "avatar_url": str(recipient.avatar_url), + "avatar_url": recipient.display_avatar.url, "mod": False, }, "creator": { "id": str(creator.id), "name": creator.name, "discriminator": creator.discriminator, - "avatar_url": str(creator.avatar_url), + "avatar_url": creator.display_avatar.url, "mod": isinstance(creator, Member), }, "closer": None, @@ -585,7 +585,7 @@ async def append_log( "id": str(message.author.id), "name": message.author.name, "discriminator": message.author.discriminator, - "avatar_url": str(message.author.avatar_url), + "avatar_url": message.author.display_avatar.url, "mod": not isinstance(message.channel, DMChannel), }, "content": message.content, @@ -635,7 +635,7 @@ async def create_note(self, recipient: Member, message: Message, message_id: Uni "id": str(message.author.id), "name": message.author.name, "discriminator": message.author.discriminator, - "avatar_url": str(message.author.avatar_url), + "avatar_url": message.author.display_avatar.url, }, "message": message.content, "message_id": str(message_id), @@ -666,7 +666,7 @@ async def update_repository(self) -> dict: "data": data, "user": { "username": user.username, - "avatar_url": user.avatar_url, + "avatar_url": user.display_avatar.url, "url": user.url, }, } @@ -680,7 +680,7 @@ async def get_user_info(self) -> Optional[dict]: return { "user": { "username": user.username, - "avatar_url": user.avatar_url, + "avatar_url": user.display_avatar.url, "url": user.url, } } diff --git a/core/paginator.py b/core/paginator.py index 7ba1c98b60..934b4670be 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -209,7 +209,13 @@ def __init__(self, ctx: commands.Context, *embeds, **options): footer_text = f"Page {i + 1} of {len(self.pages)}" if embed.footer.text: footer_text = footer_text + " • " + embed.footer.text - embed.set_footer(text=footer_text, icon_url=embed.footer.icon_url) + + if embed.footer.icon: + icon_url = embed.footer.icon.url + else: + icon_url = Embed.Empty + + embed.set_footer(text=footer_text, icon_url=icon_url) def add_page(self, item: Embed) -> None: if isinstance(item, Embed): @@ -241,7 +247,13 @@ def _set_footer(self): footer_text = f"Page {self.current+1} of {len(self.pages)}" if self.footer_text: footer_text = footer_text + " • " + self.footer_text - self.embed.set_footer(text=footer_text, icon_url=self.embed.footer.icon_url) + + if self.embed.footer.icon: + icon_url = self.embed.footer.icon.url + else: + icon_url = Embed.Empty + + self.embed.set_footer(text=footer_text, icon_url=icon_url) async def _create_base(self, item: str) -> None: self._set_footer() diff --git a/core/thread.py b/core/thread.py index 536e68b595..2550ab0ad9 100644 --- a/core/thread.py +++ b/core/thread.py @@ -4,7 +4,7 @@ import re import time import typing -from datetime import datetime, timedelta +from datetime import timedelta from types import SimpleNamespace import isodate @@ -159,7 +159,7 @@ async def setup(self, *, creator=None, category=None, initial_message=None): category = category or self.bot.main_category if category is not None: - overwrites = None + overwrites = {} try: channel = await create_thread_channel(self.bot, recipient, category, overwrites) @@ -224,7 +224,7 @@ async def send_recipient_genesis_message(): else: footer = self.bot.config["thread_creation_footer"] - embed.set_footer(text=footer, icon_url=self.bot.guild.icon_url) + embed.set_footer(text=footer, icon_url=self.bot.guild.icon.url) embed.title = self.bot.config["thread_creation_title"] if creator is None or creator == recipient: @@ -250,7 +250,7 @@ class Author: name = author["name"] id = author["id"] discriminator = author["discriminator"] - avatar_url = author["avatar_url"] + display_avatar = SimpleNamespace(url=author["avatar_url"]) data = { "id": round(time.time() * 1000 - discord.utils.DISCORD_EPOCH) << 22, @@ -264,7 +264,7 @@ class Author: "content": note["message"], "author": Author(), } - message = discord.Message(state=State(), channel=None, data=data) + message = discord.Message(state=State(), channel=self.channel, data=data) ids[note["_id"]] = str((await self.note(message, persistent=True, thread_creation=True)).id) await self.bot.api.update_note_ids(ids) @@ -290,7 +290,7 @@ def _format_info_embed(self, user, log_url, log_count, color): """Get information about a member of a server supports users from the guild or not.""" member = self.bot.guild.get_member(user.id) - time = datetime.utcnow() + time = discord.utils.utcnow() # key = log_url.split('/')[-1] @@ -329,7 +329,7 @@ def _format_info_embed(self, user, log_url, log_count, color): else: footer = f"User ID: {user.id}" - embed.set_author(name=str(user), icon_url=user.avatar_url, url=log_url) + embed.set_author(name=str(user), icon_url=user.display_avatar.url, url=log_url) # embed.set_thumbnail(url=avi) if member is not None: @@ -382,7 +382,7 @@ async def close( if after > 0: # TODO: Add somewhere to clean up broken closures # (when channel is already deleted) - now = datetime.utcnow() + now = discord.utils.utcnow() items = { # 'initiation_time': now.isoformat(), "time": (now + timedelta(seconds=after)).isoformat(), @@ -425,14 +425,14 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, { "open": False, "title": match_title(self.channel.topic), - "closed_at": str(datetime.utcnow()), + "closed_at": str(discord.utils.utcnow()), "nsfw": self.channel.nsfw, "close_message": message, "closer": { "id": str(closer.id), "name": closer.name, "discriminator": closer.discriminator, - "avatar_url": str(closer.avatar_url), + "avatar_url": closer.display_avatar.url, "mod": True, }, }, @@ -483,8 +483,8 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, event = "Thread Closed as Scheduled" if scheduled else "Thread Closed" # embed.set_author(name=f"Event: {event}", url=log_url) - embed.set_footer(text=f"{event} by {_closer}", icon_url=closer.avatar_url) - embed.timestamp = datetime.utcnow() + embed.set_footer(text=f"{event} by {_closer}", icon_url=closer.display_avatar.url) + embed.timestamp = discord.utils.utcnow() tasks = [self.bot.config.update()] @@ -498,7 +498,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, color=self.bot.error_color, ) if self.bot.config["show_timestamp"]: - embed.timestamp = datetime.utcnow() + embed.timestamp = discord.utils.utcnow() if not message: if self.id == closer.id: @@ -512,7 +512,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, embed.description = message footer = self.bot.config["thread_close_footer"] - embed.set_footer(text=footer, icon_url=self.bot.guild.icon_url) + embed.set_footer(text=footer, icon_url=self.bot.guild.icon.url) if not silent: for user in self.recipients: @@ -558,7 +558,7 @@ async def _restart_close_timer(self): # Set timeout seconds seconds = timeout.total_seconds() # seconds = 20 # Uncomment to debug with just 20 seconds - reset_time = datetime.utcnow() + timedelta(seconds=seconds) + reset_time = discord.utils.utcnow() + timedelta(seconds=seconds) human_time = human_timedelta(dt=reset_time) if self.bot.config.get("thread_auto_close_silently"): @@ -943,7 +943,7 @@ async def send( name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.guild.icon_url + avatar_url = self.bot.guild.icon.url embed.set_author( name=name, icon_url=avatar_url, @@ -952,7 +952,7 @@ async def send( else: # Normal message name = str(author) - avatar_url = author.avatar_url + avatar_url = author.display_avatar.url embed.set_author( name=name, icon_url=avatar_url, diff --git a/core/time.py b/core/time.py index bdec8d2549..376f2074eb 100644 --- a/core/time.py +++ b/core/time.py @@ -6,6 +6,7 @@ import re from datetime import datetime +import discord from discord.ext.commands import BadArgument, Converter import parsedatetime as pdt @@ -13,6 +14,7 @@ from core.models import getLogger + logger = getLogger(__name__) @@ -36,7 +38,7 @@ def __init__(self, argument): raise BadArgument("Invalid time provided.") data = {k: int(v) for k, v in match.groupdict(default="0").items()} - now = datetime.utcnow() + now = discord.utils.utcnow() self.dt = now + relativedelta(**data) @@ -50,7 +52,7 @@ class HumanTime: calendar = pdt.Calendar(version=pdt.VERSION_CONTEXT_STYLE) def __init__(self, argument): - now = datetime.utcnow() + now = discord.utils.utcnow() dt, status = self.calendar.parseDT(argument, sourceTime=now) if not status.hasDateOrTime: raise BadArgument('Invalid time provided, try e.g. "tomorrow" or "3 days".') @@ -104,7 +106,7 @@ def convert(self, ctx, argument): try: calendar = HumanTime.calendar regex = ShortTime.compiled - self.dt = self.now = datetime.utcnow() + self.dt = self.now = discord.utils.utcnow() match = regex.match(argument) if match is not None and match.group(0): @@ -186,7 +188,7 @@ async def convert(self, ctx, argument): def human_timedelta(dt, *, source=None): - now = source or datetime.utcnow() + now = source or discord.utils.utcnow() if dt > now: delta = relativedelta(dt, now) suffix = "" diff --git a/core/utils.py b/core/utils.py index 1440b9c8eb..9b56cbe31d 100644 --- a/core/utils.py +++ b/core/utils.py @@ -245,7 +245,11 @@ def parse_channel_topic(text: str) -> typing.Tuple[typing.Optional[str], int, ty A tuple of title, user ID, and other recipients IDs. """ title, user_id, other_ids = None, -1, [] - match = TOPIC_REGEX.search(text) + if isinstance(text, str): + match = TOPIC_REGEX.search(text) + else: + match = None + if match is not None: groupdict = match.groupdict() title = groupdict["title"] diff --git a/requirements.txt b/requirements.txt index d802cc0c46..fb43d23e2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,19 +11,19 @@ async-timeout==3.0.1; python_full_version >= '3.5.3' attrs==21.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' colorama==0.4.4 -discord.py==1.7.3 -dnspython==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +dnspython==2.1.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.2.0 -idna==3.2; python_version >= '3.5' +git+https://github.com/Rapptz/discord.py.git@45d498c1b76deaf3b394d17ccf56112fa691d160#egg=discord-py +idna==3.3; python_version >= '3.5' isodate==0.6.0 motor==2.4.0 -multidict==5.1.0; python_version >= '3.6' +multidict==5.2.0; python_version >= '3.6' natural==0.2.0 parsedatetime==2.6 -pymongo[srv]==3.11.4 -python-dateutil==2.8.1 +pymongo[srv]==3.12.1 +python-dateutil==2.8.2 python-dotenv==0.18.0 six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -typing-extensions==3.10.0.0 -uvloop==0.15.2; sys_platform != 'win32' -yarl==1.6.3; python_version >= '3.6' +typing-extensions==4.0.0; python_version >= '3.6' +uvloop==0.16.0; sys_platform != 'win32' +yarl==1.7.2; python_version >= '3.6' \ No newline at end of file From 96a9af069554050387e2b02c69949c07e1ad0b40 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 00:58:58 +0800 Subject: [PATCH 464/705] Update bandit baseline --- .bandit_baseline.json | 62 +++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/.bandit_baseline.json b/.bandit_baseline.json index 28a4e47b9c..12aa666e27 100644 --- a/.bandit_baseline.json +++ b/.bandit_baseline.json @@ -1,6 +1,6 @@ { "errors": [], - "generated_at": "2020-11-26T11:00:36Z", + "generated_at": "2021-11-20T16:58:19Z", "metrics": { "./bot.py": { "CONFIDENCE.HIGH": 1.0, @@ -11,7 +11,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1321, + "loc": 1412, "nosec": 0 }, "./cogs/modmail.py": { @@ -23,7 +23,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1273, + "loc": 1688, "nosec": 0 }, "./cogs/plugins.py": { @@ -35,7 +35,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 578, + "loc": 597, "nosec": 0 }, "./cogs/utility.py": { @@ -47,7 +47,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1755, + "loc": 1767, "nosec": 0 }, "./core/_color_data.py": { @@ -71,7 +71,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 155, + "loc": 159, "nosec": 0 }, "./core/checks.py": { @@ -83,7 +83,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 90, + "loc": 105, "nosec": 0 }, "./core/clients.py": { @@ -95,7 +95,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 587, + "loc": 598, "nosec": 0 }, "./core/config.py": { @@ -107,7 +107,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 352, + "loc": 377, "nosec": 0 }, "./core/decorators.py": { @@ -131,7 +131,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 202, + "loc": 204, "nosec": 0 }, "./core/paginator.py": { @@ -143,7 +143,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 209, + "loc": 217, "nosec": 0 }, "./core/thread.py": { @@ -155,7 +155,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 996, + "loc": 1138, "nosec": 0 }, "./core/time.py": { @@ -167,7 +167,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 158, + "loc": 157, "nosec": 0 }, "./core/utils.py": { @@ -179,19 +179,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 282, - "nosec": 0 - }, - "./plugins/kyb3r/modmail-plugins/profanity-filter-master/profanity-filter.py": { - "CONFIDENCE.HIGH": 0.0, - "CONFIDENCE.LOW": 0.0, - "CONFIDENCE.MEDIUM": 0.0, - "CONFIDENCE.UNDEFINED": 0.0, - "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 0.0, - "SEVERITY.MEDIUM": 0.0, - "SEVERITY.UNDEFINED": 0.0, - "loc": 81, + "loc": 389, "nosec": 0 }, "_totals": { @@ -203,20 +191,20 @@ "SEVERITY.LOW": 5.0, "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 9214, + "loc": 9983, "nosec": 0 } }, "results": [ { - "code": "11 from datetime import datetime\n12 from subprocess import PIPE\n13 from types import SimpleNamespace\n", + "code": "13 from datetime import datetime\n14 from subprocess import PIPE\n15 from types import SimpleNamespace\n", "filename": "./bot.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", - "line_number": 12, + "line_number": 14, "line_range": [ - 12 + 14 ], "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", "test_id": "B404", @@ -238,28 +226,28 @@ "test_name": "blacklist" }, { - "code": "13 from json import JSONDecodeError, loads\n14 from subprocess import PIPE\n15 from textwrap import indent\n", + "code": "11 from json import JSONDecodeError, loads\n12 from subprocess import PIPE\n13 from textwrap import indent\n", "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", - "line_number": 14, + "line_number": 12, "line_range": [ - 14 + 12 ], "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", "test_id": "B404", "test_name": "blacklist" }, { - "code": "2039 try:\n2040 exec(to_compile, env) # pylint: disable=exec-used\n2041 except Exception as exc:\n", + "code": "2060 try:\n2061 exec(to_compile, env) # pylint: disable=exec-used\n2062 except Exception as exc:\n", "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "MEDIUM", "issue_text": "Use of exec detected.", - "line_number": 2040, + "line_number": 2061, "line_range": [ - 2040 + 2061 ], "more_info": "https://bandit.readthedocs.io/en/latest/plugins/b102_exec_used.html", "test_id": "B102", @@ -280,7 +268,7 @@ "test_name": "blacklist" }, { - "code": "67 \n68 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n69 self.bot = bot\n70 self.session = bot.session\n71 self.headers: dict = None\n72 self.access_token = access_token\n73 self.username = username\n74 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n75 self.url: str = kwargs.pop(\"url\", \"\")\n76 if self.access_token:\n77 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n78 \n79 @property\n80 def BRANCH(self):\n", + "code": "67 \n68 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n69 self.bot = bot\n70 self.session = bot.session\n71 self.headers: Optional[dict] = None\n72 self.access_token = access_token\n73 self.username = username\n74 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n75 self.url: str = kwargs.pop(\"url\", \"\")\n76 if self.access_token:\n77 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n78 \n79 @property\n80 def BRANCH(self):\n", "filename": "./core/clients.py", "issue_confidence": "MEDIUM", "issue_severity": "LOW", From a1aacbfb817f6410d9c8b4fce41bbd0e1e55b6b3 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 20 Nov 2021 19:07:11 +0200 Subject: [PATCH 465/705] Update bandit baseline: --- .bandit_baseline.json | 60 +++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/.bandit_baseline.json b/.bandit_baseline.json index 28a4e47b9c..76153c873f 100644 --- a/.bandit_baseline.json +++ b/.bandit_baseline.json @@ -1,6 +1,6 @@ { "errors": [], - "generated_at": "2020-11-26T11:00:36Z", + "generated_at": "2021-11-20T17:06:28Z", "metrics": { "./bot.py": { "CONFIDENCE.HIGH": 1.0, @@ -11,7 +11,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1321, + "loc": 1406, "nosec": 0 }, "./cogs/modmail.py": { @@ -23,7 +23,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1273, + "loc": 1678, "nosec": 0 }, "./cogs/plugins.py": { @@ -35,7 +35,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 578, + "loc": 597, "nosec": 0 }, "./cogs/utility.py": { @@ -47,7 +47,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1755, + "loc": 1768, "nosec": 0 }, "./core/_color_data.py": { @@ -71,7 +71,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 155, + "loc": 159, "nosec": 0 }, "./core/checks.py": { @@ -83,7 +83,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 90, + "loc": 105, "nosec": 0 }, "./core/clients.py": { @@ -95,7 +95,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 587, + "loc": 598, "nosec": 0 }, "./core/config.py": { @@ -107,7 +107,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 352, + "loc": 375, "nosec": 0 }, "./core/decorators.py": { @@ -131,7 +131,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 202, + "loc": 204, "nosec": 0 }, "./core/paginator.py": { @@ -155,7 +155,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 996, + "loc": 1097, "nosec": 0 }, "./core/time.py": { @@ -167,7 +167,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 158, + "loc": 156, "nosec": 0 }, "./core/utils.py": { @@ -179,19 +179,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 282, - "nosec": 0 - }, - "./plugins/kyb3r/modmail-plugins/profanity-filter-master/profanity-filter.py": { - "CONFIDENCE.HIGH": 0.0, - "CONFIDENCE.LOW": 0.0, - "CONFIDENCE.MEDIUM": 0.0, - "CONFIDENCE.UNDEFINED": 0.0, - "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 0.0, - "SEVERITY.MEDIUM": 0.0, - "SEVERITY.UNDEFINED": 0.0, - "loc": 81, + "loc": 351, "nosec": 0 }, "_totals": { @@ -203,20 +191,20 @@ "SEVERITY.LOW": 5.0, "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 9214, + "loc": 9878, "nosec": 0 } }, "results": [ { - "code": "11 from datetime import datetime\n12 from subprocess import PIPE\n13 from types import SimpleNamespace\n", + "code": "13 from datetime import datetime\n14 from subprocess import PIPE\n15 from types import SimpleNamespace\n", "filename": "./bot.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", - "line_number": 12, + "line_number": 14, "line_range": [ - 12 + 14 ], "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", "test_id": "B404", @@ -238,28 +226,28 @@ "test_name": "blacklist" }, { - "code": "13 from json import JSONDecodeError, loads\n14 from subprocess import PIPE\n15 from textwrap import indent\n", + "code": "12 from json import JSONDecodeError, loads\n13 from subprocess import PIPE\n14 from textwrap import indent\n", "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", - "line_number": 14, + "line_number": 13, "line_range": [ - 14 + 13 ], "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", "test_id": "B404", "test_name": "blacklist" }, { - "code": "2039 try:\n2040 exec(to_compile, env) # pylint: disable=exec-used\n2041 except Exception as exc:\n", + "code": "2061 try:\n2062 exec(to_compile, env) # pylint: disable=exec-used\n2063 except Exception as exc:\n", "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "MEDIUM", "issue_text": "Use of exec detected.", - "line_number": 2040, + "line_number": 2062, "line_range": [ - 2040 + 2062 ], "more_info": "https://bandit.readthedocs.io/en/latest/plugins/b102_exec_used.html", "test_id": "B102", @@ -280,7 +268,7 @@ "test_name": "blacklist" }, { - "code": "67 \n68 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n69 self.bot = bot\n70 self.session = bot.session\n71 self.headers: dict = None\n72 self.access_token = access_token\n73 self.username = username\n74 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n75 self.url: str = kwargs.pop(\"url\", \"\")\n76 if self.access_token:\n77 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n78 \n79 @property\n80 def BRANCH(self):\n", + "code": "67 \n68 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n69 self.bot = bot\n70 self.session = bot.session\n71 self.headers: Optional[dict] = None\n72 self.access_token = access_token\n73 self.username = username\n74 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n75 self.url: str = kwargs.pop(\"url\", \"\")\n76 if self.access_token:\n77 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n78 \n79 @property\n80 def BRANCH(self):\n", "filename": "./core/clients.py", "issue_confidence": "MEDIUM", "issue_severity": "LOW", From 126455760831a019283943fc00ca75334a475da0 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 01:25:45 +0800 Subject: [PATCH 466/705] Support PNG/APNG stickers --- CHANGELOG.md | 1 + core/thread.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe9ec8e3e1..4e4cd95bde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Certain cases where fallback categories were not working as intended. ([PR #3109](https://github.com/kyb3r/modmail/pull/3109)) - `?contact` would create in a random category in silent mode. ([GH #3091](https://github.com/kyb3r/modmail/issues/3091), [PR #3092](https://github.com/kyb3r/modmail/pull/3092)) - Certain cases where `?close` would fail if closer isn't in cache. ([GH #3104](https://github.com/kyb3r/modmail/issues/3104), [PR #3105](https://github.com/kyb3r/modmail/pull/3105)) +- Stickers were not working in Modmail. ### Internal diff --git a/core/thread.py b/core/thread.py index 2550ab0ad9..eb0a23cd2c 100644 --- a/core/thread.py +++ b/core/thread.py @@ -989,8 +989,8 @@ async def send( images.extend(image_urls) images.extend( ( - str(i.image_url) if isinstance(i.image_url, discord.Asset) else i.image_url, - f"{i.name} Sticker", + i.url if i.format in (discord.StickerFormatType.png, discord.StickerFormatType.apng) else None, + i.name, True, ) for i in message.stickers @@ -1012,10 +1012,10 @@ async def send( if filename: if is_sticker: if url is None: - description = "Unable to retrieve sticker image" + description = f"{filename}: Unable to retrieve sticker image" else: - description = "\u200b" - embed.add_field(name=filename, value=description) + description = f"[{filename}]({url})" + embed.add_field(name="Sticker", value=description) else: embed.add_field(name="Image", value=f"[{filename}]({url})") embedded_image = True From 0ee363f64394f4ce9ceecc9b162a78e83b30288f Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sat, 20 Nov 2021 19:28:50 +0200 Subject: [PATCH 467/705] Update baseline --- .bandit_baseline.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bandit_baseline.json b/.bandit_baseline.json index 12aa666e27..c36cbc9f8e 100644 --- a/.bandit_baseline.json +++ b/.bandit_baseline.json @@ -1,6 +1,6 @@ { "errors": [], - "generated_at": "2021-11-20T16:58:19Z", + "generated_at": "2021-11-20T17:28:26Z", "metrics": { "./bot.py": { "CONFIDENCE.HIGH": 1.0, From 9121dce1c49fa3f64bd6b7ceb6fbef48d99c1463 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 01:31:31 +0800 Subject: [PATCH 468/705] Disable bandit --- .github/workflows/lints.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 145a83d489..091e012dd9 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -23,8 +23,8 @@ jobs: run: | python -m pip install --upgrade pip pipenv pipenv install --dev --system - - name: Bandit syntax check - run: bandit -r . -b .bandit_baseline.json + # - name: Bandit syntax check + # run: bandit -r . -b .bandit_baseline.json - name: Pylint run: pylint ./bot.py cogs/*.py core/*.py --exit-zero -r y continue-on-error: true From 50446d4fa02ae72d62ef713ad1dd1d54f179e7b8 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 01:33:49 +0800 Subject: [PATCH 469/705] Resolve linting --- core/thread.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index eb0a23cd2c..f7bf634435 100644 --- a/core/thread.py +++ b/core/thread.py @@ -989,7 +989,9 @@ async def send( images.extend(image_urls) images.extend( ( - i.url if i.format in (discord.StickerFormatType.png, discord.StickerFormatType.apng) else None, + i.url + if i.format in (discord.StickerFormatType.png, discord.StickerFormatType.apng) + else None, i.name, True, ) From f429c225ff5aeae5c05d41a5fa012848558602e5 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 01:40:35 +0800 Subject: [PATCH 470/705] Bump ver to 3.11.0-dev2 --- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 81cc75929c..cf62cfe5d6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v3.11.0-dev1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v3.11.0-dev2-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index a0d4043b55..fbb6ec9605 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.11.0-dev1" +__version__ = "3.11.0-dev2" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 797650d754..f1de75c772 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.11.0-dev1' +version = '3.11.0-dev2' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From fb2e9046e677eea0c5a2a0f0f5bcdb423a349d6a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 16:37:07 +0800 Subject: [PATCH 471/705] check for g.name==None #3088 --- CHANGELOG.md | 1 + bot.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e4cd95bde..75862c62da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?contact` would create in a random category in silent mode. ([GH #3091](https://github.com/kyb3r/modmail/issues/3091), [PR #3092](https://github.com/kyb3r/modmail/pull/3092)) - Certain cases where `?close` would fail if closer isn't in cache. ([GH #3104](https://github.com/kyb3r/modmail/issues/3104), [PR #3105](https://github.com/kyb3r/modmail/pull/3105)) - Stickers were not working in Modmail. +- Large server sizes results in Guild.name == None. ([GH #3088](https://github.com/kyb3r/modmail/issues/3088)) ### Internal diff --git a/bot.py b/bot.py index fbb6ec9605..fb9836010f 100644 --- a/bot.py +++ b/bot.py @@ -618,7 +618,7 @@ async def on_ready(self): logger.warning( "The bot is in more servers other than the main and staff server. " "This may cause data compromise (%s).", - ", ".join(guild.name for guild in other_guilds), + ", ".join(str(guild.name) for guild in other_guilds), ) logger.warning("If the external servers are valid, you may ignore this message.") From 33adfc30f7c4b309b21a45a76854126f13db84e6 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 17:10:01 +0800 Subject: [PATCH 472/705] Fix attachments in plain messages #3102 --- CHANGELOG.md | 1 + bot.py | 4 ++++ core/thread.py | 24 +++++++++++++----------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75862c62da..18935f9f23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Certain cases where `?close` would fail if closer isn't in cache. ([GH #3104](https://github.com/kyb3r/modmail/issues/3104), [PR #3105](https://github.com/kyb3r/modmail/pull/3105)) - Stickers were not working in Modmail. - Large server sizes results in Guild.name == None. ([GH #3088](https://github.com/kyb3r/modmail/issues/3088)) +- Attachments did not work on plain replies. ([GH #3102](https://github.com/kyb3r/modmail/issues/3102)) ### Internal diff --git a/bot.py b/bot.py index fb9836010f..c2e3ee5adf 100644 --- a/bot.py +++ b/bot.py @@ -50,6 +50,10 @@ logger = getLogger(__name__) +# # prevent "coroutine noop was never awaited" warning. +# asyncio.coroutines._DEBUG = False # type: ignore + + temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp") if not os.path.exists(temp_dir): os.mkdir(temp_dir) diff --git a/core/thread.py b/core/thread.py index f7bf634435..ff2ea791cd 100644 --- a/core/thread.py +++ b/core/thread.py @@ -4,6 +4,7 @@ import re import time import typing +import warnings from datetime import timedelta from types import SimpleNamespace @@ -835,6 +836,7 @@ async def reply( user_msg = await asyncio.gather(*user_msg_tasks) except Exception as e: logger.error("Message delivery failed:", exc_info=True) + user_msg = None if isinstance(e, discord.Forbidden): description = ( "Your message could not be delivered as " @@ -848,12 +850,10 @@ async def reply( "to an unknown error. Check `?debug` for " "more information" ) - tasks.append( - message.channel.send( - embed=discord.Embed( - color=self.bot.error_color, - description=description, - ) + msg = await message.channel.send( + embed=discord.Embed( + color=self.bot.error_color, + description=description, ) ) else: @@ -1095,17 +1095,19 @@ async def send( if plain: if from_mod and not isinstance(destination, discord.TextChannel): # Plain to user + with warnings.catch_warnings(): + # Catch coroutines not awaited warning + warnings.simplefilter("ignore") + additional_images = [] + if embed.footer.text: plain_message = f"**({embed.footer.text}) " else: plain_message = "**" plain_message += f"{embed.author.name}:** {embed.description}" files = [] - for i in embed.fields: - if "Image" in i.name: - async with self.bot.session.get(i.field[i.field.find("http") : -1]) as resp: - stream = io.BytesIO(await resp.read()) - files.append(discord.File(stream)) + for i in message.attachments: + files.append(await i.to_file()) msg = await destination.send(plain_message, files=files) else: From 2f762025d07c26092e90a2e4f5e45e5d6900364d Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 18:49:41 +0800 Subject: [PATCH 473/705] Support LOTTIE images, resolves #3119 --- CHANGELOG.md | 1 + Pipfile | 1 + Pipfile.lock | 167 +++++++++++++++++++++++++++++++++++++++++++++- README.md | 2 +- bot.py | 11 ++- core/changelog.py | 1 + core/thread.py | 58 +++++++++++++--- 7 files changed, 226 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18935f9f23..5db8a4b950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Stickers were not working in Modmail. - Large server sizes results in Guild.name == None. ([GH #3088](https://github.com/kyb3r/modmail/issues/3088)) - Attachments did not work on plain replies. ([GH #3102](https://github.com/kyb3r/modmail/issues/3102)) +- Support LOTTIE stickers. ([GH #3119](https://github.com/kyb3r/modmail/issues/3119)) ### Internal diff --git a/Pipfile b/Pipfile index 51569d26e5..a78db95d18 100644 --- a/Pipfile +++ b/Pipfile @@ -21,6 +21,7 @@ pymongo = {extras = ["srv"], version = "*"} # Required by motor python-dateutil = "~=2.8.1" python-dotenv = "~=0.18.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} +lottie = {version = "==0.6.10", extras = ["pdf"]} [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index e1a77d86b5..1fa9e5e64a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "aaa53487befe4f19feda64131fbc5bde140c1ec1a59ff2656d2ad1da2c50b390" + "sha256": "29d6f377cdb874102deb4df1406ff6d0a66834fcb89660f3c9599a2343cda038" }, "pipfile-spec": 6, "requires": { @@ -75,6 +75,76 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==21.2.0" }, + "cairocffi": { + "hashes": [ + "sha256:108a3a7cb09e203bdd8501d9baad91d786d204561bd71e9364e8b34897c47b91" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0" + }, + "cairosvg": { + "hashes": [ + "sha256:98c276b7e4f0caf01e5c7176765c104ffa1aa1461d63b2053b04ab663cf7052b", + "sha256:b0b9929cf5dba005178d746a8036fcf0025550f498ca54db61873322384783bc" + ], + "markers": "python_version >= '3.5'", + "version": "==2.5.2" + }, + "cffi": { + "hashes": [ + "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", + "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", + "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", + "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", + "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", + "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", + "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", + "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", + "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", + "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", + "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", + "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", + "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", + "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", + "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", + "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", + "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", + "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", + "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", + "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", + "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", + "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", + "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", + "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", + "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", + "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", + "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", + "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", + "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", + "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", + "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", + "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", + "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", + "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", + "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", + "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", + "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", + "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", + "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", + "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", + "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", + "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", + "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", + "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", + "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", + "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", + "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", + "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", + "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", + "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" + ], + "version": "==1.15.0" + }, "chardet": { "hashes": [ "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", @@ -91,6 +161,22 @@ "index": "pypi", "version": "==0.4.4" }, + "cssselect2": { + "hashes": [ + "sha256:2f4a9f20965367bae459e3bb42561f7927e0cfe5b7ea1692757cf67ef5d7dace", + "sha256:93fbb9af860e95dd40bf18c3b2b6ed99189a07c0f29ba76f9c5be71344664ec8" + ], + "markers": "python_version >= '3.6'", + "version": "==0.4.1" + }, + "defusedxml": { + "hashes": [ + "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", + "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.7.1" + }, "discord-py": { "git": "https://github.com/Rapptz/discord.py.git", "ref": "45d498c1b76deaf3b394d17ccf56112fa691d160" @@ -131,6 +217,16 @@ "index": "pypi", "version": "==0.6.0" }, + "lottie": { + "extras": [ + "pdf" + ], + "hashes": [ + "sha256:d3281d09a8db94da49f60267123b9e0473e3a51c282da2d5e61908d33843f1cc" + ], + "index": "pypi", + "version": "==0.6.10" + }, "motor": { "hashes": [ "sha256:1196db507142ef8f00d953efa2f37b39335ef2d72af6ce4fbccfd870b65c5e9f", @@ -232,6 +328,60 @@ "index": "pypi", "version": "==2.6" }, + "pillow": { + "hashes": [ + "sha256:066f3999cb3b070a95c3652712cffa1a748cd02d60ad7b4e485c3748a04d9d76", + "sha256:0a0956fdc5defc34462bb1c765ee88d933239f9a94bc37d132004775241a7585", + "sha256:0b052a619a8bfcf26bd8b3f48f45283f9e977890263e4571f2393ed8898d331b", + "sha256:1394a6ad5abc838c5cd8a92c5a07535648cdf6d09e8e2d6df916dfa9ea86ead8", + "sha256:1bc723b434fbc4ab50bb68e11e93ce5fb69866ad621e3c2c9bdb0cd70e345f55", + "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc", + "sha256:25a49dc2e2f74e65efaa32b153527fc5ac98508d502fa46e74fa4fd678ed6645", + "sha256:2e4440b8f00f504ee4b53fe30f4e381aae30b0568193be305256b1462216feff", + "sha256:3862b7256046fcd950618ed22d1d60b842e3a40a48236a5498746f21189afbbc", + "sha256:3eb1ce5f65908556c2d8685a8f0a6e989d887ec4057326f6c22b24e8a172c66b", + "sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6", + "sha256:493cb4e415f44cd601fcec11c99836f707bb714ab03f5ed46ac25713baf0ff20", + "sha256:4acc0985ddf39d1bc969a9220b51d94ed51695d455c228d8ac29fcdb25810e6e", + "sha256:5503c86916d27c2e101b7f71c2ae2cddba01a2cf55b8395b0255fd33fa4d1f1a", + "sha256:5b7bb9de00197fb4261825c15551adf7605cf14a80badf1761d61e59da347779", + "sha256:5e9ac5f66616b87d4da618a20ab0a38324dbe88d8a39b55be8964eb520021e02", + "sha256:620582db2a85b2df5f8a82ddeb52116560d7e5e6b055095f04ad828d1b0baa39", + "sha256:62cc1afda735a8d109007164714e73771b499768b9bb5afcbbee9d0ff374b43f", + "sha256:70ad9e5c6cb9b8487280a02c0ad8a51581dcbbe8484ce058477692a27c151c0a", + "sha256:72b9e656e340447f827885b8d7a15fc8c4e68d410dc2297ef6787eec0f0ea409", + "sha256:72cbcfd54df6caf85cc35264c77ede902452d6df41166010262374155947460c", + "sha256:792e5c12376594bfcb986ebf3855aa4b7c225754e9a9521298e460e92fb4a488", + "sha256:7b7017b61bbcdd7f6363aeceb881e23c46583739cb69a3ab39cb384f6ec82e5b", + "sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d", + "sha256:82aafa8d5eb68c8463b6e9baeb4f19043bb31fefc03eb7b216b51e6a9981ae09", + "sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b", + "sha256:8c803ac3c28bbc53763e6825746f05cc407b20e4a69d0122e526a582e3b5e153", + "sha256:93ce9e955cc95959df98505e4608ad98281fff037350d8c2671c9aa86bcf10a9", + "sha256:9a3e5ddc44c14042f0844b8cf7d2cd455f6cc80fd7f5eefbe657292cf601d9ad", + "sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df", + "sha256:a5a4532a12314149d8b4e4ad8ff09dde7427731fcfa5917ff16d0291f13609df", + "sha256:b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed", + "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed", + "sha256:c70e94281588ef053ae8998039610dbd71bc509e4acbc77ab59d7d2937b10698", + "sha256:c8a17b5d948f4ceeceb66384727dde11b240736fddeda54ca740b9b8b1556b29", + "sha256:d82cdb63100ef5eedb8391732375e6d05993b765f72cb34311fab92103314649", + "sha256:d89363f02658e253dbd171f7c3716a5d340a24ee82d38aab9183f7fdf0cdca49", + "sha256:d99ec152570e4196772e7a8e4ba5320d2d27bf22fdf11743dd882936ed64305b", + "sha256:ddc4d832a0f0b4c52fff973a0d44b6c99839a9d016fe4e6a1cb8f3eea96479c2", + "sha256:e3dacecfbeec9a33e932f00c6cd7996e62f53ad46fbe677577394aaa90ee419a", + "sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78" + ], + "markers": "python_version >= '3.6'", + "version": "==8.4.0" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "version": "==2.21" + }, "pymongo": { "extras": [ "srv" @@ -372,6 +522,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, + "tinycss2": { + "hashes": [ + "sha256:0353b5234bcaee7b1ac7ca3dea7e02cd338a9f8dcbb8f2dcd32a5795ec1e5f9a", + "sha256:fbdcac3044d60eb85fdb2aa840ece43cf7dbe798e373e6ee0be545d4d134e18a" + ], + "markers": "python_version >= '3.6'", + "version": "==1.1.0" + }, "typing-extensions": { "hashes": [ "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed", @@ -402,6 +560,13 @@ "markers": "sys_platform != 'win32'", "version": "==0.16.0" }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, "yarl": { "hashes": [ "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac", diff --git a/README.md b/README.md index cf62cfe5d6..7492a53116 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v3.11.0-dev2-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v3.11.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index c2e3ee5adf..38bd6423b2 100644 --- a/bot.py +++ b/bot.py @@ -50,9 +50,6 @@ logger = getLogger(__name__) -# # prevent "coroutine noop was never awaited" warning. -# asyncio.coroutines._DEBUG = False # type: ignore - temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp") if not os.path.exists(temp_dir): @@ -1691,6 +1688,14 @@ def main(): except ImportError: pass + try: + import cairosvg + except OSError: + logger.error( + "Unable to import cairosvg, install GTK Installer for Windows: https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/latest" + ) + sys.exit(0) + # check discord version if discord.__version__ != "2.0.0a": logger.error( diff --git a/core/changelog.py b/core/changelog.py index 4ede9f09f1..a4f88ed323 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -97,6 +97,7 @@ def embed(self) -> Embed: for name, value in self.fields.items(): embed.add_field(name=name, value=truncate(value, 1024), inline=False) embed.set_footer(text=f"Current version: v{self.bot.version}") + embed.set_thumbnail(url=self.bot.user.display_avatar.url) return embed diff --git a/core/thread.py b/core/thread.py index ff2ea791cd..09f8bd3d41 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1,8 +1,11 @@ import asyncio +import base64 import copy +import functools import io import re import time +import traceback import typing import warnings from datetime import timedelta @@ -12,6 +15,8 @@ import discord from discord.ext.commands import MissingRequiredArgument, CommandError +from lottie.importers import importers as l_importers +from lottie.exporters import exporters as l_exporters from core.models import DMDisabled, DummyMessage, getLogger from core.time import human_timedelta @@ -987,16 +992,49 @@ async def send( if is_image_url(url, convert_size=False) ] images.extend(image_urls) - images.extend( - ( - i.url - if i.format in (discord.StickerFormatType.png, discord.StickerFormatType.apng) - else None, - i.name, - True, - ) - for i in message.stickers - ) + + def lottie_to_png(data): + importer = l_importers.get("lottie") + exporter = l_exporters.get("png") + with io.BytesIO() as stream: + stream.write(data) + stream.seek(0) + an = importer.process(stream) + + with io.BytesIO() as stream: + exporter.process(an, stream) + stream.seek(0) + return stream.read() + + for i in message.stickers: + if i.format in (discord.StickerFormatType.png, discord.StickerFormatType.apng): + images.append((i.url, i.name, True)) + elif i.format == discord.StickerFormatType.lottie: + # save the json lottie representation + try: + async with self.bot.session.get(i.url) as resp: + data = await resp.read() + + # convert to a png + img_data = await self.bot.loop.run_in_executor(None, functools.partial(lottie_to_png, data)) + b64_data = base64.b64encode(img_data).decode() + + # upload to imgur + async with self.bot.session.post( + "https://api.imgur.com/3/image", + headers={"Authorization": "Client-ID 50e96145ac5e085"}, + data={"image": b64_data}, + ) as resp: + result = await resp.json() + url = result["data"]["link"] + + except Exception: + traceback.print_exc() + images.append((None, i.name, True)) + else: + images.append((url, i.name, True)) + else: + images.append((None, i.name, True)) embedded_image = False From 0de26a3e0cd4dd20e36a4b5df70076e4b38bd5d8 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 18:51:36 +0800 Subject: [PATCH 474/705] Bump version to 3.11-dev3 --- bot.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index 38bd6423b2..b3364ad1f1 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.11.0-dev2" +__version__ = "3.11.0-dev3" import asyncio diff --git a/pyproject.toml b/pyproject.toml index f1de75c772..1e1a13f5c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.11.0-dev2' +version = '3.11.0-dev3' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 8d76a3279ef70c06afc3743c5b53922664a2c0f4 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 18:55:18 +0800 Subject: [PATCH 475/705] Fix editing notes, resolve #3094 --- CHANGELOG.md | 1 + core/thread.py | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5db8a4b950..aa0a6d3121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Large server sizes results in Guild.name == None. ([GH #3088](https://github.com/kyb3r/modmail/issues/3088)) - Attachments did not work on plain replies. ([GH #3102](https://github.com/kyb3r/modmail/issues/3102)) - Support LOTTIE stickers. ([GH #3119](https://github.com/kyb3r/modmail/issues/3119)) +- Editing notes now work. ([GH #3094](https://github.com/kyb3r/modmail/issues/3094)) ### Internal diff --git a/core/thread.py b/core/thread.py index 09f8bd3d41..5209b1b615 100644 --- a/core/thread.py +++ b/core/thread.py @@ -677,13 +677,14 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> embed1.description = message tasks = [self.bot.api.edit_message(message1.id, message), message1.edit(embed=embed1)] - if message2 is not [None]: - for m2 in message2: - embed2 = m2.embeds[0] - embed2.description = message - tasks += [m2.edit(embed=embed2)] - elif message1.embeds[0].author.name.startswith("Persistent Note"): + if message1.embeds[0].author.name.startswith("Persistent Note"): tasks += [self.bot.api.edit_note(message1.id, message)] + else: + for m2 in message2: + if m2 is not None: + embed2 = m2.embeds[0] + embed2.description = message + tasks += [m2.edit(embed=embed2)] await asyncio.gather(*tasks) From 8e4d4b033a8fc6b3eff08d583f065662549d39ab Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 19:12:15 +0800 Subject: [PATCH 476/705] Test potential fix for addusers #3090 --- cogs/modmail.py | 33 +++++++++++++++++++++++++-------- core/thread.py | 8 +++++--- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 60c18594ac..7080a7bdf5 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1,4 +1,5 @@ import asyncio +from asyncio import tasks import re from datetime import datetime from itertools import zip_longest @@ -735,6 +736,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str ctx.command.reset_cooldown(ctx) return + tasks = [] if not silent: description = self.bot.formatter.format( self.bot.config["private_added_to_group_response"], moderator=ctx.author @@ -748,7 +750,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str em.timestamp = discord.utils.utcnow() em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) for u in users: - await u.send(embed=em) + tasks.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_added_to_group_response"], @@ -766,9 +768,12 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str for i in ctx.thread.recipients: if i not in users: - await i.send(embed=em) + tasks.append(i.send(embed=em)) await ctx.thread.add_users(users) + if tasks: + await asyncio.gather(*tasks) + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -824,6 +829,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ctx.command.reset_cooldown(ctx) return + tasks = [] if not silent: description = self.bot.formatter.format( self.bot.config["private_removed_from_group_response"], moderator=ctx.author @@ -837,7 +843,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, em.timestamp = discord.utils.utcnow() em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) for u in users: - await u.send(embed=em) + tasks.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_removed_from_group_response"], @@ -855,9 +861,12 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, for i in ctx.thread.recipients: if i not in users: - await i.send(embed=em) + tasks.append(i.send(embed=em)) await ctx.thread.remove_users(users) + if tasks: + await asyncio.gather(*tasks) + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -907,6 +916,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ctx.command.reset_cooldown(ctx) return + tasks = [] if not silent: em = discord.Embed( title=self.bot.config["private_added_to_group_title"], @@ -928,7 +938,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, em.set_footer(text=name, icon_url=avatar_url) for u in users: - await u.send(embed=em) + tasks.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_added_to_group_description_anon"], @@ -945,9 +955,12 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, for i in ctx.thread.recipients: if i not in users: - await i.send(embed=em) + tasks.append(i.send(embed=em)) await ctx.thread.add_users(users) + if tasks: + await asyncio.gather(*tasks) + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -992,6 +1005,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro ctx.command.reset_cooldown(ctx) return + tasks = [] if not silent: em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], @@ -1013,7 +1027,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro em.set_footer(text=name, icon_url=avatar_url) for u in users: - await u.send(embed=em) + tasks.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_removed_from_group_description_anon"], @@ -1030,9 +1044,12 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro for i in ctx.thread.recipients: if i not in users: - await i.send(embed=em) + tasks.append(i.send(embed=em)) await ctx.thread.remove_users(users) + if tasks: + await asyncio.gather(*tasks) + sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) diff --git a/core/thread.py b/core/thread.py index 5209b1b615..4aea00734e 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1203,7 +1203,7 @@ async def _update_users_genesis(self): embed.add_field(name="Other Recipients", value=value, inline=False) else: if value: - embed.set_field_at(index, value=value) + embed.set_field_at(index, name="Other Recipients", value=value, inline=False) else: embed.remove_field(index) @@ -1211,13 +1211,15 @@ async def _update_users_genesis(self): async def add_users(self, users: typing.List[typing.Union[discord.Member, discord.User]]) -> None: topic = "" - title, user_id, _ = parse_channel_topic(self.channel.topic) + title, _, _ = parse_channel_topic(self.channel.topic) if title is not None: topic += f"Title: {title}\n" - topic += f"User ID: {user_id}" + topic += f"User ID: {self._id}" self._other_recipients += users + self._other_recipients = list(set(self._other_recipients)) + ids = ",".join(str(i.id) for i in self._other_recipients) topic += f"\nOther Recipients: {ids}" From a89a3fe593011fab26557daf6350f79175a7fdf8 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 19:19:10 +0800 Subject: [PATCH 477/705] Update changelog --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa0a6d3121..9613ba44c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,13 +10,17 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Breaking -- Upgraded to discord.py v2.0 master ([internal changes](https://gist.github.com/apple502j/f75b4f24652f04de85c7084ffd73ec58)). +- Upgraded to discord.py v2.0 master ([internal changes](https://gist.github.com/apple502j/f75b4f24652f04de85c7084ffd73ec58), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). - Python 3.8 or higher is required. ### Added - `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/kyb3r/modmail/pull/3093)) +### Improved + +- Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/kyb3r/modmail/issues/3048)) + ### Fixed - Several minor typos. ([PR #3095](https://github.com/kyb3r/modmail/pull/3095), [PR #3116](https://github.com/kyb3r/modmail/pull/3116)) @@ -31,7 +35,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Internal -- Improve regex parsing of channel topics. ([PR #3111](https://github.com/kyb3r/modmail/pull/3111)) +- Improve regex parsing of channel topics. ([GH #3114](https://github.com/kyb3r/modmail/issues/3114), [PR #3111](https://github.com/kyb3r/modmail/pull/3111)) - Add warning if deploying on a developmental version. # v3.10.3 From 1444c1d97444e4c3cc4a6caa01c5d35e2be7a1df Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 19:19:47 +0800 Subject: [PATCH 478/705] Formatting --- core/thread.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 4aea00734e..145864e815 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1017,7 +1017,9 @@ def lottie_to_png(data): data = await resp.read() # convert to a png - img_data = await self.bot.loop.run_in_executor(None, functools.partial(lottie_to_png, data)) + img_data = await self.bot.loop.run_in_executor( + None, functools.partial(lottie_to_png, data) + ) b64_data = base64.b64encode(img_data).decode() # upload to imgur From 13a22cf003333acfb61bbadd7f81b0a711c89a79 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 21:49:26 +0800 Subject: [PATCH 479/705] require_close_reason config, resolves #3107 --- CHANGELOG.md | 5 +++-- bot.py | 2 +- cogs/modmail.py | 3 +++ core/config.py | 2 ++ core/config_help.json | 8 ++++++++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9613ba44c4..ff96521f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added - `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/kyb3r/modmail/pull/3093)) +- `require_close_reason` to require a reason to close a thread. ([GH #3107](https://github.com/kyb3r/modmail/issues/3107)) ### Improved @@ -27,9 +28,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Certain cases where fallback categories were not working as intended. ([PR #3109](https://github.com/kyb3r/modmail/pull/3109)) - `?contact` would create in a random category in silent mode. ([GH #3091](https://github.com/kyb3r/modmail/issues/3091), [PR #3092](https://github.com/kyb3r/modmail/pull/3092)) - Certain cases where `?close` would fail if closer isn't in cache. ([GH #3104](https://github.com/kyb3r/modmail/issues/3104), [PR #3105](https://github.com/kyb3r/modmail/pull/3105)) -- Stickers were not working in Modmail. +- Stickers now work in Modmail. - Large server sizes results in Guild.name == None. ([GH #3088](https://github.com/kyb3r/modmail/issues/3088)) -- Attachments did not work on plain replies. ([GH #3102](https://github.com/kyb3r/modmail/issues/3102)) +- Attachments now work on plain replies. ([GH #3102](https://github.com/kyb3r/modmail/issues/3102)) - Support LOTTIE stickers. ([GH #3119](https://github.com/kyb3r/modmail/issues/3119)) - Editing notes now work. ([GH #3094](https://github.com/kyb3r/modmail/issues/3094)) diff --git a/bot.py b/bot.py index b3364ad1f1..38bd6423b2 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.11.0-dev3" +__version__ = "3.11.0-dev2" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index 7080a7bdf5..5871f76fb6 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -419,6 +419,9 @@ async def close(self, ctx, *, after: UserFriendlyTime = None): return await ctx.send(embed=embed) + if self.bot.config["require_close_reason"] and message is None: + raise commands.BadArgument("Provide a reason for closing the thread.") + if after and after.dt > now: await self.send_scheduled_close_message(ctx, after, silent) diff --git a/core/config.py b/core/config.py index e9de7d516d..d06443a6a3 100644 --- a/core/config.py +++ b/core/config.py @@ -91,6 +91,7 @@ class ConfigManager: "silent_alert_on_mention": False, "show_timestamp": True, "anonymous_snippets": False, + "require_close_reason": False, # group conversations "private_added_to_group_title": "New Thread (Group)", "private_added_to_group_response": "{moderator.name} has added you to a Modmail thread.", @@ -206,6 +207,7 @@ class ConfigManager: "update_notifications", "thread_contact_silently", "anonymous_snippets", + "require_close_reason", "recipient_thread_close", "thread_show_roles", "thread_show_account_age", diff --git a/core/config_help.json b/core/config_help.json index 04f177cd97..ee03aca24a 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -797,6 +797,14 @@ "See also: `anon_avatar_url`, `anon_tag`." ] }, + "require_close_reason": { + "default" : "No", + "description": "Require a reason to close threads.", + "examples": [ + "`{prefix}config set require_close_reason yes`" + ], + "notes": [] + }, "private_added_to_group_title": { "default": "New Thread (Group)", "description": "This is the message embed title sent to the recipient that is just added to a thread.", From e44fb12e90dbb5974a7e9d066a68d0d39d6e023c Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 21:58:17 +0800 Subject: [PATCH 480/705] plain_snippets, ?fpareply and ?fpreply, resolves #3083 --- CHANGELOG.md | 4 +- bot.py | 8 ++-- cogs/modmail.py | 85 ++++++++++++++++++++++++++++++++----------- core/config.py | 2 + core/config_help.json | 12 +++++- 5 files changed, 85 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff96521f8d..42a1744d12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added - `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/kyb3r/modmail/pull/3093)) -- `require_close_reason` to require a reason to close a thread. ([GH #3107](https://github.com/kyb3r/modmail/issues/3107)) +- `require_close_reason` config to require a reason to close a thread. ([GH #3107](https://github.com/kyb3r/modmail/issues/3107)) +- `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/kyb3r/modmail/issues/3083)) +- `?fpareply` and `?fpreply` to reply to messages with variables plainly. ### Improved diff --git a/bot.py b/bot.py index 38bd6423b2..fcdf8011aa 100644 --- a/bot.py +++ b/bot.py @@ -1144,10 +1144,12 @@ async def process_commands(self, message): cmd = cmd.lower() if cmd in self.snippets: snippet = self.snippets[cmd] + modifiers = "f" + if self.config["plain_snippets"]: + modifiers += "p" if self.config["anonymous_snippets"]: - message.content = f"{self.prefix}fareply {snippet}" - else: - message.content = f"{self.prefix}freply {snippet}" + modifiers += "a" + message.content = f"{self.prefix}{modifiers}reply {snippet}" ctxs = await self.get_contexts(message) for ctx in ctxs: diff --git a/cogs/modmail.py b/cogs/modmail.py index 5871f76fb6..c17b580370 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1,5 +1,4 @@ import asyncio -from asyncio import tasks import re from datetime import datetime from itertools import zip_longest @@ -739,7 +738,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str ctx.command.reset_cooldown(ctx) return - tasks = [] + to_exec = [] if not silent: description = self.bot.formatter.format( self.bot.config["private_added_to_group_response"], moderator=ctx.author @@ -753,7 +752,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str em.timestamp = discord.utils.utcnow() em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) for u in users: - tasks.append(u.send(embed=em)) + to_exec.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_added_to_group_response"], @@ -771,11 +770,11 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str for i in ctx.thread.recipients: if i not in users: - tasks.append(i.send(embed=em)) + to_exec.append(i.send(embed=em)) await ctx.thread.add_users(users) - if tasks: - await asyncio.gather(*tasks) + if to_exec: + await asyncio.gather(*to_exec) sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -832,7 +831,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ctx.command.reset_cooldown(ctx) return - tasks = [] + to_exec = [] if not silent: description = self.bot.formatter.format( self.bot.config["private_removed_from_group_response"], moderator=ctx.author @@ -846,7 +845,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, em.timestamp = discord.utils.utcnow() em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) for u in users: - tasks.append(u.send(embed=em)) + to_exec.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_removed_from_group_response"], @@ -864,11 +863,11 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, for i in ctx.thread.recipients: if i not in users: - tasks.append(i.send(embed=em)) + to_exec.append(i.send(embed=em)) await ctx.thread.remove_users(users) - if tasks: - await asyncio.gather(*tasks) + if to_exec: + await asyncio.gather(*to_exec) sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -919,7 +918,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ctx.command.reset_cooldown(ctx) return - tasks = [] + to_exec = [] if not silent: em = discord.Embed( title=self.bot.config["private_added_to_group_title"], @@ -941,7 +940,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, em.set_footer(text=name, icon_url=avatar_url) for u in users: - tasks.append(u.send(embed=em)) + to_exec.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_added_to_group_description_anon"], @@ -958,11 +957,11 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, for i in ctx.thread.recipients: if i not in users: - tasks.append(i.send(embed=em)) + to_exec.append(i.send(embed=em)) await ctx.thread.add_users(users) - if tasks: - await asyncio.gather(*tasks) + if to_exec: + await asyncio.gather(*to_exec) sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -1008,7 +1007,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro ctx.command.reset_cooldown(ctx) return - tasks = [] + to_exec = [] if not silent: em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], @@ -1030,7 +1029,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro em.set_footer(text=name, icon_url=avatar_url) for u in users: - tasks.append(u.send(embed=em)) + to_exec.append(u.send(embed=em)) description = self.bot.formatter.format( self.bot.config["public_removed_from_group_description_anon"], @@ -1047,11 +1046,11 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro for i in ctx.thread.recipients: if i not in users: - tasks.append(i.send(embed=em)) + to_exec.append(i.send(embed=em)) await ctx.thread.remove_users(users) - if tasks: - await asyncio.gather(*tasks) + if to_exec: + await asyncio.gather(*to_exec) sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) @@ -1253,6 +1252,50 @@ async def fareply(self, ctx, *, msg: str = ""): async with ctx.typing(): await ctx.thread.reply(ctx.message, anonymous=True) + @commands.command(aliases=["formatplainreply"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def fpreply(self, ctx, *, msg: str = ""): + """ + Reply to a Modmail thread with variables and a plain message. + + Works just like `{prefix}areply`, however with the addition of three variables: + - `{{channel}}` - the `discord.TextChannel` object + - `{{recipient}}` - the `discord.User` object of the recipient + - `{{author}}` - the `discord.User` object of the author + + Supports attachments and images as well as + automatically embedding image URLs. + """ + msg = self.bot.formatter.format( + msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + ) + ctx.message.content = msg + async with ctx.typing(): + await ctx.thread.reply(ctx.message, plain=True) + + @commands.command(aliases=["formatplainanonreply"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def fpareply(self, ctx, *, msg: str = ""): + """ + Anonymously reply to a Modmail thread with variables and a plain message. + + Works just like `{prefix}areply`, however with the addition of three variables: + - `{{channel}}` - the `discord.TextChannel` object + - `{{recipient}}` - the `discord.User` object of the recipient + - `{{author}}` - the `discord.User` object of the author + + Supports attachments and images as well as + automatically embedding image URLs. + """ + msg = self.bot.formatter.format( + msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + ) + ctx.message.content = msg + async with ctx.typing(): + await ctx.thread.reply(ctx.message, anonymous=True, plain=True) + @commands.command(aliases=["anonreply", "anonymousreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() diff --git a/core/config.py b/core/config.py index d06443a6a3..4af16e8272 100644 --- a/core/config.py +++ b/core/config.py @@ -91,6 +91,7 @@ class ConfigManager: "silent_alert_on_mention": False, "show_timestamp": True, "anonymous_snippets": False, + "plain_snippets": False, "require_close_reason": False, # group conversations "private_added_to_group_title": "New Thread (Group)", @@ -207,6 +208,7 @@ class ConfigManager: "update_notifications", "thread_contact_silently", "anonymous_snippets", + "plain_snippets", "require_close_reason", "recipient_thread_close", "thread_show_roles", diff --git a/core/config_help.json b/core/config_help.json index ee03aca24a..c31be337d6 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -794,7 +794,17 @@ "`{prefix}config set anonymous_snippets yes`" ], "notes": [ - "See also: `anon_avatar_url`, `anon_tag`." + "See also: `anon_avatar_url`, `anon_tag`, `plain_snippets`." + ] + }, + "plain_snippets": { + "default": "No", + "description": "Sends snippets with a plain interface.", + "examples":[ + "`{prefix}config set plain_snippets yes`" + ], + "notes": [ + "See also: `anonymous_snippets`." ] }, "require_close_reason": { From ec8fb29f7553f9961495b1fe36e09ec0e38429b9 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 22:08:33 +0800 Subject: [PATCH 481/705] use_nickname_channel_name, resolves #3112 --- CHANGELOG.md | 1 + bot.py | 9 +++++++-- core/config.py | 2 ++ core/config_help.json | 21 +++++++++++++++++---- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42a1744d12..4744e57bba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `require_close_reason` config to require a reason to close a thread. ([GH #3107](https://github.com/kyb3r/modmail/issues/3107)) - `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/kyb3r/modmail/issues/3083)) - `?fpareply` and `?fpreply` to reply to messages with variables plainly. +- `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/kyb3r/modmail/issues/3112)) ### Improved diff --git a/bot.py b/bot.py index fcdf8011aa..dcd447eed4 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.11.0-dev2" +__version__ = "3.11.0-dev3" import asyncio @@ -1663,7 +1663,12 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): elif self.config["use_timestamp_channel_name"]: name = new_name = author.created_at.isoformat(sep="-", timespec="minutes") else: - name = author.name.lower() + if self.config["use_nickname_channel_name"]: + author_member = self.guild.get_member(author.id) + name = author_member.display_name.lower() + else: + name = author.name.lower() + if force_null: name = "null" diff --git a/core/config.py b/core/config.py index 4af16e8272..6d2a2eb1cd 100644 --- a/core/config.py +++ b/core/config.py @@ -52,6 +52,7 @@ class ConfigManager: "close_emoji": "\N{LOCK}", "use_user_id_channel_name": False, "use_timestamp_channel_name": False, + "use_nickname_channel_name": False, "recipient_thread_close": False, "thread_show_roles": True, "thread_show_account_age": True, @@ -184,6 +185,7 @@ class ConfigManager: booleans = { "use_user_id_channel_name", "use_timestamp_channel_name", + "use_nickname_channel_name", "user_typing", "mod_typing", "reply_without_command", diff --git a/core/config_help.json b/core/config_help.json index c31be337d6..53d1d4daec 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -106,8 +106,8 @@ ], "notes": [ "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", - "This cannot be applied with `use_timestamp_channel_name`.", - "See also: `use_timestamp_channel_name`." + "This cannot be applied with `use_timestamp_channel_name` or `use_nickname_channel_name`.", + "See also: `use_timestamp_channel_name`, `use_nickname_channel_name`." ] }, "use_timestamp_channel_name": { @@ -119,8 +119,21 @@ ], "notes": [ "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", - "This cannot be applied with `use_user_id_channel_name`.", - "See also: `use_user_id_channel_name`." + "This cannot be applied with `use_user_id_channel_name` or `use_nickname_channel_name`.", + "See also: `use_user_id_channel_name`, `use_nickname_channel_name`." + ] + }, + "use_nickname_channel_name": { + "default": "No", + "description": "When this is set to `yes`, new thread channels will be named with the recipient's nickname instead of the recipient's name.", + "examples": [ + "`{prefix}config set use_nickname_channel_name yes`", + "`{prefix}config set use_nickname_channel_name no`" + ], + "notes": [ + "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", + "This cannot be applied with `use_timestamp_channel_name` or `use_user_id_channel_name`.", + "See also: `use_timestamp_channel_name`, `use_user_id_channel_name`." ] }, "mod_typing": { From d741738e1e71ed8b047bfe96502308d95119d851 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 22:29:45 +0800 Subject: [PATCH 482/705] Use discord relative timedeltas, resolves #3046 --- CHANGELOG.md | 1 + bot.py | 4 +-- cogs/modmail.py | 9 +++--- core/config.py | 2 +- core/config_help.json | 2 +- core/thread.py | 2 +- core/time.py | 66 +++++++++++++++++++++++-------------------- 7 files changed, 45 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4744e57bba..2ef596f888 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Improved - Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/kyb3r/modmail/issues/3048)) +- Use discord relative timedeltas. ([GH #3046](https://github.com/kyb3r/modmail/issues/3046)) ### Fixed diff --git a/bot.py b/bot.py index dcd447eed4..45da7fa953 100644 --- a/bot.py +++ b/bot.py @@ -685,7 +685,7 @@ def check_account_age(self, author: discord.Member) -> bool: logger.debug("Blocked due to account age, user %s.", author.name) if str(author.id) not in self.blocked_users: - new_reason = f"System Message: New Account. Required to wait for {delta}." + new_reason = f"System Message: New Account. User can try again {delta}." self.blocked_users[str(author.id)] = new_reason return False @@ -711,7 +711,7 @@ def check_guild_age(self, author: discord.Member) -> bool: logger.debug("Blocked due to guild age, user %s.", author.name) if str(author.id) not in self.blocked_users: - new_reason = f"System Message: Recently Joined. Required to wait for {delta}." + new_reason = f"System Message: Recently Joined. User can try again {delta}." self.blocked_users[str(author.id)] = new_reason return False diff --git a/cogs/modmail.py b/cogs/modmail.py index c17b580370..7900f0eeef 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1,6 +1,6 @@ import asyncio import re -from datetime import datetime +from datetime import datetime, timezone from itertools import zip_longest from typing import Optional, Union from types import SimpleNamespace @@ -12,7 +12,6 @@ from discord.utils import escape_markdown from dateutil import parser -from natural.date import duration from core import checks from core.models import DMDisabled, PermissionLevel, SimilarCategoryConverter, getLogger @@ -359,7 +358,7 @@ async def send_scheduled_close_message(self, ctx, after, silent=False): embed = discord.Embed( title="Scheduled close", - description=f"This thread will close {silent}in {human_delta}.", + description=f"This thread will close {silent}{human_delta}.", color=self.bot.error_color, ) @@ -631,7 +630,7 @@ def format_log_embeds(self, logs, avatar_url): title = f"Total Results Found ({len(logs)})" for entry in logs: - created_at = parser.parse(entry["created_at"]) + created_at = parser.parse(entry["created_at"]).astimezone(timezone.utc) prefix = self.bot.config["log_url_prefix"].strip("/") if prefix == "NONE": @@ -646,7 +645,7 @@ def format_log_embeds(self, logs, avatar_url): embed = discord.Embed(color=self.bot.main_color, timestamp=created_at) embed.set_author(name=f"{title} - {username}", icon_url=avatar_url, url=log_url) embed.url = log_url - embed.add_field(name="Created", value=duration(created_at, now=discord.utils.utcnow())) + embed.add_field(name="Created", value=human_timedelta(created_at)) closer = entry.get("closer") if closer is None: closer_msg = "Unknown" diff --git a/core/config.py b/core/config.py index 6d2a2eb1cd..399592e055 100644 --- a/core/config.py +++ b/core/config.py @@ -78,7 +78,7 @@ class ConfigManager: "thread_move_notify_mods": False, "thread_move_response": "This thread has been moved.", "cooldown_thread_title": "Message not sent!", - "cooldown_thread_response": "You must wait for {delta} before you can contact me again.", + "cooldown_thread_response": "Your cooldown ends {delta}. Try contacting me then.", "disabled_new_thread_title": "Not Delivered", "disabled_new_thread_response": "We are not accepting new threads.", "disabled_new_thread_footer": "Please try again later...", diff --git a/core/config_help.json b/core/config_help.json index 53d1d4daec..6ee84eee15 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -571,7 +571,7 @@ ] }, "cooldown_thread_response": { - "default": "You must wait for {delta} before you can contact me again.", + "default": "Your cooldown ends {delta}. Try contacting me then.", "description": "The description of the message embed when the user has a cooldown before creating a new thread.", "examples": [ "`{prefix}config set cooldown_thread_response Be patient! You are on cooldown, wait {delta} more.`" diff --git a/core/thread.py b/core/thread.py index 145864e815..9fa504152e 100644 --- a/core/thread.py +++ b/core/thread.py @@ -565,7 +565,7 @@ async def _restart_close_timer(self): seconds = timeout.total_seconds() # seconds = 20 # Uncomment to debug with just 20 seconds reset_time = discord.utils.utcnow() + timedelta(seconds=seconds) - human_time = human_timedelta(dt=reset_time) + human_time = human_timedelta(dt=reset_time, spec="manual") if self.bot.config.get("thread_auto_close_silently"): return await self.close(closer=self.bot.user, silent=True, after=int(seconds), auto_close=True) diff --git a/core/time.py b/core/time.py index 376f2074eb..26b41b9043 100644 --- a/core/time.py +++ b/core/time.py @@ -187,35 +187,39 @@ async def convert(self, ctx, argument): return super().convert(ctx, argument) -def human_timedelta(dt, *, source=None): - now = source or discord.utils.utcnow() - if dt > now: - delta = relativedelta(dt, now) - suffix = "" - else: - delta = relativedelta(now, dt) - suffix = " ago" - - if delta.microseconds and delta.seconds: - delta = delta + relativedelta(seconds=+1) - - attrs = ["years", "months", "days", "hours", "minutes", "seconds"] - - output = [] - for attr in attrs: - elem = getattr(delta, attr) - if not elem: - continue - - if elem > 1: - output.append(f"{elem} {attr}") +def human_timedelta(dt, *, spec="R"): + if spec == "manual": + now = discord.utils.utcnow() + if dt > now: + delta = relativedelta(dt, now) + suffix = "" else: - output.append(f"{elem} {attr[:-1]}") - - if not output: - return "now" - if len(output) == 1: - return output[0] + suffix - if len(output) == 2: - return f"{output[0]} and {output[1]}{suffix}" - return f"{output[0]}, {output[1]} and {output[2]}{suffix}" + delta = relativedelta(now, dt) + suffix = " ago" + + if delta.microseconds and delta.seconds: + delta = delta + relativedelta(seconds=+1) + + attrs = ["years", "months", "days", "hours", "minutes", "seconds"] + + output = [] + for attr in attrs: + elem = getattr(delta, attr) + if not elem: + continue + + if elem > 1: + output.append(f"{elem} {attr}") + else: + output.append(f"{elem} {attr[:-1]}") + + if not output: + return "now" + if len(output) == 1: + return output[0] + suffix + if len(output) == 2: + return f"{output[0]} and {output[1]}{suffix}" + return f"{output[0]}, {output[1]} and {output[2]}{suffix}" + else: + unixtime = int(dt.timestamp()) + return f"<t:{unixtime}:{spec}>" From 3af772f0c1bd9fd034b4e2b5ce7e119ea1c14f28 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 22:40:28 +0800 Subject: [PATCH 483/705] Properly implement per-server avatars --- core/thread.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/core/thread.py b/core/thread.py index 9fa504152e..eb47ba9cdc 100644 --- a/core/thread.py +++ b/core/thread.py @@ -335,10 +335,9 @@ def _format_info_embed(self, user, log_url, log_count, color): else: footer = f"User ID: {user.id}" - embed.set_author(name=str(user), icon_url=user.display_avatar.url, url=log_url) - # embed.set_thumbnail(url=avi) - if member is not None: + embed.set_author(name=str(user), icon_url=member.display_avatar.url, url=log_url) + joined = str((time - member.joined_at).days) # embed.add_field(name='Joined', value=joined + days(joined)) if self.bot.config["thread_show_join_age"]: @@ -350,6 +349,7 @@ def _format_info_embed(self, user, log_url, log_count, color): embed.add_field(name="Roles", value=role_names, inline=True) embed.set_footer(text=footer) else: + embed.set_author(name=str(user), icon_url=user.display_avatar.url, url=log_url) embed.set_footer(text=f"{footer} • (not in main server)") embed.description += ", ".join(user_info) @@ -931,6 +931,11 @@ async def send( destination = destination or self.channel author = message.author + member = self.bot.guild.get_member(author.id) + if member: + avatar_url = member.display_avatar.url + else: + avatar_url = author.display_avatar.url embed = discord.Embed(description=message.content) if self.bot.config["show_timestamp"]: @@ -958,7 +963,7 @@ async def send( else: # Normal message name = str(author) - avatar_url = author.display_avatar.url + avatar_url = avatar_url embed.set_author( name=name, icon_url=avatar_url, From 998d938f33ed9fe3bfe59ff6934c1ffd0bb67116 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 22:49:42 +0800 Subject: [PATCH 484/705] Modmail now work in threads --- CHANGELOG.md | 1 + core/thread.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef596f888..c2fca71128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Attachments now work on plain replies. ([GH #3102](https://github.com/kyb3r/modmail/issues/3102)) - Support LOTTIE stickers. ([GH #3119](https://github.com/kyb3r/modmail/issues/3119)) - Editing notes now work. ([GH #3094](https://github.com/kyb3r/modmail/issues/3094)) +- Commands now work in threads. ### Internal diff --git a/core/thread.py b/core/thread.py index eb47ba9cdc..1d41c0a18a 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1281,7 +1281,7 @@ async def find( recipient_id: int = None, ) -> typing.Optional[Thread]: """Finds a thread from cache or from discord channel topics.""" - if recipient is None and channel is not None: + if recipient is None and channel is not None and isinstance(channel, discord.TextChannel): thread = await self._find_from_channel(channel) if thread is None: user_id, thread = next( @@ -1310,7 +1310,6 @@ async def find( await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: - def check(topic): _, user_id, other_ids = parse_channel_topic(topic) return recipient_id == user_id or recipient_id in other_ids From 67781cae9cc149d2d847e96292377fab0341c029 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 22:54:20 +0800 Subject: [PATCH 485/705] Formatting --- core/thread.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/thread.py b/core/thread.py index 1d41c0a18a..c95ce09cb6 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1310,6 +1310,7 @@ async def find( await thread.close(closer=self.bot.user, silent=True, delete_channel=False) thread = None else: + def check(topic): _, user_id, other_ids = parse_channel_topic(topic) return recipient_id == user_id or recipient_id in other_ids From ae1af88c2966606611386b76cf46836be5fab6be Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 22:58:16 +0800 Subject: [PATCH 486/705] Bunp version to v4-dev4 --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2fca71128..a4409e12bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.11.0 +# v4.0.0 ### Breaking diff --git a/README.md b/README.md index 7492a53116..4487438a5c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v3.11.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.0.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index 45da7fa953..77d6327a4f 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.11.0-dev3" +__version__ = "4.0.0-dev4" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 1e1a13f5c9..9b541f6243 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.11.0-dev3' +version = '4.0.0-dev4' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 68bc5733cbf5a57394879e2b370023e550ba061c Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 23:26:43 +0800 Subject: [PATCH 487/705] Fix timezone mismatch --- bot.py | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bot.py b/bot.py index 77d6327a4f..c9ad1ee638 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev4" +__version__ = "4.0.0-dev5" import asyncio @@ -10,7 +10,7 @@ import string import sys import typing -from datetime import datetime +from datetime import datetime, timezone from subprocess import PIPE from types import SimpleNamespace @@ -565,7 +565,7 @@ async def on_ready(self): logger.line() for recipient_id, items in tuple(closures.items()): - after = (datetime.fromisoformat(items["time"]) - discord.utils.utcnow()).total_seconds() + after = (datetime.fromisoformat(items["time"]).astimezone(timezone.utc) - discord.utils.utcnow()).total_seconds() if after <= 0: logger.debug("Closing thread for recipient %s.", recipient_id) after = 0 diff --git a/pyproject.toml b/pyproject.toml index 9b541f6243..9f722227eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev4' +version = '4.0.0-dev5' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 459b81dbec086193a59c4c5490800ba5e9182cf6 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 21 Nov 2021 23:38:21 +0800 Subject: [PATCH 488/705] format --- bot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index c9ad1ee638..fb4f8b04a2 100644 --- a/bot.py +++ b/bot.py @@ -565,7 +565,9 @@ async def on_ready(self): logger.line() for recipient_id, items in tuple(closures.items()): - after = (datetime.fromisoformat(items["time"]).astimezone(timezone.utc) - discord.utils.utcnow()).total_seconds() + after = ( + datetime.fromisoformat(items["time"]).astimezone(timezone.utc) - discord.utils.utcnow() + ).total_seconds() if after <= 0: logger.debug("Closing thread for recipient %s.", recipient_id) after = 0 From da92d04a5325a644e475f514f01d20a78a5c2431 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 00:52:33 +0800 Subject: [PATCH 489/705] improve cairo warnings --- bot.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index fb4f8b04a2..c553686852 100644 --- a/bot.py +++ b/bot.py @@ -8,6 +8,7 @@ import re import signal import string +import struct import sys import typing from datetime import datetime, timezone @@ -1690,7 +1691,7 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): def main(): try: # noinspection PyUnresolvedReferences - import uvloop + import uvloop # type: ignore logger.debug("Setting up with uvloop.") uvloop.install() @@ -1698,11 +1699,21 @@ def main(): pass try: - import cairosvg + import cairosvg # noqa: F401 except OSError: - logger.error( - "Unable to import cairosvg, install GTK Installer for Windows: https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/latest" - ) + if os.name == "nt": + if struct.calcsize("P") * 8 != 64: + logger.error( + "Unable to import cairosvg, ensure your Python is a 64-bit version: https://www.python.org/downloads/" + ) + else: + logger.error( + "Unable to import cairosvg, install GTK Installer for Windows: https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/latest" + ) + else: + logger.error( + "Unable to import cairosvg, report on our support server with your OS details: https://discord.gg/etJNHCQ" + ) sys.exit(0) # check discord version From 28d86764f46807cbdd18f271c37734d2f66bfaad Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 17:32:51 +0800 Subject: [PATCH 490/705] show_log_url_button for log urls resolves #3122 --- CHANGELOG.md | 1 + core/config.py | 2 ++ core/config_help.json | 8 ++++++++ core/thread.py | 7 ++++++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4409e12bb..b3dae23d78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/kyb3r/modmail/issues/3083)) - `?fpareply` and `?fpreply` to reply to messages with variables plainly. - `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/kyb3r/modmail/issues/3112)) +- `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/kyb3r/modmail/issues/3122)) ### Improved diff --git a/core/config.py b/core/config.py index 399592e055..14f86ecd2e 100644 --- a/core/config.py +++ b/core/config.py @@ -94,6 +94,7 @@ class ConfigManager: "anonymous_snippets": False, "plain_snippets": False, "require_close_reason": False, + "show_log_url_button": False, # group conversations "private_added_to_group_title": "New Thread (Group)", "private_added_to_group_response": "{moderator.name} has added you to a Modmail thread.", @@ -191,6 +192,7 @@ class ConfigManager: "reply_without_command", "anon_reply_without_command", "plain_reply_without_command", + "show_log_url_button", "recipient_thread_close", "thread_auto_close_silently", "thread_move_notify", diff --git a/core/config_help.json b/core/config_help.json index 6ee84eee15..342652456d 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -828,6 +828,14 @@ ], "notes": [] }, + "show_log_url_button": { + "default" : "No", + "description": "Shows the button to open the Log URL.", + "examples": [ + "`{prefix}config set show_log_url_button yes`" + ], + "notes": [] + }, "private_added_to_group_title": { "default": "New Thread (Group)", "description": "This is the message embed title sent to the recipient that is just added to a thread.", diff --git a/core/thread.py b/core/thread.py index c95ce09cb6..67458f0017 100644 --- a/core/thread.py +++ b/core/thread.py @@ -495,7 +495,12 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, tasks = [self.bot.config.update()] if self.bot.log_channel is not None and self.channel is not None: - tasks.append(self.bot.log_channel.send(embed=embed)) + if self.bot.config["show_log_url_button"]: + view = discord.ui.View() + view.add_item(discord.ui.Button(label='Log link', url=log_url, style=discord.ButtonStyle.url)) + else: + view = None + tasks.append(self.bot.log_channel.send(embed=embed, view=view)) # Thread closed message From 9866141817bd9d63adee3b238979d743878b1216 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 18:54:27 +0800 Subject: [PATCH 491/705] Use discord native buttons for pagination --- CHANGELOG.md | 1 + core/paginator.py | 259 ++++++++++++++++++++++++++++------------------ core/thread.py | 2 +- 3 files changed, 159 insertions(+), 103 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3dae23d78..641b3ffcf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/kyb3r/modmail/issues/3048)) - Use discord relative timedeltas. ([GH #3046](https://github.com/kyb3r/modmail/issues/3046)) +- Use discord native buttons for all paginator sessions. ### Fixed diff --git a/core/paginator.py b/core/paginator.py index 934b4670be..b208bff0a3 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -1,8 +1,8 @@ import typing -import asyncio -from discord import User, Reaction, Message, Embed -from discord import HTTPException, InvalidArgument +import discord +from discord import Message, Embed, ButtonStyle, Interaction +from discord.ui import View, Button from discord.ext import commands @@ -33,8 +33,8 @@ class PaginatorSession: The `Message` of the `Embed`. current : int The current page number. - reaction_map : Dict[str, method] - A mapping for reaction to method. + callback_map : Dict[str, method] + A mapping for text to method. """ def __init__(self, ctx: commands.Context, *pages, **options): @@ -45,38 +45,15 @@ def __init__(self, ctx: commands.Context, *pages, **options): self.current = 0 self.pages = list(pages) self.destination = options.get("destination", ctx) - self.reaction_map = { - "⏮": self.first_page, - "◀": self.previous_page, - "▶": self.next_page, - "⏭": self.last_page, - "🛑": self.close, - } - - def add_page(self, item) -> None: - """ - Add a page. - """ - raise NotImplementedError - - async def create_base(self, item) -> None: - """ - Create a base `Message`. - """ - await self._create_base(item) + self.view = None - if len(self.pages) == 1: - self.running = False - return - - self.running = True - for reaction in self.reaction_map: - if len(self.pages) == 2 and reaction in "⏮⏭": - continue - await self.ctx.bot.add_reaction(self.base, reaction) - - async def _create_base(self, item) -> None: - raise NotImplementedError + self.callback_map = { + "<<": self.first_page, + "<": self.previous_page, + ">": self.next_page, + ">>": self.last_page, + } + self._buttons_map = {"<<": None, "<": None, ">": None, ">>": None} async def show_page(self, index: int) -> None: """ @@ -98,66 +75,77 @@ async def show_page(self, index: int) -> None: else: await self.create_base(page) + self.update_disabled_status() + + def update_disabled_status(self): + if self.current == self.first_page(): + # disable << button + if self._buttons_map["<<"]: + self._buttons_map["<<"].disabled = True + + self._buttons_map["<"].disabled = True + else: + if self._buttons_map["<<"]: + self._buttons_map["<<"].disabled = False + + self._buttons_map["<"].disabled = False + + if self.current == self.last_page(): + # disable >> button + if self._buttons_map[">>"] is not None: + self._buttons_map[">>"].disabled = True + + self._buttons_map[">"].disabled = True + else: + if self._buttons_map[">>"] is not None: + self._buttons_map[">>"].disabled = False + + self._buttons_map[">"].disabled = False + + async def create_base(self, item) -> None: + """ + Create a base `Message`. + """ + if len(self.pages) == 1: + self.view = None + self.running = False + else: + self.view = PaginatorView(self, timeout=self.timeout) + self.update_disabled_status() + self.running = True + + await self._create_base(item, self.view) + + async def _create_base(self, item, view: View) -> None: + raise NotImplementedError + async def _show_page(self, page): raise NotImplementedError - def react_check(self, reaction: Reaction, user: User) -> bool: - """ + def first_page(self): + """Returns the index of the first page""" + return 0 - Parameters - ---------- - reaction : Reaction - The `Reaction` object of the reaction. - user : User - The `User` or `Member` object of who sent the reaction. + def next_page(self): + """Returns the index of the next page""" + return min(self.current + 1, self.last_page()) - Returns - ------- - bool - """ - return ( - reaction.message.id == self.base.id - and user.id == self.ctx.author.id - and reaction.emoji in self.reaction_map.keys() - ) + def previous_page(self): + """Returns the index of the previous page""" + return max(self.current - 1, self.first_page()) + + def last_page(self): + """Returns the index of the last page""" + return len(self.pages) - 1 async def run(self) -> typing.Optional[Message]: """ Starts the pagination session. - - Returns - ------- - Optional[Message] - If it's closed before running ends. """ if not self.running: await self.show_page(self.current) - while self.running: - try: - reaction, user = await self.ctx.bot.wait_for( - "reaction_add", check=self.react_check, timeout=self.timeout - ) - except asyncio.TimeoutError: - return await self.close(delete=False) - else: - action = self.reaction_map.get(reaction.emoji) - await action() - try: - await self.base.remove_reaction(reaction, user) - except (HTTPException, InvalidArgument): - pass - - async def previous_page(self) -> None: - """ - Go to the previous page. - """ - await self.show_page(self.current - 1) - - async def next_page(self) -> None: - """ - Go to the next page. - """ - await self.show_page(self.current + 1) + await self.view.wait() + await self.close(delete=False) async def close(self, delete: bool = True) -> typing.Optional[Message]: """ @@ -179,25 +167,92 @@ async def close(self, delete: bool = True) -> typing.Optional[Message]: sent_emoji, _ = await self.ctx.bot.retrieve_emoji() await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) + self.view.clear_items() + self.view.stop() if delete: return await self.base.delete() - try: - await self.base.clear_reactions() - except HTTPException: - pass - async def first_page(self) -> None: - """ - Go to the first page. - """ - await self.show_page(0) +class PaginatorView(View): + """ + View that is used for pagination. - async def last_page(self) -> None: - """ - Go to the last page. - """ - await self.show_page(len(self.pages) - 1) + Parameters + ---------- + handler : PaginatorSession + The paginator session that spawned this view. + timeout : float + How long to wait for before the session closes. + + Attributes + ---------- + handler : PaginatorSession + The paginator session that spawned this view. + timeout : float + How long to wait for before the session closes. + """ + + def __init__(self, handler: PaginatorSession, *args, **kwargs): + super().__init__(*args, **kwargs) + self.handler = handler + self.clear_items() + self.fill_items() + + @discord.ui.button(label="Stop", style=ButtonStyle.danger) + async def stop_button(self, button: Button, interaction: Interaction): + await interaction.response.edit_message(view=self) + await self.handler.close() + + def fill_items(self): + for label, callback in self.handler.callback_map.items(): + if len(self.handler.pages) == 2 and label in ("<<", ">>"): + continue + + if label in ("<<", ">>"): + style = ButtonStyle.secondary + else: + style = ButtonStyle.primary + + button = PageButton(self.handler, callback, label=label, style=style) + + self.handler._buttons_map[label] = button + self.add_item(button) + self.add_item(self.stop_button) + + async def interaction_check(self, interaction: Interaction): + """Only allow the message author to interact""" + if interaction.user != self.handler.ctx.author: + return False + return True + + +class PageButton(Button): + """ + A button that has a callback to jump to the next page + + Parameters + ---------- + handler : PaginatorSession + The paginator session that spawned this view. + page_callback : Callable + A callable that returns an int of the page to go to. + + Attributes + ---------- + handler : PaginatorSession + The paginator session that spawned this view. + page_callback : Callable + A callable that returns an int of the page to go to. + """ + + def __init__(self, handler, page_callback, **kwargs): + super().__init__(**kwargs) + self.handler = handler + self.page_callback = page_callback + + async def callback(self, interaction: Interaction): + await self.handler.show_page(self.page_callback()) + await interaction.response.edit_message(view=self.view) class EmbedPaginatorSession(PaginatorSession): @@ -223,8 +278,8 @@ def add_page(self, item: Embed) -> None: else: raise TypeError("Page must be an Embed object.") - async def _create_base(self, item: Embed) -> None: - self.base = await self.destination.send(embed=item) + async def _create_base(self, item: Embed, view: View) -> None: + self.base = await self.destination.send(embed=item, view=view) async def _show_page(self, page): await self.base.edit(embed=page) @@ -255,9 +310,9 @@ def _set_footer(self): self.embed.set_footer(text=footer_text, icon_url=icon_url) - async def _create_base(self, item: str) -> None: + async def _create_base(self, item: str, view: View) -> None: self._set_footer() - self.base = await self.ctx.send(content=item, embed=self.embed) + self.base = await self.ctx.send(content=item, embed=self.embed, view=view) async def _show_page(self, page) -> None: self._set_footer() diff --git a/core/thread.py b/core/thread.py index 67458f0017..87ffc45ee3 100644 --- a/core/thread.py +++ b/core/thread.py @@ -497,7 +497,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, if self.bot.log_channel is not None and self.channel is not None: if self.bot.config["show_log_url_button"]: view = discord.ui.View() - view.add_item(discord.ui.Button(label='Log link', url=log_url, style=discord.ButtonStyle.url)) + view.add_item(discord.ui.Button(label="Log link", url=log_url, style=discord.ButtonStyle.url)) else: view = None tasks.append(self.bot.log_channel.send(embed=embed, view=view)) From e50cf1fdb60fd10e2952a5cc40b2b648cda9e3d4 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:24:41 +0800 Subject: [PATCH 492/705] Select menus for some embed paginations #2913 --- CHANGELOG.md | 1 + core/paginator.py | 56 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 641b3ffcf4..aa4dea5219 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?fpareply` and `?fpreply` to reply to messages with variables plainly. - `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/kyb3r/modmail/issues/3112)) - `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/kyb3r/modmail/issues/3122)) +- Select menus for certain paginators. ### Improved diff --git a/core/paginator.py b/core/paginator.py index b208bff0a3..bb84aa350f 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -1,8 +1,9 @@ +from collections import OrderedDict import typing import discord from discord import Message, Embed, ButtonStyle, Interaction -from discord.ui import View, Button +from discord.ui import View, Button, Select from discord.ext import commands @@ -35,6 +36,10 @@ class PaginatorSession: The current page number. callback_map : Dict[str, method] A mapping for text to method. + view : PaginatorView + The view that is sent along with the base message. + select_menu : Select + A select menu that will be added to the View. """ def __init__(self, ctx: commands.Context, *pages, **options): @@ -46,6 +51,7 @@ def __init__(self, ctx: commands.Context, *pages, **options): self.pages = list(pages) self.destination = options.get("destination", ctx) self.view = None + self.select_menu = None self.callback_map = { "<<": self.first_page, @@ -195,7 +201,7 @@ class PaginatorView(View): def __init__(self, handler: PaginatorSession, *args, **kwargs): super().__init__(*args, **kwargs) self.handler = handler - self.clear_items() + self.clear_items() # clear first so we can control the order self.fill_items() @discord.ui.button(label="Stop", style=ButtonStyle.danger) @@ -204,6 +210,9 @@ async def stop_button(self, button: Button, interaction: Interaction): await self.handler.close() def fill_items(self): + if self.handler.select_menu is not None: + self.add_item(self.handler.select_menu) + for label, callback in self.handler.callback_map.items(): if len(self.handler.pages) == 2 and label in ("<<", ">>"): continue @@ -255,11 +264,29 @@ async def callback(self, interaction: Interaction): await interaction.response.edit_message(view=self.view) +class PageSelect(Select): + def __init__(self, handler: PaginatorSession, pages: typing.List[typing.Tuple[str]]): + self.handler = handler + options = [] + for n, (label, description) in enumerate(pages): + options.append(discord.SelectOption(label=label, description=description, value=str(n))) + + options = options[:25] # max 25 options + super().__init__(placeholder="Select a page", min_values=1, max_values=1, options=options) + + async def callback(self, interaction: Interaction): + page = int(self.values[0]) + await self.handler.show_page(page) + await interaction.response.edit_message(view=self.view) + + class EmbedPaginatorSession(PaginatorSession): def __init__(self, ctx: commands.Context, *embeds, **options): super().__init__(ctx, *embeds, **options) if len(self.pages) > 1: + select_options = [] + create_select = True for i, embed in enumerate(self.pages): footer_text = f"Page {i + 1} of {len(self.pages)}" if embed.footer.text: @@ -269,9 +296,32 @@ def __init__(self, ctx: commands.Context, *embeds, **options): icon_url = embed.footer.icon.url else: icon_url = Embed.Empty - embed.set_footer(text=footer_text, icon_url=icon_url) + # select menu + if embed.author.name: + title = embed.author.name[:30].strip() + if len(embed.author.name) > 30: + title += "..." + else: + title = embed.title[:30].strip() + if len(embed.title) > 30: + title += "..." + if not title: + create_select = False + + if embed.description: + description = embed.description[:40].replace("*", "").replace("`", "").strip() + if len(embed.description) > 40: + description += "..." + else: + description = "" + select_options.append((title, description)) + + if create_select: + if len(set(x[0] for x in select_options)) != 1: # must have unique authors + self.select_menu = PageSelect(self, select_options) + def add_page(self, item: Embed) -> None: if isinstance(item, Embed): self.pages.append(item) From 77ed926f87949e2fa55bb1c2e6b6b56c2be667ab Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:26:15 +0800 Subject: [PATCH 493/705] Bump version to v4-dev6 --- bot.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index c553686852..3e3a6ec5cf 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev5" +__version__ = "4.0.0-dev6" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 9f722227eb..031fc5073f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev5' +version = '4.0.0-dev6' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 0bdaba666c7540dd9b7b0c2be2fb99677278a040 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:26:36 +0800 Subject: [PATCH 494/705] Remove unused import --- core/paginator.py | 1 - 1 file changed, 1 deletion(-) diff --git a/core/paginator.py b/core/paginator.py index bb84aa350f..c4a4772337 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -1,4 +1,3 @@ -from collections import OrderedDict import typing import discord From a743321e01a8339b07f1dd5e8d2dac46b9f21960 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:56:28 +0800 Subject: [PATCH 495/705] Remove unused import --- core/paginator.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/paginator.py b/core/paginator.py index c4a4772337..3126ddc527 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -173,6 +173,8 @@ async def close(self, delete: bool = True) -> typing.Optional[Message]: await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) self.view.clear_items() + await self.message.edit(view=self.view) + self.view.stop() if delete: return await self.base.delete() From 8011ccd6b71bd2a4b9902e13625a50dc52cddc0a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 20:04:39 +0800 Subject: [PATCH 496/705] Fix closing paginators --- core/paginator.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core/paginator.py b/core/paginator.py index 3126ddc527..3fbd990c4a 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -167,17 +167,18 @@ async def close(self, delete: bool = True) -> typing.Optional[Message]: Optional[Message] If `delete` is `True`. """ - self.running = False - - sent_emoji, _ = await self.ctx.bot.retrieve_emoji() - await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) + if self.running: + self.running = False - self.view.clear_items() - await self.message.edit(view=self.view) + self.view.stop() + if delete: + await self.base.delete() + else: + self.view.clear_items() + await self.base.edit(view=self.view) - self.view.stop() - if delete: - return await self.base.delete() + sent_emoji, _ = await self.ctx.bot.retrieve_emoji() + await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) class PaginatorView(View): From f7a882a62fa7375f89449e1669168fc14c84e1f1 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 20:15:13 +0800 Subject: [PATCH 497/705] Optimise paginators page switching --- core/paginator.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/core/paginator.py b/core/paginator.py index 3fbd990c4a..6525d0ddd0 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -60,7 +60,7 @@ def __init__(self, ctx: commands.Context, *pages, **options): } self._buttons_map = {"<<": None, "<": None, ">": None, ">>": None} - async def show_page(self, index: int) -> None: + async def show_page(self, index: int) -> typing.Optional[typing.Dict]: """ Show a page by page number. @@ -74,13 +74,15 @@ async def show_page(self, index: int) -> None: self.current = index page = self.pages[index] + result = None if self.running: - await self._show_page(page) + result = self._show_page(page) else: await self.create_base(page) self.update_disabled_status() + return result def update_disabled_status(self): if self.current == self.first_page(): @@ -124,7 +126,7 @@ async def create_base(self, item) -> None: async def _create_base(self, item, view: View) -> None: raise NotImplementedError - async def _show_page(self, page): + def _show_page(self, page): raise NotImplementedError def first_page(self): @@ -233,6 +235,7 @@ def fill_items(self): async def interaction_check(self, interaction: Interaction): """Only allow the message author to interact""" if interaction.user != self.handler.ctx.author: + await interaction.response.send_message("Only the original author can control this!", ephemeral=True) return False return True @@ -262,8 +265,8 @@ def __init__(self, handler, page_callback, **kwargs): self.page_callback = page_callback async def callback(self, interaction: Interaction): - await self.handler.show_page(self.page_callback()) - await interaction.response.edit_message(view=self.view) + kwargs = await self.handler.show_page(self.page_callback()) + await interaction.response.edit_message(**kwargs, view=self.view) class PageSelect(Select): @@ -278,8 +281,8 @@ def __init__(self, handler: PaginatorSession, pages: typing.List[typing.Tuple[st async def callback(self, interaction: Interaction): page = int(self.values[0]) - await self.handler.show_page(page) - await interaction.response.edit_message(view=self.view) + kwargs = await self.handler.show_page(page) + await interaction.response.edit_message(**kwargs, view=self.view) class EmbedPaginatorSession(PaginatorSession): @@ -333,8 +336,8 @@ def add_page(self, item: Embed) -> None: async def _create_base(self, item: Embed, view: View) -> None: self.base = await self.destination.send(embed=item, view=view) - async def _show_page(self, page): - await self.base.edit(embed=page) + def _show_page(self, page): + return dict(embed=page) class MessagePaginatorSession(PaginatorSession): @@ -366,6 +369,6 @@ async def _create_base(self, item: str, view: View) -> None: self._set_footer() self.base = await self.ctx.send(content=item, embed=self.embed, view=view) - async def _show_page(self, page) -> None: + def _show_page(self, page) -> typing.Dict: self._set_footer() - await self.base.edit(content=page, embed=self.embed) + return dict(content=page, embed=self.embed) From c16ff261f204f5831da577d26a011db5d65d4610 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Nov 2021 20:21:56 +0800 Subject: [PATCH 498/705] Optimise Stop pagination --- core/paginator.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/core/paginator.py b/core/paginator.py index 6525d0ddd0..b9cd29a26b 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -154,7 +154,9 @@ async def run(self) -> typing.Optional[Message]: await self.view.wait() await self.close(delete=False) - async def close(self, delete: bool = True) -> typing.Optional[Message]: + async def close( + self, delete: bool = True, *, interaction: Interaction = None + ) -> typing.Optional[Message]: """ Closes the pagination session. @@ -170,17 +172,22 @@ async def close(self, delete: bool = True) -> typing.Optional[Message]: If `delete` is `True`. """ if self.running: + sent_emoji, _ = await self.ctx.bot.retrieve_emoji() + await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) + + if interaction: + message = interaction.message + else: + message = self.base + self.running = False self.view.stop() if delete: - await self.base.delete() + await message.delete() else: self.view.clear_items() - await self.base.edit(view=self.view) - - sent_emoji, _ = await self.ctx.bot.retrieve_emoji() - await self.ctx.bot.add_reaction(self.ctx.message, sent_emoji) + await message.edit(view=self.view) class PaginatorView(View): @@ -210,8 +217,7 @@ def __init__(self, handler: PaginatorSession, *args, **kwargs): @discord.ui.button(label="Stop", style=ButtonStyle.danger) async def stop_button(self, button: Button, interaction: Interaction): - await interaction.response.edit_message(view=self) - await self.handler.close() + await self.handler.close(interaction=interaction) def fill_items(self): if self.handler.select_menu is not None: @@ -235,7 +241,9 @@ def fill_items(self): async def interaction_check(self, interaction: Interaction): """Only allow the message author to interact""" if interaction.user != self.handler.ctx.author: - await interaction.response.send_message("Only the original author can control this!", ephemeral=True) + await interaction.response.send_message( + "Only the original author can control this!", ephemeral=True + ) return False return True From 6adcd048d5cd82e6f68487d039249933a51006ab Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Mon, 22 Nov 2021 22:48:40 +0100 Subject: [PATCH 499/705] make config readable --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index 7278c350fc..dbd3ccf279 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -913,7 +913,7 @@ def fmt(val): if current_key == key: index = i embed = discord.Embed( - title=f"Configuration description on {current_key}:", color=self.bot.main_color + title=f"{current_key}", color=self.bot.main_color ) embed.add_field(name="Default:", value=fmt(info["default"]), inline=False) embed.add_field(name="Information:", value=fmt(info["description"]), inline=False) From f8ad5fd16e3b660d1e303dc52b87152af4b5878e Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Tue, 23 Nov 2021 13:15:33 +0530 Subject: [PATCH 500/705] Process snippets in get_contexts --- bot.py | 54 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/bot.py b/bot.py index fb4f8b04a2..d65eee3a48 100644 --- a/bot.py +++ b/bot.py @@ -955,6 +955,16 @@ async def process_dm_modmail(self, message: discord.Message) -> None: await self.add_reaction(message, sent_emoji) self.dispatch("thread_reply", thread, False, message, False, False) + def _get_snippet_command(self) -> commands.Command: + """Get the correct reply command based on the snippet config""" + modifiers = "f" + if self.config["plain_snippets"]: + modifiers += "p" + if self.config["anonymous_snippets"]: + modifiers += "a" + + return self.get_command(f'{modifiers}reply') + async def get_contexts(self, message, *, cls=commands.Context): """ Returns all invocation contexts from the message. @@ -986,18 +996,40 @@ async def get_contexts(self, message, *, cls=commands.Context): self.aliases.pop(invoker) for alias in aliases: - view = StringView(invoked_prefix + alias) + command = None + try: + snippet_text = self.snippets[alias] + except KeyError: + command_invocation_text = alias + else: + command = self._get_snippet_command() + command_invocation_text = f'{invoked_prefix}{command} {snippet_text}' + + view = StringView(invoked_prefix + command_invocation_text) ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) ctx_.thread = thread discord.utils.find(view.skip_string, prefixes) ctx_.invoked_with = view.get_word().lower() - ctx_.command = self.all_commands.get(ctx_.invoked_with) + ctx_.command = command or self.all_commands.get(ctx_.invoked_with) ctxs += [ctx_] return ctxs ctx.thread = thread - ctx.invoked_with = invoker - ctx.command = self.all_commands.get(invoker) + + try: + snippet_text = self.snippets[invoker] + except KeyError: + # Process regular commands + ctx.command = self.all_commands.get(invoker) + ctx.invoked_with = invoker + else: + # Process snippets + ctx.command = self._get_snippet_command() + reply_view = StringView(f'{invoked_prefix}{ctx.command} {snippet_text}') + discord.utils.find(reply_view.skip_string, prefixes) + ctx.invoked_with = reply_view.get_word().lower() + ctx.view = reply_view + return [ctx] async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context): @@ -1139,20 +1171,6 @@ async def process_commands(self, message): if isinstance(message.channel, discord.DMChannel): return await self.process_dm_modmail(message) - if message.content.startswith(self.prefix): - cmd = message.content[len(self.prefix) :].strip() - - # Process snippets - cmd = cmd.lower() - if cmd in self.snippets: - snippet = self.snippets[cmd] - modifiers = "f" - if self.config["plain_snippets"]: - modifiers += "p" - if self.config["anonymous_snippets"]: - modifiers += "a" - message.content = f"{self.prefix}{modifiers}reply {snippet}" - ctxs = await self.get_contexts(message) for ctx in ctxs: if ctx.command: From 4de349111ea1e070bb886e1d69a2cb1d1a038dae Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Tue, 23 Nov 2021 13:17:59 +0530 Subject: [PATCH 501/705] Allow the usage of snippets in `alias add` --- cogs/utility.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index 7278c350fc..89c4467109 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1070,7 +1070,9 @@ async def make_alias(self, name, value, action): linked_command = view.get_word().lower() message = view.read_rest() - if not self.bot.get_command(linked_command): + is_snippet = linked_command in self.bot.snippets and not message + + if not self.bot.get_command(linked_command) and not is_snippet: alias_command = self.bot.aliases.get(linked_command) if alias_command is not None: save_aliases.extend(utils.normalize_alias(alias_command, message)) From 55e90f564dc5fe097f71685e4c1adb29eff9989a Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Sat, 27 Nov 2021 21:42:25 +0530 Subject: [PATCH 502/705] Handle snippet deletions and resolve aliases --- bot.py | 26 +++++++++++- cogs/modmail.py | 104 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 120 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index d65eee3a48..df513ed8ad 100644 --- a/bot.py +++ b/bot.py @@ -46,7 +46,7 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import normalize_alias, truncate, tryint +from core.utils import normalize_alias, parse_alias, truncate, tryint logger = getLogger(__name__) @@ -85,6 +85,30 @@ def __init__(self): self.plugin_db = PluginDatabaseClient(self) # Deprecated self.startup() + def _resolve_snippet(self, name: str) -> typing.Optional[str]: + """ + Get actual snippet names from direct aliases to snippets. + + If the provided name is a snippet, it's returned unchanged. + If there is an alias by this name, it is parsed to see if it + refers only to a snippet, in which case that snippet name is + returned. + + If no snippets were found, None is returned. + """ + if name in self.snippets: + return name + + try: + command, = parse_alias(self.aliases[name]) + except (KeyError, ValueError): + # There is either no alias by this name present or the + # alias has multiple steps. + pass + else: + if command in self.snippets: + return command + @property def uptime(self) -> str: now = discord.utils.utcnow() diff --git a/cogs/modmail.py b/cogs/modmail.py index 7900f0eeef..3d29523421 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -7,6 +7,7 @@ import discord from discord.ext import commands +from discord.ext.commands.view import StringView from discord.ext.commands.cooldowns import BucketType from discord.role import Role from discord.utils import escape_markdown @@ -143,12 +144,14 @@ async def snippet(self, ctx, *, name: str.lower = None): """ if name is not None: - val = self.bot.snippets.get(name) - if val is None: + snippet_name = self.bot._resolve_snippet(name) + + if snippet_name is None: embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") else: + val = self.bot.snippets[snippet_name] embed = discord.Embed( - title=f'Snippet - "{name}":', description=val, color=self.bot.main_color + title=f'Snippet - "{snippet_name}":', description=val, color=self.bot.main_color ) return await ctx.send(embed=embed) @@ -177,13 +180,13 @@ async def snippet_raw(self, ctx, *, name: str.lower): """ View the raw content of a snippet. """ - val = self.bot.snippets.get(name) - if val is None: + snippet_name = self.bot._resolve_snippet(name) + if snippet_name is None: embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") else: - val = truncate(escape_code_block(val), 2048 - 7) + val = truncate(escape_code_block(self.bot.snippets[snippet_name]), 2048 - 7) embed = discord.Embed( - title=f'Raw snippet - "{name}":', + title=f'Raw snippet - "{snippet_name}":', description=f"```\n{val}```", color=self.bot.main_color, ) @@ -246,16 +249,99 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte ) return await ctx.send(embed=embed) + def _fix_aliases(self, snippet_being_deleted: str) -> tuple[list[str]]: + """ + Remove references to the snippet being deleted from aliases. + + Direct aliases to snippets are deleted, and aliases having + other steps are edited. + + A tuple of dictionaries are returned. The first dictionary + contains a mapping of alias names which were deleted to their + original value, and the second dictionary contains a mapping + of alias names which were edited to their original value. + """ + deleted = {} + edited = {} + + # Using a copy since we might need to delete aliases + for alias, val in self.bot.aliases.copy().items(): + values = parse_alias(val) + + save_aliases = [] + + for val in values: + view = StringView(val) + linked_command = view.get_word().lower() + message = view.read_rest() + + if linked_command == snippet_being_deleted: + continue + + is_valid_snippet = snippet_being_deleted in self.bot.snippets + + if not self.bot.get_command(linked_command) and not is_valid_snippet: + alias_command = self.bot.aliases[linked_command] + save_aliases.extend(normalize_alias(alias_command, message)) + else: + save_aliases.append(val) + + if not save_aliases: + original_value = self.bot.aliases.pop(alias) + deleted[alias] = original_value + else: + original_alias = self.bot.aliases[alias] + new_alias = " && ".join(f'"{a}"' for a in save_aliases) + + if original_alias != new_alias: + self.bot.aliases[alias] = new_alias + edited[alias] = original_alias + + return deleted, edited + @snippet.command(name="remove", aliases=["del", "delete"]) @checks.has_permissions(PermissionLevel.SUPPORTER) async def snippet_remove(self, ctx, *, name: str.lower): """Remove a snippet.""" - if name in self.bot.snippets: + deleted_aliases, edited_aliases = self._fix_aliases(name) + + deleted_aliases_string = ','.join(f'`{alias}`' for alias in deleted_aliases) + if len(deleted_aliases) == 1: + deleted_aliases_output = f'The `{deleted_aliases_string}` direct alias has been removed.' + elif deleted_aliases: + deleted_aliases_output = f'The following direct aliases have been removed: {deleted_aliases_string}.' + else: + deleted_aliases_output = None + + if len(edited_aliases) == 1: + alias, val = edited_aliases.popitem() + edited_aliases_output = ( + f'Steps pointing to this snippet have been removed from the `{alias}` alias' + f' (previous value: `{val}`).`' + ) + elif edited_aliases: + alias_list = '\n'.join([ + f'- `{alias_name}` (previous value: `{val}`)' + for alias_name, val in edited_aliases.items() + ]) + edited_aliases_output = ( + f'Steps pointing to this snippet have been removed from the following aliases:' + f'\n\n{alias_list}' + ) + else: + edited_aliases_output = None + + description = f"Snippet `{name}` is now deleted." + if deleted_aliases_output: + description += f'\n\n{deleted_aliases_output}' + if edited_aliases_output: + description += f'\n\n{edited_aliases_output}' + embed = discord.Embed( title="Removed snippet", color=self.bot.main_color, - description=f"Snippet `{name}` is now deleted.", + description=description, ) self.bot.snippets.pop(name) await self.bot.config.update() From 3599f02874a8611ca3e3979d7596fecacd0c1faa Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Sat, 27 Nov 2021 21:42:41 +0530 Subject: [PATCH 503/705] make the help output for snippets list its aliases --- cogs/utility.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index 89c4467109..e38fc0984b 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -184,7 +184,20 @@ async def send_error_message(self, error): val = self.context.bot.snippets.get(command) if val is not None: embed = discord.Embed(title=f"{command} is a snippet.", color=self.context.bot.main_color) - embed.add_field(name=f"`{command}` will send:", value=val) + embed.add_field(name=f"`{command}` will send:", value=val, inline=False) + + snippet_aliases = [] + for alias in self.context.bot.aliases: + if self.context.bot._resolve_snippet(alias) == command: + snippet_aliases.append(f'`{alias}`') + + if snippet_aliases: + embed.add_field( + name=f'Aliases to this snippet:', + value=','.join(snippet_aliases), + inline=False + ) + return await self.get_destination().send(embed=embed) val = self.context.bot.aliases.get(command) From ba93b9c4cf1cd279f5bcf1a148c25435a748dec3 Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Sat, 27 Nov 2021 23:54:44 +0530 Subject: [PATCH 504/705] Handle multi-word snippets --- bot.py | 22 +++++++++++++--------- cogs/utility.py | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index df513ed8ad..f808448429 100644 --- a/bot.py +++ b/bot.py @@ -1010,9 +1010,17 @@ async def get_contexts(self, message, *, cls=commands.Context): invoker = view.get_word().lower() + # Check if a snippet is being called. + # This needs to be done before checking for aliases since + # snippets can have multiple words. + try: + snippet_text = self.snippets[message.content.removeprefix(invoked_prefix)] + except KeyError: + snippet_text = None + # Check if there is any aliases being called. alias = self.aliases.get(invoker) - if alias is not None: + if alias is not None and snippet_text is None: ctxs = [] aliases = normalize_alias(alias, message.content[len(f"{invoked_prefix}{invoker}") :]) if not aliases: @@ -1028,7 +1036,6 @@ async def get_contexts(self, message, *, cls=commands.Context): else: command = self._get_snippet_command() command_invocation_text = f'{invoked_prefix}{command} {snippet_text}' - view = StringView(invoked_prefix + command_invocation_text) ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) ctx_.thread = thread @@ -1040,19 +1047,16 @@ async def get_contexts(self, message, *, cls=commands.Context): ctx.thread = thread - try: - snippet_text = self.snippets[invoker] - except KeyError: - # Process regular commands - ctx.command = self.all_commands.get(invoker) - ctx.invoked_with = invoker - else: + if snippet_text is not None: # Process snippets ctx.command = self._get_snippet_command() reply_view = StringView(f'{invoked_prefix}{ctx.command} {snippet_text}') discord.utils.find(reply_view.skip_string, prefixes) ctx.invoked_with = reply_view.get_word().lower() ctx.view = reply_view + else: + ctx.command = self.all_commands.get(invoker) + ctx.invoked_with = invoker return [ctx] diff --git a/cogs/utility.py b/cogs/utility.py index e38fc0984b..a3f5597519 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1083,7 +1083,7 @@ async def make_alias(self, name, value, action): linked_command = view.get_word().lower() message = view.read_rest() - is_snippet = linked_command in self.bot.snippets and not message + is_snippet = val in self.bot.snippets if not self.bot.get_command(linked_command) and not is_snippet: alias_command = self.bot.aliases.get(linked_command) From 6041d37fbfe2990eb7f9ef2aedce40065b8ea341 Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Sun, 28 Nov 2021 00:08:18 +0530 Subject: [PATCH 505/705] Update the CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4409e12bb..803b5f0c1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/kyb3r/modmail/issues/3048)) - Use discord relative timedeltas. ([GH #3046](https://github.com/kyb3r/modmail/issues/3046)) +- Snippets can be used in aliases. ([GH #3108](https://github.com/kyb3r/modmail/issues/3108)) ### Fixed From 893acc982f738c2384ddd2d274c974322bb8a697 Mon Sep 17 00:00:00 2001 From: Qwerty-133 <74311372+Qwerty-133@users.noreply.github.com> Date: Sun, 28 Nov 2021 17:45:43 +0530 Subject: [PATCH 506/705] Lint --- bot.py | 8 ++++---- cogs/modmail.py | 30 +++++++++++++++++------------- cogs/utility.py | 8 +++----- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/bot.py b/bot.py index f808448429..b01bc30ee9 100644 --- a/bot.py +++ b/bot.py @@ -100,7 +100,7 @@ def _resolve_snippet(self, name: str) -> typing.Optional[str]: return name try: - command, = parse_alias(self.aliases[name]) + (command,) = parse_alias(self.aliases[name]) except (KeyError, ValueError): # There is either no alias by this name present or the # alias has multiple steps. @@ -987,7 +987,7 @@ def _get_snippet_command(self) -> commands.Command: if self.config["anonymous_snippets"]: modifiers += "a" - return self.get_command(f'{modifiers}reply') + return self.get_command(f"{modifiers}reply") async def get_contexts(self, message, *, cls=commands.Context): """ @@ -1035,7 +1035,7 @@ async def get_contexts(self, message, *, cls=commands.Context): command_invocation_text = alias else: command = self._get_snippet_command() - command_invocation_text = f'{invoked_prefix}{command} {snippet_text}' + command_invocation_text = f"{invoked_prefix}{command} {snippet_text}" view = StringView(invoked_prefix + command_invocation_text) ctx_ = cls(prefix=self.prefix, view=view, bot=self, message=message) ctx_.thread = thread @@ -1050,7 +1050,7 @@ async def get_contexts(self, message, *, cls=commands.Context): if snippet_text is not None: # Process snippets ctx.command = self._get_snippet_command() - reply_view = StringView(f'{invoked_prefix}{ctx.command} {snippet_text}') + reply_view = StringView(f"{invoked_prefix}{ctx.command} {snippet_text}") discord.utils.find(reply_view.skip_string, prefixes) ctx.invoked_with = reply_view.get_word().lower() ctx.view = reply_view diff --git a/cogs/modmail.py b/cogs/modmail.py index 3d29523421..f06dc4339c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -306,37 +306,41 @@ async def snippet_remove(self, ctx, *, name: str.lower): if name in self.bot.snippets: deleted_aliases, edited_aliases = self._fix_aliases(name) - deleted_aliases_string = ','.join(f'`{alias}`' for alias in deleted_aliases) + deleted_aliases_string = ",".join(f"`{alias}`" for alias in deleted_aliases) if len(deleted_aliases) == 1: - deleted_aliases_output = f'The `{deleted_aliases_string}` direct alias has been removed.' + deleted_aliases_output = f"The `{deleted_aliases_string}` direct alias has been removed." elif deleted_aliases: - deleted_aliases_output = f'The following direct aliases have been removed: {deleted_aliases_string}.' + deleted_aliases_output = ( + f"The following direct aliases have been removed: {deleted_aliases_string}." + ) else: deleted_aliases_output = None if len(edited_aliases) == 1: alias, val = edited_aliases.popitem() edited_aliases_output = ( - f'Steps pointing to this snippet have been removed from the `{alias}` alias' - f' (previous value: `{val}`).`' + f"Steps pointing to this snippet have been removed from the `{alias}` alias" + f" (previous value: `{val}`).`" ) elif edited_aliases: - alias_list = '\n'.join([ - f'- `{alias_name}` (previous value: `{val}`)' - for alias_name, val in edited_aliases.items() - ]) + alias_list = "\n".join( + [ + f"- `{alias_name}` (previous value: `{val}`)" + for alias_name, val in edited_aliases.items() + ] + ) edited_aliases_output = ( - f'Steps pointing to this snippet have been removed from the following aliases:' - f'\n\n{alias_list}' + f"Steps pointing to this snippet have been removed from the following aliases:" + f"\n\n{alias_list}" ) else: edited_aliases_output = None description = f"Snippet `{name}` is now deleted." if deleted_aliases_output: - description += f'\n\n{deleted_aliases_output}' + description += f"\n\n{deleted_aliases_output}" if edited_aliases_output: - description += f'\n\n{edited_aliases_output}' + description += f"\n\n{edited_aliases_output}" embed = discord.Embed( title="Removed snippet", diff --git a/cogs/utility.py b/cogs/utility.py index a3f5597519..26ae936ffc 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -189,13 +189,11 @@ async def send_error_message(self, error): snippet_aliases = [] for alias in self.context.bot.aliases: if self.context.bot._resolve_snippet(alias) == command: - snippet_aliases.append(f'`{alias}`') + snippet_aliases.append(f"`{alias}`") if snippet_aliases: embed.add_field( - name=f'Aliases to this snippet:', - value=','.join(snippet_aliases), - inline=False + name=f"Aliases to this snippet:", value=",".join(snippet_aliases), inline=False ) return await self.get_destination().send(embed=embed) @@ -1083,7 +1081,7 @@ async def make_alias(self, name, value, action): linked_command = view.get_word().lower() message = view.read_rest() - is_snippet = val in self.bot.snippets + is_snippet = val in self.bot.snippets if not self.bot.get_command(linked_command) and not is_snippet: alias_command = self.bot.aliases.get(linked_command) From aeb1128d83b2a9136cee411e7abe68dce428a18a Mon Sep 17 00:00:00 2001 From: Chris Lovering <chris.lovering.95@gmail.com> Date: Sun, 5 Dec 2021 21:28:56 +0000 Subject: [PATCH 507/705] Add git to Dockerfile Since discord.py is installed via git in requirements.txt the Dockerfile needs to have git installed to download it. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 34aba25ce6..76992efcc5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM python:3.9-slim as py FROM py as build -RUN apt update && apt install -y g++ +RUN apt update && apt install -y g++ git COPY requirements.txt / RUN pip install --prefix=/inst -U -r /requirements.txt From d90c1ecf0d05d2ae6e8aa95a62ab534a32cc3b02 Mon Sep 17 00:00:00 2001 From: Chris Lovering <chris.lovering.95@gmail.com> Date: Sun, 5 Dec 2021 23:04:15 +0000 Subject: [PATCH 508/705] Regenerate reqs.txt and use full python image This is so that all of the requirements for lottie are available within the image --- Dockerfile | 2 +- requirements.txt | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 76992efcc5..2906f4508f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-slim as py +FROM python:3.9 as py FROM py as build diff --git a/requirements.txt b/requirements.txt index fb43d23e2b..737a58c219 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,21 +9,31 @@ aiohttp==3.7.4.post0 async-timeout==3.0.1; python_full_version >= '3.5.3' attrs==21.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +cairocffi==1.3.0; python_version >= '3.7' +cairosvg==2.5.2; python_version >= '3.5' +cffi==1.15.0 chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' colorama==0.4.4 +cssselect2==0.4.1; python_version >= '3.6' +defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' dnspython==2.1.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.2.0 git+https://github.com/Rapptz/discord.py.git@45d498c1b76deaf3b394d17ccf56112fa691d160#egg=discord-py idna==3.3; python_version >= '3.5' isodate==0.6.0 +lottie[pdf]==0.6.10 motor==2.4.0 multidict==5.2.0; python_version >= '3.6' natural==0.2.0 parsedatetime==2.6 +pillow==8.4.0; python_version >= '3.6' +pycparser==2.21 pymongo[srv]==3.12.1 python-dateutil==2.8.2 python-dotenv==0.18.0 six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +tinycss2==1.1.0; python_version >= '3.6' typing-extensions==4.0.0; python_version >= '3.6' uvloop==0.16.0; sys_platform != 'win32' +webencodings==0.5.1 yarl==1.7.2; python_version >= '3.6' \ No newline at end of file From 9b58b99cbc2dc7deb84aad73bfbab09ed696ef80 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 8 Feb 2022 01:59:54 -0800 Subject: [PATCH 509/705] 3.10.3 contact fix --- CHANGELOG.md | 8 ++++++++ README.md | 2 +- bot.py | 2 +- core/models.py | 13 ++++++++----- pyproject.toml | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af6e0cc407..8f9b461169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.10.3 +This is a hotfix for contact command. + +### Fixed + +- Fixed a bug where contacting with no category argument defaults to the top category. + + # v3.10.2 This is a hotfix for react to contact. diff --git a/README.md b/README.md index 2b4f44ea62..465b13f1ab 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v3.10.2-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v3.10.3-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index 7d4248173c..0ee38be340 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.2" +__version__ = "3.10.3" import asyncio diff --git a/core/models.py b/core/models.py index 445f7793ae..670a23c743 100644 --- a/core/models.py +++ b/core/models.py @@ -2,6 +2,7 @@ import re import sys import os +from difflib import get_close_matches from enum import IntEnum from logging.handlers import RotatingFileHandler from string import Formatter @@ -202,13 +203,15 @@ async def convert(self, ctx, argument): return await super().convert(ctx, argument) except commands.ChannelNotFound: - def check(c): - return isinstance(c, discord.CategoryChannel) and c.name.lower().startswith(argument.lower()) - if guild: - result = discord.utils.find(check, guild.categories) + categories = {c.name.casefold(): c for c in guild.categories} else: - result = discord.utils.find(check, bot.get_all_channels()) + categories = {c.name.casefold(): c for c in bot.get_all_channels() + if isinstance(c, discord.CategoryChannel)} + + result = get_close_matches(argument.casefold(), categories.keys(), n=1, cutoff=0.75) + if result: + result = categories[result[0]] if not isinstance(result, discord.CategoryChannel): raise commands.ChannelNotFound(argument) diff --git a/pyproject.toml b/pyproject.toml index 4dc7d411a5..341e506413 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.2' +version = '3.10.3' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From fa718e4023a2b52f90d228e37556e7a5e90225e8 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:11:20 +0800 Subject: [PATCH 510/705] Update to dpy@97fe07edb2f3d0f5a980917fb6ee479bf396fd94 & async changes --- CHANGELOG.md | 4 + Pipfile | 2 +- Pipfile.lock | 708 ++++++++++++++++++++++++---------------------- bot.py | 162 +++++------ cogs/modmail.py | 4 +- cogs/plugins.py | 18 +- cogs/utility.py | 8 +- core/paginator.py | 4 +- core/thread.py | 11 +- pyproject.toml | 2 +- 10 files changed, 466 insertions(+), 457 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4dea5219..209bbcfcea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,10 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Breaking +- Modmail now requires [`Message Content` privileged intent](https://support-dev.discord.com/hc/en-us/articles/4404772028055-Message-Content-Privileged-Intent-for-Verified-Bots). - Upgraded to discord.py v2.0 master ([internal changes](https://gist.github.com/apple502j/f75b4f24652f04de85c7084ffd73ec58), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). - Python 3.8 or higher is required. +- Asyncio changes ([gist](https://gist.github.com/Rapptz/6706e1c8f23ac27c98cee4dd985c8120)) ### Added @@ -41,11 +43,13 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Support LOTTIE stickers. ([GH #3119](https://github.com/kyb3r/modmail/issues/3119)) - Editing notes now work. ([GH #3094](https://github.com/kyb3r/modmail/issues/3094)) - Commands now work in threads. +- Audit log searching now properly works. ### Internal - Improve regex parsing of channel topics. ([GH #3114](https://github.com/kyb3r/modmail/issues/3114), [PR #3111](https://github.com/kyb3r/modmail/pull/3111)) - Add warning if deploying on a developmental version. +- Extensions are now loaded `on_connect`. # v3.10.3 diff --git a/Pipfile b/Pipfile index a78db95d18..04d998cbc8 100644 --- a/Pipfile +++ b/Pipfile @@ -11,7 +11,7 @@ pylint = "~=2.9.3" [packages] aiohttp = "==3.7.4.post0" colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 -"discord.py" = {ref = "45d498c1b76deaf3b394d17ccf56112fa691d160", git = "https://github.com/Rapptz/discord.py.git"} +"discord.py" = {ref = "97fe07edb2f3d0f5a980917fb6ee479bf396fd94", git = "https://github.com/Rapptz/discord.py.git"} emoji = "~=1.2.0" isodate = "~=0.6.0" motor = "~=2.4.0" diff --git a/Pipfile.lock b/Pipfile.lock index 1fa9e5e64a..5cd3d63616 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "29d6f377cdb874102deb4df1406ff6d0a66834fcb89660f3c9599a2343cda038" + "sha256": "5f3ca86a89bbc9bcda36bdb3503c91f81ff9c5e12409c3ad056524aa920f4fad" }, "pipfile-spec": 6, "requires": { @@ -69,11 +69,11 @@ }, "attrs": { "hashes": [ - "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", - "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" + "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", + "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.2.0" + "version": "==21.4.0" }, "cairocffi": { "hashes": [ @@ -163,11 +163,11 @@ }, "cssselect2": { "hashes": [ - "sha256:2f4a9f20965367bae459e3bb42561f7927e0cfe5b7ea1692757cf67ef5d7dace", - "sha256:93fbb9af860e95dd40bf18c3b2b6ed99189a07c0f29ba76f9c5be71344664ec8" + "sha256:8d4690bce5f25013262997e64cef3e7bade877d3ef126f9cc624e5b1f294d934", + "sha256:d98a7bbdd8ebc46093279195d669a3359bd5a23f90c19e82c19d9eeef333e617" ], - "markers": "python_version >= '3.6'", - "version": "==0.4.1" + "markers": "python_version >= '3.7'", + "version": "==0.5.0" }, "defusedxml": { "hashes": [ @@ -179,19 +179,19 @@ }, "discord-py": { "git": "https://github.com/Rapptz/discord.py.git", - "ref": "45d498c1b76deaf3b394d17ccf56112fa691d160" + "ref": "97fe07edb2f3d0f5a980917fb6ee479bf396fd94" }, "discord.py": { "git": "https://github.com/Rapptz/discord.py.git", - "ref": "45d498c1b76deaf3b394d17ccf56112fa691d160" + "ref": "97fe07edb2f3d0f5a980917fb6ee479bf396fd94" }, "dnspython": { "hashes": [ - "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216", - "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4" + "sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e", + "sha256:a851e51367fb93e9e1361732c1d60dab63eff98712e503ea7d92e6eccb109b4f" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.1.0" + "version": "==2.2.1" }, "emoji": { "hashes": [ @@ -211,11 +211,11 @@ }, "isodate": { "hashes": [ - "sha256:2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", - "sha256:aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81" + "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96", + "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9" ], "index": "pypi", - "version": "==0.6.0" + "version": "==0.6.1" }, "lottie": { "extras": [ @@ -237,81 +237,68 @@ }, "multidict": { "hashes": [ - "sha256:06560fbdcf22c9387100979e65b26fba0816c162b888cb65b845d3def7a54c9b", - "sha256:067150fad08e6f2dd91a650c7a49ba65085303fcc3decbd64a57dc13a2733031", - "sha256:0a2cbcfbea6dc776782a444db819c8b78afe4db597211298dd8b2222f73e9cd0", - "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce", - "sha256:0fed465af2e0eb6357ba95795d003ac0bdb546305cc2366b1fc8f0ad67cc3fda", - "sha256:116347c63ba049c1ea56e157fa8aa6edaf5e92925c9b64f3da7769bdfa012858", - "sha256:1b4ac3ba7a97b35a5ccf34f41b5a8642a01d1e55454b699e5e8e7a99b5a3acf5", - "sha256:1c7976cd1c157fa7ba5456ae5d31ccdf1479680dc9b8d8aa28afabc370df42b8", - "sha256:246145bff76cc4b19310f0ad28bd0769b940c2a49fc601b86bfd150cbd72bb22", - "sha256:25cbd39a9029b409167aa0a20d8a17f502d43f2efebfe9e3ac019fe6796c59ac", - "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e", - "sha256:2d1d55cdf706ddc62822d394d1df53573d32a7a07d4f099470d3cb9323b721b6", - "sha256:2e77282fd1d677c313ffcaddfec236bf23f273c4fba7cdf198108f5940ae10f5", - "sha256:32fdba7333eb2351fee2596b756d730d62b5827d5e1ab2f84e6cbb287cc67fe0", - "sha256:35591729668a303a02b06e8dba0eb8140c4a1bfd4c4b3209a436a02a5ac1de11", - "sha256:380b868f55f63d048a25931a1632818f90e4be71d2081c2338fcf656d299949a", - "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55", - "sha256:38ba256ee9b310da6a1a0f013ef4e422fca30a685bcbec86a969bd520504e341", - "sha256:3bc3b1621b979621cee9f7b09f024ec76ec03cc365e638126a056317470bde1b", - "sha256:3d2d7d1fff8e09d99354c04c3fd5b560fb04639fd45926b34e27cfdec678a704", - "sha256:517d75522b7b18a3385726b54a081afd425d4f41144a5399e5abd97ccafdf36b", - "sha256:5f79c19c6420962eb17c7e48878a03053b7ccd7b69f389d5831c0a4a7f1ac0a1", - "sha256:5f841c4f14331fd1e36cbf3336ed7be2cb2a8f110ce40ea253e5573387db7621", - "sha256:637c1896497ff19e1ee27c1c2c2ddaa9f2d134bbb5e0c52254361ea20486418d", - "sha256:6ee908c070020d682e9b42c8f621e8bb10c767d04416e2ebe44e37d0f44d9ad5", - "sha256:77f0fb7200cc7dedda7a60912f2059086e29ff67cefbc58d2506638c1a9132d7", - "sha256:7878b61c867fb2df7a95e44b316f88d5a3742390c99dfba6c557a21b30180cac", - "sha256:78c106b2b506b4d895ddc801ff509f941119394b89c9115580014127414e6c2d", - "sha256:8b911d74acdc1fe2941e59b4f1a278a330e9c34c6c8ca1ee21264c51ec9b67ef", - "sha256:93de39267c4c676c9ebb2057e98a8138bade0d806aad4d864322eee0803140a0", - "sha256:9416cf11bcd73c861267e88aea71e9fcc35302b3943e45e1dbb4317f91a4b34f", - "sha256:94b117e27efd8e08b4046c57461d5a114d26b40824995a2eb58372b94f9fca02", - "sha256:9815765f9dcda04921ba467957be543423e5ec6a1136135d84f2ae092c50d87b", - "sha256:98ec9aea6223adf46999f22e2c0ab6cf33f5914be604a404f658386a8f1fba37", - "sha256:a37e9a68349f6abe24130846e2f1d2e38f7ddab30b81b754e5a1fde32f782b23", - "sha256:a43616aec0f0d53c411582c451f5d3e1123a68cc7b3475d6f7d97a626f8ff90d", - "sha256:a4771d0d0ac9d9fe9e24e33bed482a13dfc1256d008d101485fe460359476065", - "sha256:a5635bcf1b75f0f6ef3c8a1ad07b500104a971e38d3683167b9454cb6465ac86", - "sha256:a9acb76d5f3dd9421874923da2ed1e76041cb51b9337fd7f507edde1d86535d6", - "sha256:ac42181292099d91217a82e3fa3ce0e0ddf3a74fd891b7c2b347a7f5aa0edded", - "sha256:b227345e4186809d31f22087d0265655114af7cda442ecaf72246275865bebe4", - "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7", - "sha256:b70913cbf2e14275013be98a06ef4b412329fe7b4f83d64eb70dce8269ed1e1a", - "sha256:b9aad49466b8d828b96b9e3630006234879c8d3e2b0a9d99219b3121bc5cdb17", - "sha256:baf1856fab8212bf35230c019cde7c641887e3fc08cadd39d32a421a30151ea3", - "sha256:bd6c9c50bf2ad3f0448edaa1a3b55b2e6866ef8feca5d8dbec10ec7c94371d21", - "sha256:c1ff762e2ee126e6f1258650ac641e2b8e1f3d927a925aafcfde943b77a36d24", - "sha256:c30ac9f562106cd9e8071c23949a067b10211917fdcb75b4718cf5775356a940", - "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac", - "sha256:cdd68778f96216596218b4e8882944d24a634d984ee1a5a049b300377878fa7c", - "sha256:ce8cacda0b679ebc25624d5de66c705bc53dcc7c6f02a7fb0f3ca5e227d80422", - "sha256:cfde464ca4af42a629648c0b0d79b8f295cf5b695412451716531d6916461628", - "sha256:d3def943bfd5f1c47d51fd324df1e806d8da1f8e105cc7f1c76a1daf0f7e17b0", - "sha256:d9b668c065968c5979fe6b6fa6760bb6ab9aeb94b75b73c0a9c1acf6393ac3bf", - "sha256:da7d57ea65744d249427793c042094c4016789eb2562576fb831870f9c878d9e", - "sha256:dc3a866cf6c13d59a01878cd806f219340f3e82eed514485e094321f24900677", - "sha256:df23c83398715b26ab09574217ca21e14694917a0c857e356fd39e1c64f8283f", - "sha256:dfc924a7e946dd3c6360e50e8f750d51e3ef5395c95dc054bc9eab0f70df4f9c", - "sha256:e4a67f1080123de76e4e97a18d10350df6a7182e243312426d508712e99988d4", - "sha256:e5283c0a00f48e8cafcecadebfa0ed1dac8b39e295c7248c44c665c16dc1138b", - "sha256:e58a9b5cc96e014ddf93c2227cbdeca94b56a7eb77300205d6e4001805391747", - "sha256:e6453f3cbeb78440747096f239d282cc57a2997a16b5197c9bc839099e1633d0", - "sha256:e6c4fa1ec16e01e292315ba76eb1d012c025b99d22896bd14a66628b245e3e01", - "sha256:e7d81ce5744757d2f05fc41896e3b2ae0458464b14b5a2c1e87a6a9d69aefaa8", - "sha256:ea21d4d5104b4f840b91d9dc8cbc832aba9612121eaba503e54eaab1ad140eb9", - "sha256:ecc99bce8ee42dcad15848c7885197d26841cb24fa2ee6e89d23b8993c871c64", - "sha256:f0bb0973f42ffcb5e3537548e0767079420aefd94ba990b61cf7bb8d47f4916d", - "sha256:f19001e790013ed580abfde2a4465388950728861b52f0da73e8e8a9418533c0", - "sha256:f76440e480c3b2ca7f843ff8a48dc82446b86ed4930552d736c0bac507498a52", - "sha256:f9bef5cff994ca3026fcc90680e326d1a19df9841c5e3d224076407cc21471a1", - "sha256:fc66d4016f6e50ed36fb39cd287a3878ffcebfa90008535c62e0e90a7ab713ae", - "sha256:fd77c8f3cba815aa69cb97ee2b2ef385c7c12ada9c734b0f3b32e26bb88bbf1d" + "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60", + "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c", + "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672", + "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51", + "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032", + "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2", + "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b", + "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80", + "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88", + "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a", + "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d", + "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389", + "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c", + "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9", + "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c", + "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516", + "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b", + "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43", + "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee", + "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227", + "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d", + "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae", + "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7", + "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4", + "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9", + "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f", + "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013", + "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9", + "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e", + "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693", + "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a", + "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15", + "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb", + "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96", + "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87", + "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376", + "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658", + "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0", + "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071", + "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360", + "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc", + "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3", + "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba", + "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8", + "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9", + "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2", + "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3", + "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68", + "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8", + "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d", + "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49", + "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608", + "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57", + "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86", + "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20", + "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293", + "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849", + "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937", + "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d" ], - "markers": "python_version >= '3.6'", - "version": "==5.2.0" + "markers": "python_version >= '3.7'", + "version": "==6.0.2" }, "natural": { "hashes": [ @@ -330,50 +317,44 @@ }, "pillow": { "hashes": [ - "sha256:066f3999cb3b070a95c3652712cffa1a748cd02d60ad7b4e485c3748a04d9d76", - "sha256:0a0956fdc5defc34462bb1c765ee88d933239f9a94bc37d132004775241a7585", - "sha256:0b052a619a8bfcf26bd8b3f48f45283f9e977890263e4571f2393ed8898d331b", - "sha256:1394a6ad5abc838c5cd8a92c5a07535648cdf6d09e8e2d6df916dfa9ea86ead8", - "sha256:1bc723b434fbc4ab50bb68e11e93ce5fb69866ad621e3c2c9bdb0cd70e345f55", - "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc", - "sha256:25a49dc2e2f74e65efaa32b153527fc5ac98508d502fa46e74fa4fd678ed6645", - "sha256:2e4440b8f00f504ee4b53fe30f4e381aae30b0568193be305256b1462216feff", - "sha256:3862b7256046fcd950618ed22d1d60b842e3a40a48236a5498746f21189afbbc", - "sha256:3eb1ce5f65908556c2d8685a8f0a6e989d887ec4057326f6c22b24e8a172c66b", - "sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6", - "sha256:493cb4e415f44cd601fcec11c99836f707bb714ab03f5ed46ac25713baf0ff20", - "sha256:4acc0985ddf39d1bc969a9220b51d94ed51695d455c228d8ac29fcdb25810e6e", - "sha256:5503c86916d27c2e101b7f71c2ae2cddba01a2cf55b8395b0255fd33fa4d1f1a", - "sha256:5b7bb9de00197fb4261825c15551adf7605cf14a80badf1761d61e59da347779", - "sha256:5e9ac5f66616b87d4da618a20ab0a38324dbe88d8a39b55be8964eb520021e02", - "sha256:620582db2a85b2df5f8a82ddeb52116560d7e5e6b055095f04ad828d1b0baa39", - "sha256:62cc1afda735a8d109007164714e73771b499768b9bb5afcbbee9d0ff374b43f", - "sha256:70ad9e5c6cb9b8487280a02c0ad8a51581dcbbe8484ce058477692a27c151c0a", - "sha256:72b9e656e340447f827885b8d7a15fc8c4e68d410dc2297ef6787eec0f0ea409", - "sha256:72cbcfd54df6caf85cc35264c77ede902452d6df41166010262374155947460c", - "sha256:792e5c12376594bfcb986ebf3855aa4b7c225754e9a9521298e460e92fb4a488", - "sha256:7b7017b61bbcdd7f6363aeceb881e23c46583739cb69a3ab39cb384f6ec82e5b", - "sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d", - "sha256:82aafa8d5eb68c8463b6e9baeb4f19043bb31fefc03eb7b216b51e6a9981ae09", - "sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b", - "sha256:8c803ac3c28bbc53763e6825746f05cc407b20e4a69d0122e526a582e3b5e153", - "sha256:93ce9e955cc95959df98505e4608ad98281fff037350d8c2671c9aa86bcf10a9", - "sha256:9a3e5ddc44c14042f0844b8cf7d2cd455f6cc80fd7f5eefbe657292cf601d9ad", - "sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df", - "sha256:a5a4532a12314149d8b4e4ad8ff09dde7427731fcfa5917ff16d0291f13609df", - "sha256:b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed", - "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed", - "sha256:c70e94281588ef053ae8998039610dbd71bc509e4acbc77ab59d7d2937b10698", - "sha256:c8a17b5d948f4ceeceb66384727dde11b240736fddeda54ca740b9b8b1556b29", - "sha256:d82cdb63100ef5eedb8391732375e6d05993b765f72cb34311fab92103314649", - "sha256:d89363f02658e253dbd171f7c3716a5d340a24ee82d38aab9183f7fdf0cdca49", - "sha256:d99ec152570e4196772e7a8e4ba5320d2d27bf22fdf11743dd882936ed64305b", - "sha256:ddc4d832a0f0b4c52fff973a0d44b6c99839a9d016fe4e6a1cb8f3eea96479c2", - "sha256:e3dacecfbeec9a33e932f00c6cd7996e62f53ad46fbe677577394aaa90ee419a", - "sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78" + "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97", + "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049", + "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c", + "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae", + "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28", + "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030", + "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56", + "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976", + "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e", + "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e", + "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f", + "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b", + "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a", + "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e", + "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa", + "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7", + "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00", + "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838", + "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360", + "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b", + "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a", + "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd", + "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4", + "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70", + "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204", + "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc", + "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b", + "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669", + "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7", + "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e", + "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c", + "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092", + "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c", + "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5", + "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac" ], - "markers": "python_version >= '3.6'", - "version": "==8.4.0" + "markers": "python_version >= '3.7'", + "version": "==9.0.1" }, "pycparser": { "hashes": [ @@ -387,116 +368,116 @@ "srv" ], "hashes": [ - "sha256:02e0c088f189ca69fac094cb5f851b43bbbd7cec42114495777d4d8f297f7f8a", - "sha256:138248c542051eb462f88b50b0267bd5286d6661064bab06faa0ef6ac30cdb4b", - "sha256:13a7c6d055af58a1e9c505e736da8b6a2e95ccc8cec10b008143f7a536e5de8a", - "sha256:13d74bf3435c1e58d8fafccc0d5e87f246ae2c6e9cbef4b35e32a1c3759e354f", - "sha256:15dae01341571d0af51526b7a21648ca575e9375e16ba045c9860848dfa8952f", - "sha256:17238115e6d37f5423b046cb829f1ca02c4ea7edb163f5b8b88e0c975dc3fec9", - "sha256:180b405e17b90a877ea5dbc5efe7f4c171af4c89323148e100c0f12cedb86f12", - "sha256:1821ce4e5a293313947fd017bbd2d2535aa6309680fa29b33d0442d15da296ec", - "sha256:1a7b138a04fdd17849930dc8bf664002e17db38448850bfb96d200c9c5a8b3a1", - "sha256:1c4e51a3b69789b6f468a8e881a13f2d1e8f5e99e41f80fd44845e6ec0f701e1", - "sha256:1d55982e5335925c55e2b87467043866ce72bd30ea7e7e3eeed6ec3d95a806d4", - "sha256:1fa6f08ddb6975371777f97592d35c771e713ee2250e55618148a5e57e260aff", - "sha256:2174d3279b8e2b6d7613b338f684cd78ff7adf1e7ec5b7b7bde5609a129c9898", - "sha256:2462a68f6675da548e333fa299d8e9807e00f95a4d198cfe9194d7be69f40c9b", - "sha256:25fd76deabe9ea37c8360c362b32f702cc095a208dd1c5328189938ca7685847", - "sha256:287c2a0063267c1458c4ddf528b44063ce7f376a6436eea5bccd7f625bbc3b5e", - "sha256:2d3abe548a280b49269c7907d5b71199882510c484d680a5ea7860f30c4a695f", - "sha256:2fa101bb23619120673899694a65b094364269e597f551a87c4bdae3a474d726", - "sha256:2fda3b3fb5c0d159195ab834b322a23808f1b059bcc7e475765abeddee6a2529", - "sha256:303531649fa45f96b694054c1aa02f79bda32ef57affe42c5c339336717eed74", - "sha256:36806ee53a85c3ba73939652f2ced2961e6a77cfbae385cd83f2e24cd97964b7", - "sha256:37a63da5ee623acdf98e6d511171c8a5827a6106b0712c18af4441ef4f11e6be", - "sha256:3a2fcbd04273a509fa85285d9eccf17ab65ce440bd4f5e5a58c978e563cd9e9a", - "sha256:3b40e36d3036bfe69ba63ec8e746a390721f75467085a0384b528e1dda532c69", - "sha256:4168b6c425d783e81723fc3dc382d374a228ff29530436a472a36d9f27593e73", - "sha256:444c00ebc20f2f9dc62e34f7dc9453dc2f5f5a72419c8dccad6e26d546c35712", - "sha256:45d6b47d70ed44e3c40bef618ed61866c48176e7e5dff80d06d8b1a6192e8584", - "sha256:460bdaa3f65ddb5b7474ae08589a1763b5da1a78b8348351b9ba1c63b459d67d", - "sha256:47ed77f62c8417a86f9ad158b803f3459a636386cb9d3d4e9e7d6a82d051f907", - "sha256:48722e91981bb22a16b0431ea01da3e1cc5b96805634d3b8d3c2a5315c1ce7f1", - "sha256:49b0d92724d3fce1174fd30b0b428595072d5c6b14d6203e46a9ea347ae7b439", - "sha256:4a2d73a9281faefb273a5448f6d25f44ebd311ada9eb79b6801ae890508fe231", - "sha256:4f4bc64fe9cbd70d46f519f1e88c9e4677f7af18ab9cd4942abce2bcfa7549c3", - "sha256:5067c04d3b19c820faac6342854d887ade58e8d38c3db79b68c2a102bbb100e7", - "sha256:51437c77030bed72d57d8a61e22758e3c389b13fea7787c808030002bb05ca39", - "sha256:515e4708d6567901ffc06476a38abe2c9093733f52638235d9f149579c1d3de0", - "sha256:5183b698d6542219e4135de583b57bc6286bd37df7f645b688278eb919bfa785", - "sha256:56feb80ea1f5334ccab9bd16a5161571ab70392e51fcc752fb8a1dc67125f663", - "sha256:573e2387d0686976642142c50740dfc4d3494cc627e2a7d22782b99f70879055", - "sha256:58a67b3800476232f9989e533d0244060309451b436d46670a53e6d189f1a7e7", - "sha256:5e3833c001a04aa06a28c6fd9628256862a654c09b0f81c07734b5629bc014ab", - "sha256:5f5fe59328838fa28958cc06ecf94be585726b97d637012f168bc3c7abe4fd81", - "sha256:6235bf2157aa46e53568ed79b70603aa8874baa202d5d1de82fa0eb917696e73", - "sha256:63be03f7ae1e15e72a234637ec7941ef229c7ab252c9ff6af48bba1e5418961c", - "sha256:65f159c445761cab04b665fc448b3fc008aebc98e54fdcbfd1aff195ef1b1408", - "sha256:67e0b2ad3692f6d0335ae231a40de55ec395b6c2e971ad6f55b162244d1ec542", - "sha256:68409171ab2aa7ccd6e8e839233e4b8ddeec246383c9a3698614e814739356f9", - "sha256:6a96c04ce39d66df60d9ce89f4c254c4967bc7d9e2e2c52adc58f47be826ee96", - "sha256:6ead0126fb4424c6c6a4fdc603d699a9db7c03cdb8eac374c352a75fec8a820a", - "sha256:6eb6789f26c398c383225e1313c8e75a7d290d323b8eaf65f3f3ddd0eb8a5a3c", - "sha256:6f07888e3b73c0dfa46f12d098760494f5f23fd66923a6615edfe486e6a7649c", - "sha256:6f0f0a10f128ea0898e607d351ebfabf70941494fc94e87f12c76e2894d8e6c4", - "sha256:704879b6a54c45ad76cea7c6789c1ae7185050acea7afd15b58318fa1932ed45", - "sha256:7117bfd8827cfe550f65a3c399dcd6e02226197a91c6d11a3540c3e8efc686d6", - "sha256:712de1876608fd5d76abc3fc8ec55077278dd5044073fbe9492631c9a2c58351", - "sha256:75c7ef67b4b8ec070e7a4740764f6c03ec9246b59d95e2ae45c029d41cb9efa1", - "sha256:77dddf596fb065de29fb39992fbc81301f7fd0003be649b7fa7448c77ca53bed", - "sha256:7abc87e45b572eb6d17a50422e69a9e5d6f13e691e821fe2312df512500faa50", - "sha256:7d8cdd2f070c71366e64990653522cce84b08dc26ab0d1fa19aa8d14ee0cf9ba", - "sha256:81ce5f871f5d8e82615c8bd0b34b68a9650204c8b1a04ce7890d58c98eb66e39", - "sha256:837cdef094f39c6f4a2967abc646a412999c2540fbf5d3cce1dd3b671f4b876c", - "sha256:849e641cfed05c75d772f9e9018f42c5fbd00655d43d52da1b9c56346fd3e4cc", - "sha256:87114b995506e7584cf3daf891e419b5f6e7e383e7df6267494da3a76312aa22", - "sha256:87db421c9eb915b8d9a9a13c5b2ee338350e36ee83e26ff0adfc48abc5db3ac3", - "sha256:8851544168703fb519e95556e3b463fca4beeef7ed3f731d81a68c8268515d9d", - "sha256:891f541c7ed29b95799da0cd249ae1db1842777b564e8205a197b038c5df6135", - "sha256:8f87f53c9cd89010ae45490ec2c963ff18b31f5f290dc08b04151709589fe8d9", - "sha256:9641be893ccce7d192a0094efd0a0d9f1783a1ebf314b4128f8a27bfadb8a77c", - "sha256:979e34db4f3dc5710c18db437aaf282f691092b352e708cb2afd4df287698c76", - "sha256:9b62d84478f471fdb0dcea3876acff38f146bd23cbdbed15074fb4622064ec2e", - "sha256:a472ca3d43d33e596ff5836c6cc71c3e61be33f44fe1cfdab4a1100f4af60333", - "sha256:a5dbeeea6a375fbd79448b48a54c46fc9351611a03ef8398d2a40b684ce46194", - "sha256:a7430f3987d232e782304c109be1d0e6fff46ca6405cb2479e4d8d08cd29541e", - "sha256:a81e52dbf95f236a0c89a5abcd2b6e1331da0c0312f471c73fae76c79d2acf6b", - "sha256:aa434534cc91f51a85e3099dc257ee8034b3d2be77f2ca58fb335a686e3a681f", - "sha256:ab27d6d7d41a66d9e54269a290d27cd5c74f08e9add0054a754b4821026c4f42", - "sha256:adb37bf22d25a51b84d989a2a5c770d4514ac590201eea1cb50ce8c9c5257f1d", - "sha256:afb16330ab6efbbf995375ad94e970fa2f89bb46bd10d854b7047620fdb0d67d", - "sha256:b1b06038c9940a49c73db0aeb0f6809b308e198da1326171768cf68d843af521", - "sha256:b1e6d1cf4bd6552b5f519432cce1530c09e6b0aab98d44803b991f7e880bd332", - "sha256:bf2d9d62178bb5c05e77d40becf89c309b1966fbcfb5c306238f81bf1ec2d6a2", - "sha256:bfd073fea04061019a103a288847846b5ef40dfa2f73b940ed61e399ca95314f", - "sha256:c04e84ccf590933a266180286d8b6a5fc844078a5d934432628301bd8b5f9ca7", - "sha256:c0947d7be30335cb4c3d5d0983d8ebc8294ae52503cf1d596c926f7e7183900b", - "sha256:c2a17752f97a942bdb4ff4a0516a67c5ade1658ebe1ab2edacdec0b42e39fa75", - "sha256:c4653830375ab019b86d218c749ad38908b74182b2863d09936aa8d7f990d30e", - "sha256:c660fd1e4a4b52f79f7d134a3d31d452948477b7f46ff5061074a534c5805ba6", - "sha256:cb48ff6cc6109190e1ccf8ea1fc71cc244c9185813ce7d1c415dce991cfb8709", - "sha256:cef2675004d85d85a4ccc24730b73a99931547368d18ceeed1259a2d9fcddbc1", - "sha256:d1b98539b0de822b6f717498e59ae3e5ae2e7f564370ab513e6d0c060753e447", - "sha256:d6c6989c10008ac70c2bb2ad2b940fcfe883712746c89f7e3308c14c213a70d7", - "sha256:db3efec9dcecd96555d752215797816da40315d61878f90ca39c8e269791bf17", - "sha256:dc4749c230a71b34db50ac2481d9008bb17b67c92671c443c3b40e192fbea78e", - "sha256:dcf906c1f7a33e4222e4bff18da1554d69323bc4dd95fe867a6fa80709ee5f93", - "sha256:e2bccadbe313b11704160aaba5eec95d2da1aa663f02f41d2d1520d02bbbdcd5", - "sha256:e30cce3cc86d6082c8596b3fbee0d4f54bc4d337a4fa1bf536920e2e319e24f0", - "sha256:e5d6428b8b422ba5205140e8be11722fa7292a0bedaa8bc80fb34c92eb19ba45", - "sha256:e841695b5dbea38909ab2dbf17e91e9a823412d8d88d1ef77f1b94a7bc551c0f", - "sha256:eb65ec0255a0fccc47c87d44e505ef5180bfd71690bd5f84161b1f23949fb209", - "sha256:ed20ec5a01c43254f6047c5d8124b70d28e39f128c8ad960b437644fe94e1827", - "sha256:ed751a20840a31242e7bea566fcf93ba75bc11b33afe2777bbf46069c1af5094", - "sha256:ef8b927813c27c3bdfc82c55682d7767403bcdadfd9f9c0fc49f4be4553a877b", - "sha256:f43cacda46fc188f998e6d308afe1c61ff41dcb300949f4cbf731e9a0a5eb2d3", - "sha256:f44bea60fd2178d7153deef9621c4b526a93939da30010bba24d3408a98b0f79", - "sha256:fcc021530b7c71069132fe4846d95a3cdd74d143adc2f7e398d5fabf610f111c", - "sha256:fe16517b275031d61261a4e3941c411fb7c46a9cd012f02381b56e7907cc9e06", - "sha256:fe3ae4294d593da54862f0140fdcc89d1aeeb94258ca97f094119ed7f0e5882d" + "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", + "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", + "sha256:0a02313e71b7c370c43056f6b16c45effbb2d29a44d24403a3d5ba6ed322fa3f", + "sha256:0a89cadc0062a5e53664dde043f6c097172b8c1c5f0094490095282ff9995a5f", + "sha256:0be605bfb8461384a4cb81e80f51eb5ca1b89851f2d0e69a75458c788a7263a4", + "sha256:0d52a70350ec3dfc39b513df12b03b7f4c8f8ec6873bbf958299999db7b05eb1", + "sha256:0e7a5d0b9077e8c3e57727f797ee8adf12e1d5e7534642230d98980d160d1320", + "sha256:145d78c345a38011497e55aff22c0f8edd40ee676a6810f7e69563d68a125e83", + "sha256:14dee106a10b77224bba5efeeb6aee025aabe88eb87a2b850c46d3ee55bdab4a", + "sha256:176fdca18391e1206c32fb1d8265628a84d28333c20ad19468d91e3e98312cd1", + "sha256:1b4c535f524c9d8c86c3afd71d199025daa070859a2bdaf94a298120b0de16db", + "sha256:1b5cb75d2642ff7db823f509641f143f752c0d1ab03166cafea1e42e50469834", + "sha256:1c6c71e198b36f0f0dfe354f06d3655ecfa30d69493a1da125a9a54668aad652", + "sha256:1c771f1a8b3cd2d697baaf57e9cfa4ae42371cacfbea42ea01d9577c06d92f96", + "sha256:208a61db8b8b647fb5b1ff3b52b4ed6dbced01eac3b61009958adb203596ee99", + "sha256:2157d68f85c28688e8b723bbe70c8013e0aba5570e08c48b3562f74d33fc05c4", + "sha256:2301051701b27aff2cbdf83fae22b7ca883c9563dfd088033267291b46196643", + "sha256:2567885ff0c8c7c0887ba6cefe4ae4af96364a66a7069f924ce0cd12eb971d04", + "sha256:2577b8161eeae4dd376d13100b2137d883c10bb457dd08935f60c9f9d4b5c5f6", + "sha256:27e5ea64332385385b75414888ce9d1a9806be8616d7cef4ef409f4f256c6d06", + "sha256:28bfd5244d32faf3e49b5a8d1fab0631e922c26e8add089312e4be19fb05af50", + "sha256:295a5beaecb7bf054c1c6a28749ed72b19f4d4b61edcd8a0815d892424baf780", + "sha256:2c46a0afef69d61938a6fe32c3afd75b91dec3ab3056085dc72abbeedcc94166", + "sha256:3100a2352bdded6232b385ceda0c0a4624598c517d52c2d8cf014b7abbebd84d", + "sha256:320a1fe403dd83a35709fcf01083d14bc1462e9789b711201349a9158db3a87e", + "sha256:320f8734553c50cffe8a8e1ae36dfc7d7be1941c047489db20a814d2a170d7b5", + "sha256:33ab8c031f788609924e329003088831045f683931932a52a361d4a955b7dce2", + "sha256:3492ae1f97209c66af70e863e6420e6301cecb0a51a5efa701058aa73a8ca29e", + "sha256:351a2efe1c9566c348ad0076f4bf541f4905a0ebe2d271f112f60852575f3c16", + "sha256:3f0ac6e0203bd88863649e6ed9c7cfe53afab304bc8225f2597c4c0a74e4d1f0", + "sha256:3fedad05147b40ff8a93fcd016c421e6c159f149a2a481cfa0b94bfa3e473bab", + "sha256:4294f2c1cd069b793e31c2e6d7ac44b121cf7cedccd03ebcc30f3fc3417b314a", + "sha256:463b974b7f49d65a16ca1435bc1c25a681bb7d630509dd23b2e819ed36da0b7f", + "sha256:4e0a3ea7fd01cf0a36509f320226bd8491e0f448f00b8cb89f601c109f6874e1", + "sha256:514e78d20d8382d5b97f32b20c83d1d0452c302c9a135f0a9022236eb9940fda", + "sha256:517b09b1dd842390a965a896d1327c55dfe78199c9f5840595d40facbcd81854", + "sha256:51d1d061df3995c2332ae78f036492cc188cb3da8ef122caeab3631a67bb477e", + "sha256:5296669bff390135528001b4e48d33a7acaffcd361d98659628ece7f282f11aa", + "sha256:5296e5e69243ffd76bd919854c4da6630ae52e46175c804bc4c0e050d937b705", + "sha256:58db209da08a502ce6948841d522dcec80921d714024354153d00b054571993c", + "sha256:5b779e87300635b8075e8d5cfd4fdf7f46078cd7610c381d956bca5556bb8f97", + "sha256:5cf113a46d81cff0559d57aa66ffa473d57d1a9496f97426318b6b5b14fdec1c", + "sha256:5d20072d81cbfdd8e15e6a0c91fc7e3a4948c71e0adebfc67d3b4bcbe8602711", + "sha256:5d67dbc8da2dac1644d71c1839d12d12aa333e266a9964d5b1a49feed036bc94", + "sha256:5f530f35e1a57d4360eddcbed6945aecdaee2a491cd3f17025e7b5f2eea88ee7", + "sha256:5fdffb0cfeb4dc8646a5381d32ec981ae8472f29c695bf09e8f7a8edb2db12ca", + "sha256:602284e652bb56ca8760f8e88a5280636c5b63d7946fca1c2fe0f83c37dffc64", + "sha256:648fcfd8e019b122b7be0e26830a3a2224d57c3e934f19c1e53a77b8380e6675", + "sha256:64b9122be1c404ce4eb367ad609b590394587a676d84bfed8e03c3ce76d70560", + "sha256:6526933760ee1e6090db808f1690a111ec409699c1990efc96f134d26925c37f", + "sha256:6632b1c63d58cddc72f43ab9f17267354ddce563dd5e11eadabd222dcc808808", + "sha256:6f93dbfa5a461107bc3f5026e0d5180499e13379e9404f07a9f79eb5e9e1303d", + "sha256:71c0db2c313ea8a80825fb61b7826b8015874aec29ee6364ade5cb774fe4511b", + "sha256:71c5c200fd37a5322706080b09c3ec8907cf01c377a7187f354fc9e9e13abc73", + "sha256:7738147cd9dbd6d18d5593b3491b4620e13b61de975fd737283e4ad6c255c273", + "sha256:7a6e4dccae8ef5dd76052647d78f02d5d0ffaff1856277d951666c54aeba3ad2", + "sha256:7b4a9fcd95e978cd3c96cdc2096aa54705266551422cf0883c12a4044def31c6", + "sha256:80710d7591d579442c67a3bc7ae9dcba9ff95ea8414ac98001198d894fc4ff46", + "sha256:81a3ebc33b1367f301d1c8eda57eec4868e951504986d5d3fe437479dcdac5b2", + "sha256:8455176fd1b86de97d859fed4ae0ef867bf998581f584c7a1a591246dfec330f", + "sha256:845b178bd127bb074835d2eac635b980c58ec5e700ebadc8355062df708d5a71", + "sha256:87e18f29bac4a6be76a30e74de9c9005475e27100acf0830679420ce1fd9a6fd", + "sha256:89d7baa847383b9814de640c6f1a8553d125ec65e2761ad146ea2e75a7ad197c", + "sha256:8c7ad5cab282f53b9d78d51504330d1c88c83fbe187e472c07e6908a0293142e", + "sha256:8d92c6bb9174d47c2257528f64645a00bbc6324a9ff45a626192797aff01dc14", + "sha256:9252c991e8176b5a2fa574c5ab9a841679e315f6e576eb7cf0bd958f3e39b0ad", + "sha256:93111fd4e08fa889c126aa8baf5c009a941880a539c87672e04583286517450a", + "sha256:95d15cf81cd2fb926f2a6151a9f94c7aacc102b415e72bc0e040e29332b6731c", + "sha256:9d5b66d457d2c5739c184a777455c8fde7ab3600a56d8bbebecf64f7c55169e1", + "sha256:a055d29f1302892a9389a382bed10a3f77708bcf3e49bfb76f7712fa5f391cc6", + "sha256:a1ba93be779a9b8e5e44f5c133dc1db4313661cead8a2fd27661e6cb8d942ee9", + "sha256:a283425e6a474facd73072d8968812d1d9058490a5781e022ccf8895500b83ce", + "sha256:a351986d6c9006308f163c359ced40f80b6cffb42069f3e569b979829951038d", + "sha256:a766157b195a897c64945d4ff87b050bb0e763bb78f3964e996378621c703b00", + "sha256:a8a3540e21213cb8ce232e68a7d0ee49cdd35194856c50b8bd87eeb572fadd42", + "sha256:a8e0a086dbbee406cc6f603931dfe54d1cb2fba585758e06a2de01037784b737", + "sha256:ab23b0545ec71ea346bf50a5d376d674f56205b729980eaa62cdb7871805014b", + "sha256:b0db9a4691074c347f5d7ee830ab3529bc5ad860939de21c1f9c403daf1eda9a", + "sha256:b1b5be40ebf52c3c67ee547e2c4435ed5bc6352f38d23e394520b686641a6be4", + "sha256:b3e08aef4ea05afbc0a70cd23c13684e7f5e074f02450964ec5cfa1c759d33d2", + "sha256:b7df0d99e189b7027d417d4bfd9b8c53c9c7ed5a0a1495d26a6f547d820eca88", + "sha256:be1f10145f7ea76e3e836fdc5c8429c605675bdcddb0bca9725ee6e26874c00c", + "sha256:bf254a1a95e95fdf4eaa25faa1ea450a6533ed7a997f9f8e49ab971b61ea514d", + "sha256:bfc2d763d05ec7211313a06e8571236017d3e61d5fef97fcf34ec4b36c0b6556", + "sha256:c164eda0be9048f83c24b9b2656900041e069ddf72de81c17d874d0c32f6079f", + "sha256:c22591cff80188dd8543be0b559d0c807f7288bd353dc0bcfe539b4588b3a5cd", + "sha256:c5f83bb59d0ff60c6fdb1f8a7b0288fbc4640b1f0fd56f5ae2387749c35d34e3", + "sha256:c7e8221278e5f9e2b6d3893cfc3a3e46c017161a57bb0e6f244826e4cee97916", + "sha256:c8d6bf6fcd42cde2f02efb8126812a010c297eacefcd090a609639d2aeda6185", + "sha256:c8f7dd025cb0bf19e2f60a64dfc24b513c8330e0cfe4a34ccf941eafd6194d9e", + "sha256:c9d212e2af72d5c8d082775a43eb726520e95bf1c84826440f74225843975136", + "sha256:cebb3d8bcac4a6b48be65ebbc5c9881ed4a738e27bb96c86d9d7580a1fb09e05", + "sha256:d3082e5c4d7b388792124f5e805b469109e58f1ab1eb1fbd8b998e8ab766ffb7", + "sha256:d81047341ab56061aa4b6823c54d4632579c3b16e675089e8f520e9b918a133b", + "sha256:d81299f63dc33cc172c26faf59cc54dd795fc6dd5821a7676cca112a5ee8bbd6", + "sha256:dfa217bf8cf3ff6b30c8e6a89014e0c0e7b50941af787b970060ae5ba04a4ce5", + "sha256:dfec57f15f53d677b8e4535695ff3f37df7f8fe431f2efa8c3c8c4025b53d1eb", + "sha256:e099b79ccf7c40f18b149a64d3d10639980035f9ceb223169dd806ff1bb0d9cc", + "sha256:e1fc4d3985868860b6585376e511bb32403c5ffb58b0ed913496c27fd791deea", + "sha256:e2b4c95c47fb81b19ea77dc1c50d23af3eba87c9628fcc2e03d44124a3d336ea", + "sha256:e4e5d163e6644c2bc84dd9f67bfa89288c23af26983d08fefcc2cbc22f6e57e6", + "sha256:e66b3c9f8b89d4fd58a59c04fdbf10602a17c914fbaaa5e6ea593f1d54b06362", + "sha256:ed7d11330e443aeecab23866055e08a5a536c95d2c25333aeb441af2dbac38d2", + "sha256:f340a2a908644ea6cccd399be0fb308c66e05d2800107345f9f0f0d59e1731c4", + "sha256:f38b35ecd2628bf0267761ed659e48af7e620a7fcccfccf5774e7308fb18325c", + "sha256:f6d5443104f89a840250087863c91484a72f254574848e951d1bdd7d8b2ce7c9", + "sha256:fc2048d13ff427605fea328cbe5369dce549b8c7657b0e22051a5b8831170af6" ], "index": "pypi", - "version": "==3.12.1" + "version": "==3.12.3" }, "python-dateutil": { "hashes": [ @@ -524,19 +505,19 @@ }, "tinycss2": { "hashes": [ - "sha256:0353b5234bcaee7b1ac7ca3dea7e02cd338a9f8dcbb8f2dcd32a5795ec1e5f9a", - "sha256:fbdcac3044d60eb85fdb2aa840ece43cf7dbe798e373e6ee0be545d4d134e18a" + "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf", + "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8" ], "markers": "python_version >= '3.6'", - "version": "==1.1.0" + "version": "==1.1.1" }, "typing-extensions": { "hashes": [ - "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed", - "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9" + "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", + "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" ], "markers": "python_version >= '3.6'", - "version": "==4.0.0" + "version": "==4.1.1" }, "uvloop": { "hashes": [ @@ -664,11 +645,11 @@ }, "bandit": { "hashes": [ - "sha256:a81b00b5436e6880fa8ad6799bc830e02032047713cbb143a12939ac67eb756c", - "sha256:f5acd838e59c038a159b5c621cf0f8270b279e884eadd7b782d7491c02add0d4" + "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2", + "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a" ], "index": "pypi", - "version": "==1.7.1" + "version": "==1.7.4" }, "black": { "hashes": [ @@ -680,11 +661,11 @@ }, "click": { "hashes": [ - "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", - "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" + "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1", + "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb" ], "markers": "python_version >= '3.6'", - "version": "==8.0.3" + "version": "==8.0.4" }, "colorama": { "hashes": [ @@ -704,11 +685,11 @@ }, "gitpython": { "hashes": [ - "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647", - "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5" + "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704", + "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d" ], "markers": "python_version >= '3.7'", - "version": "==3.1.24" + "version": "==3.1.27" }, "isort": { "hashes": [ @@ -720,31 +701,46 @@ }, "lazy-object-proxy": { "hashes": [ - "sha256:17e0967ba374fc24141738c69736da90e94419338fd4c7c7bef01ee26b339653", - "sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61", - "sha256:22ddd618cefe54305df49e4c069fa65715be4ad0e78e8d252a33debf00f6ede2", - "sha256:24a5045889cc2729033b3e604d496c2b6f588c754f7a62027ad4437a7ecc4837", - "sha256:410283732af311b51b837894fa2f24f2c0039aa7f220135192b38fcc42bd43d3", - "sha256:4732c765372bd78a2d6b2150a6e99d00a78ec963375f236979c0626b97ed8e43", - "sha256:489000d368377571c6f982fba6497f2aa13c6d1facc40660963da62f5c379726", - "sha256:4f60460e9f1eb632584c9685bccea152f4ac2130e299784dbaf9fae9f49891b3", - "sha256:5743a5ab42ae40caa8421b320ebf3a998f89c85cdc8376d6b2e00bd12bd1b587", - "sha256:85fb7608121fd5621cc4377a8961d0b32ccf84a7285b4f1d21988b2eae2868e8", - "sha256:9698110e36e2df951c7c36b6729e96429c9c32b3331989ef19976592c5f3c77a", - "sha256:9d397bf41caad3f489e10774667310d73cb9c4258e9aed94b9ec734b34b495fd", - "sha256:b579f8acbf2bdd9ea200b1d5dea36abd93cabf56cf626ab9c744a432e15c815f", - "sha256:b865b01a2e7f96db0c5d12cfea590f98d8c5ba64ad222300d93ce6ff9138bcad", - "sha256:bf34e368e8dd976423396555078def5cfc3039ebc6fc06d1ae2c5a65eebbcde4", - "sha256:c6938967f8528b3668622a9ed3b31d145fab161a32f5891ea7b84f6b790be05b", - "sha256:d1c2676e3d840852a2de7c7d5d76407c772927addff8d742b9808fe0afccebdf", - "sha256:d7124f52f3bd259f510651450e18e0fd081ed82f3c08541dffc7b94b883aa981", - "sha256:d900d949b707778696fdf01036f58c9876a0d8bfe116e8d220cfd4b15f14e741", - "sha256:ebfd274dcd5133e0afae738e6d9da4323c3eb021b3e13052d8cbd0e457b1256e", - "sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93", - "sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.6.0" + "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7", + "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a", + "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c", + "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc", + "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f", + "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09", + "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442", + "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e", + "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029", + "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61", + "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb", + "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0", + "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35", + "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42", + "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1", + "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad", + "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443", + "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd", + "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9", + "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148", + "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38", + "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55", + "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36", + "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a", + "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b", + "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44", + "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6", + "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69", + "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4", + "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84", + "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de", + "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28", + "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c", + "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1", + "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8", + "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b", + "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb" + ], + "markers": "python_version >= '3.6'", + "version": "==1.7.1" }, "mccabe": { "hashes": [ @@ -769,11 +765,11 @@ }, "pbr": { "hashes": [ - "sha256:176e8560eaf61e127817ef93d8a844803abb27a4d4637f0ff3bb783129be2e0a", - "sha256:672d8ebee84921862110f23fcec2acea191ef58543d34dfe9ef3d9f13c31cddf" + "sha256:27108648368782d07bbf1cb468ad2e2eeef29086affd14087a6d04b7de8af4ec", + "sha256:66bc5a34912f408bb3925bf21231cb6f59206267b7f63f3503ef865c1a292e25" ], "markers": "python_version >= '2.6'", - "version": "==5.8.0" + "version": "==5.8.1" }, "pylint": { "hashes": [ @@ -824,57 +820,91 @@ }, "regex": { "hashes": [ - "sha256:05b7d6d7e64efe309972adab77fc2af8907bb93217ec60aa9fe12a0dad35874f", - "sha256:0617383e2fe465732af4509e61648b77cbe3aee68b6ac8c0b6fe934db90be5cc", - "sha256:07856afef5ffcc052e7eccf3213317fbb94e4a5cd8177a2caa69c980657b3cb4", - "sha256:162abfd74e88001d20cb73ceaffbfe601469923e875caf9118333b1a4aaafdc4", - "sha256:2207ae4f64ad3af399e2d30dde66f0b36ae5c3129b52885f1bffc2f05ec505c8", - "sha256:30ab804ea73972049b7a2a5c62d97687d69b5a60a67adca07eb73a0ddbc9e29f", - "sha256:3b5df18db1fccd66de15aa59c41e4f853b5df7550723d26aa6cb7f40e5d9da5a", - "sha256:3c5fb32cc6077abad3bbf0323067636d93307c9fa93e072771cf9a64d1c0f3ef", - "sha256:416c5f1a188c91e3eb41e9c8787288e707f7d2ebe66e0a6563af280d9b68478f", - "sha256:432bd15d40ed835a51617521d60d0125867f7b88acf653e4ed994a1f8e4995dc", - "sha256:4aaa4e0705ef2b73dd8e36eeb4c868f80f8393f5f4d855e94025ce7ad8525f50", - "sha256:537ca6a3586931b16a85ac38c08cc48f10fc870a5b25e51794c74df843e9966d", - "sha256:53db2c6be8a2710b359bfd3d3aa17ba38f8aa72a82309a12ae99d3c0c3dcd74d", - "sha256:5537f71b6d646f7f5f340562ec4c77b6e1c915f8baae822ea0b7e46c1f09b733", - "sha256:6650f16365f1924d6014d2ea770bde8555b4a39dc9576abb95e3cd1ff0263b36", - "sha256:666abff54e474d28ff42756d94544cdfd42e2ee97065857413b72e8a2d6a6345", - "sha256:68a067c11463de2a37157930d8b153005085e42bcb7ad9ca562d77ba7d1404e0", - "sha256:780b48456a0f0ba4d390e8b5f7c661fdd218934388cde1a974010a965e200e12", - "sha256:788aef3549f1924d5c38263104dae7395bf020a42776d5ec5ea2b0d3d85d6646", - "sha256:7ee1227cf08b6716c85504aebc49ac827eb88fcc6e51564f010f11a406c0a667", - "sha256:7f301b11b9d214f83ddaf689181051e7f48905568b0c7017c04c06dfd065e244", - "sha256:83ee89483672b11f8952b158640d0c0ff02dc43d9cb1b70c1564b49abe92ce29", - "sha256:85bfa6a5413be0ee6c5c4a663668a2cad2cbecdee367630d097d7823041bdeec", - "sha256:9345b6f7ee578bad8e475129ed40123d265464c4cfead6c261fd60fc9de00bcf", - "sha256:93a5051fcf5fad72de73b96f07d30bc29665697fb8ecdfbc474f3452c78adcf4", - "sha256:962b9a917dd7ceacbe5cd424556914cb0d636001e393b43dc886ba31d2a1e449", - "sha256:98ba568e8ae26beb726aeea2273053c717641933836568c2a0278a84987b2a1a", - "sha256:a3feefd5e95871872673b08636f96b61ebef62971eab044f5124fb4dea39919d", - "sha256:b43c2b8a330a490daaef5a47ab114935002b13b3f9dc5da56d5322ff218eeadb", - "sha256:b483c9d00a565633c87abd0aaf27eb5016de23fed952e054ecc19ce32f6a9e7e", - "sha256:ba05430e819e58544e840a68b03b28b6d328aff2e41579037e8bab7653b37d83", - "sha256:ca5f18a75e1256ce07494e245cdb146f5a9267d3c702ebf9b65c7f8bd843431e", - "sha256:d5ca078bb666c4a9d1287a379fe617a6dccd18c3e8a7e6c7e1eb8974330c626a", - "sha256:da1a90c1ddb7531b1d5ff1e171b4ee61f6345119be7351104b67ff413843fe94", - "sha256:dba70f30fd81f8ce6d32ddeef37d91c8948e5d5a4c63242d16a2b2df8143aafc", - "sha256:dd33eb9bdcfbabab3459c9ee651d94c842bc8a05fabc95edf4ee0c15a072495e", - "sha256:e0538c43565ee6e703d3a7c3bdfe4037a5209250e8502c98f20fea6f5fdf2965", - "sha256:e1f54b9b4b6c53369f40028d2dd07a8c374583417ee6ec0ea304e710a20f80a0", - "sha256:e32d2a2b02ccbef10145df9135751abea1f9f076e67a4e261b05f24b94219e36", - "sha256:e71255ba42567d34a13c03968736c5d39bb4a97ce98188fafb27ce981115beec", - "sha256:ed2e07c6a26ed4bea91b897ee2b0835c21716d9a469a96c3e878dc5f8c55bb23", - "sha256:eef2afb0fd1747f33f1ee3e209bce1ed582d1896b240ccc5e2697e3275f037c7", - "sha256:f23222527b307970e383433daec128d769ff778d9b29343fb3496472dc20dabe", - "sha256:f341ee2df0999bfdf7a95e448075effe0db212a59387de1a70690e4acb03d4c6", - "sha256:f7f325be2804246a75a4f45c72d4ce80d2443ab815063cdf70ee8fb2ca59ee1b", - "sha256:f8af619e3be812a2059b212064ea7a640aff0568d972cd1b9e920837469eb3cb", - "sha256:fa8c626d6441e2d04b6ee703ef2d1e17608ad44c7cb75258c09dd42bacdfc64b", - "sha256:fbb9dc00e39f3e6c0ef48edee202f9520dafb233e8b51b06b8428cfcb92abd30", - "sha256:fff55f3ce50a3ff63ec8e2a8d3dd924f1941b250b0aac3d3d42b687eeff07a8e" - ], - "version": "==2021.11.10" + "sha256:0066a6631c92774391f2ea0f90268f0d82fffe39cb946f0f9c6b382a1c61a5e5", + "sha256:0100f0ded953b6b17f18207907159ba9be3159649ad2d9b15535a74de70359d3", + "sha256:01c913cf573d1da0b34c9001a94977273b5ee2fe4cb222a5d5b320f3a9d1a835", + "sha256:0214ff6dff1b5a4b4740cfe6e47f2c4c92ba2938fca7abbea1359036305c132f", + "sha256:029e9e7e0d4d7c3446aa92474cbb07dafb0b2ef1d5ca8365f059998c010600e6", + "sha256:0317eb6331146c524751354ebef76a7a531853d7207a4d760dfb5f553137a2a4", + "sha256:04b5ee2b6d29b4a99d38a6469aa1db65bb79d283186e8460542c517da195a8f6", + "sha256:04c09b9651fa814eeeb38e029dc1ae83149203e4eeb94e52bb868fadf64852bc", + "sha256:058054c7a54428d5c3e3739ac1e363dc9347d15e64833817797dc4f01fb94bb8", + "sha256:060f9066d2177905203516c62c8ea0066c16c7342971d54204d4e51b13dfbe2e", + "sha256:0a7b75cc7bb4cc0334380053e4671c560e31272c9d2d5a6c4b8e9ae2c9bd0f82", + "sha256:0e2630ae470d6a9f8e4967388c1eda4762706f5750ecf387785e0df63a4cc5af", + "sha256:174d964bc683b1e8b0970e1325f75e6242786a92a22cedb2a6ec3e4ae25358bd", + "sha256:25ecb1dffc5e409ca42f01a2b2437f93024ff1612c1e7983bad9ee191a5e8828", + "sha256:286908cbe86b1a0240a867aecfe26a439b16a1f585d2de133540549831f8e774", + "sha256:303b15a3d32bf5fe5a73288c316bac5807587f193ceee4eb6d96ee38663789fa", + "sha256:34bb30c095342797608727baf5c8aa122406aa5edfa12107b8e08eb432d4c5d7", + "sha256:3e265b388cc80c7c9c01bb4f26c9e536c40b2c05b7231fbb347381a2e1c8bf43", + "sha256:3e4d710ff6539026e49f15a3797c6b1053573c2b65210373ef0eec24480b900b", + "sha256:42eb13b93765c6698a5ab3bcd318d8c39bb42e5fa8a7fcf7d8d98923f3babdb1", + "sha256:48081b6bff550fe10bcc20c01cf6c83dbca2ccf74eeacbfac240264775fd7ecf", + "sha256:491fc754428514750ab21c2d294486223ce7385446f2c2f5df87ddbed32979ae", + "sha256:4d1445824944e642ffa54c4f512da17a953699c563a356d8b8cbdad26d3b7598", + "sha256:530a3a16e57bd3ea0dff5ec2695c09632c9d6c549f5869d6cf639f5f7153fb9c", + "sha256:591d4fba554f24bfa0421ba040cd199210a24301f923ed4b628e1e15a1001ff4", + "sha256:5a86cac984da35377ca9ac5e2e0589bd11b3aebb61801204bd99c41fac516f0d", + "sha256:5b1ceede92400b3acfebc1425937454aaf2c62cd5261a3fabd560c61e74f6da3", + "sha256:5b2e24f3ae03af3d8e8e6d824c891fea0ca9035c5d06ac194a2700373861a15c", + "sha256:6504c22c173bb74075d7479852356bb7ca80e28c8e548d4d630a104f231e04fb", + "sha256:673f5a393d603c34477dbad70db30025ccd23996a2d0916e942aac91cc42b31a", + "sha256:6ca6dcd17f537e9f3793cdde20ac6076af51b2bd8ad5fe69fa54373b17b48d3c", + "sha256:6e1d8ed9e61f37881c8db383a124829a6e8114a69bd3377a25aecaeb9b3538f8", + "sha256:75a5e6ce18982f0713c4bac0704bf3f65eed9b277edd3fb9d2b0ff1815943327", + "sha256:76435a92e444e5b8f346aed76801db1c1e5176c4c7e17daba074fbb46cb8d783", + "sha256:764e66a0e382829f6ad3bbce0987153080a511c19eb3d2f8ead3f766d14433ac", + "sha256:78ce90c50d0ec970bd0002462430e00d1ecfd1255218d52d08b3a143fe4bde18", + "sha256:794a6bc66c43db8ed06698fc32aaeaac5c4812d9f825e9589e56f311da7becd9", + "sha256:797437e6024dc1589163675ae82f303103063a0a580c6fd8d0b9a0a6708da29e", + "sha256:7b7494df3fdcc95a1f76cf134d00b54962dd83189520fd35b8fcd474c0aa616d", + "sha256:7d1a6e403ac8f1d91d8f51c441c3f99367488ed822bda2b40836690d5d0059f5", + "sha256:7f63877c87552992894ea1444378b9c3a1d80819880ae226bb30b04789c0828c", + "sha256:8923e1c5231549fee78ff9b2914fad25f2e3517572bb34bfaa3aea682a758683", + "sha256:8afcd1c2297bc989dceaa0379ba15a6df16da69493635e53431d2d0c30356086", + "sha256:8b1cc70e31aacc152a12b39245974c8fccf313187eead559ee5966d50e1b5817", + "sha256:8d1f3ea0d1924feb4cf6afb2699259f658a08ac6f8f3a4a806661c2dfcd66db1", + "sha256:940570c1a305bac10e8b2bc934b85a7709c649317dd16520471e85660275083a", + "sha256:947a8525c0a95ba8dc873191f9017d1b1e3024d4dc757f694e0af3026e34044a", + "sha256:9beb03ff6fe509d6455971c2489dceb31687b38781206bcec8e68bdfcf5f1db2", + "sha256:9c144405220c5ad3f5deab4c77f3e80d52e83804a6b48b6bed3d81a9a0238e4c", + "sha256:a98ae493e4e80b3ded6503ff087a8492db058e9c68de371ac3df78e88360b374", + "sha256:aa2ce79f3889720b46e0aaba338148a1069aea55fda2c29e0626b4db20d9fcb7", + "sha256:aa5eedfc2461c16a092a2fabc5895f159915f25731740c9152a1b00f4bcf629a", + "sha256:ab5d89cfaf71807da93c131bb7a19c3e19eaefd613d14f3bce4e97de830b15df", + "sha256:b4829db3737480a9d5bfb1c0320c4ee13736f555f53a056aacc874f140e98f64", + "sha256:b52771f05cff7517f7067fef19ffe545b1f05959e440d42247a17cd9bddae11b", + "sha256:b8248f19a878c72d8c0a785a2cd45d69432e443c9f10ab924c29adda77b324ae", + "sha256:b9809404528a999cf02a400ee5677c81959bc5cb938fdc696b62eb40214e3632", + "sha256:c155a1a80c5e7a8fa1d9bb1bf3c8a953532b53ab1196092749bafb9d3a7cbb60", + "sha256:c33ce0c665dd325200209340a88438ba7a470bd5f09f7424e520e1a3ff835b52", + "sha256:c5adc854764732dbd95a713f2e6c3e914e17f2ccdc331b9ecb777484c31f73b6", + "sha256:cb374a2a4dba7c4be0b19dc7b1adc50e6c2c26c3369ac629f50f3c198f3743a4", + "sha256:cd00859291658fe1fda48a99559fb34da891c50385b0bfb35b808f98956ef1e7", + "sha256:ce3057777a14a9a1399b81eca6a6bfc9612047811234398b84c54aeff6d536ea", + "sha256:d0a5a1fdc9f148a8827d55b05425801acebeeefc9e86065c7ac8b8cc740a91ff", + "sha256:dad3991f0678facca1a0831ec1ddece2eb4d1dd0f5150acb9440f73a3b863907", + "sha256:dc7b7c16a519d924c50876fb152af661a20749dcbf653c8759e715c1a7a95b18", + "sha256:dcbb7665a9db9f8d7642171152c45da60e16c4f706191d66a1dc47ec9f820aed", + "sha256:df037c01d68d1958dad3463e2881d3638a0d6693483f58ad41001aa53a83fcea", + "sha256:f08a7e4d62ea2a45557f561eea87c907222575ca2134180b6974f8ac81e24f06", + "sha256:f16cf7e4e1bf88fecf7f41da4061f181a6170e179d956420f84e700fb8a3fd6b", + "sha256:f2c53f3af011393ab5ed9ab640fa0876757498aac188f782a0c620e33faa2a3d", + "sha256:f320c070dea3f20c11213e56dbbd7294c05743417cde01392148964b7bc2d31a", + "sha256:f553a1190ae6cd26e553a79f6b6cfba7b8f304da2071052fa33469da075ea625", + "sha256:fc8c7958d14e8270171b3d72792b609c057ec0fa17d507729835b5cff6b7f69a" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.3.15" + }, + "setuptools": { + "hashes": [ + "sha256:6599055eeb23bfef457d5605d33a4d68804266e6cb430b0fb12417c5efeae36c", + "sha256:782ef48d58982ddb49920c11a0c5c9c0b02e7d7d1c2ad0aa44e1a1e133051c96" + ], + "markers": "python_version >= '3.7'", + "version": "==60.10.0" }, "smmap": { "hashes": [ @@ -900,14 +930,6 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, - "typing-extensions": { - "hashes": [ - "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed", - "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9" - ], - "markers": "python_version >= '3.6'", - "version": "==4.0.0" - }, "wrapt": { "hashes": [ "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" diff --git a/bot.py b/bot.py index 3e3a6ec5cf..c691cea068 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev6" +__version__ = "4.0.0-dev7" import asyncio @@ -67,7 +67,7 @@ class ModmailBot(commands.Bot): def __init__(self): intents = discord.Intents.all() super().__init__(command_prefix=None, intents=intents) # implemented in `get_prefix` - self._session = None + self.session = None self._api = None self.formatter = SafeFormatter() self.loaded_cogs = ["cogs.modmail", "cogs.plugins", "cogs.utility"] @@ -131,10 +131,11 @@ def startup(self): logger.info("discord.py: v%s", discord.__version__) logger.line() + async def load_extensions(self): for cog in self.loaded_cogs: logger.debug("Loading %s.", cog) try: - self.load_extension(cog) + await self.load_extension(cog) logger.debug("Successfully loaded %s.", cog) except Exception: logger.exception("Failed to load %s.", cog) @@ -167,12 +168,6 @@ def _configure_logging(self): def version(self): return parse_version(__version__) - @property - def session(self) -> ClientSession: - if self._session is None: - self._session = ClientSession(loop=self.loop) - return self._session - @property def api(self) -> ApiClient: if self._api is None: @@ -192,102 +187,85 @@ async def get_prefix(self, message=None): return [self.prefix, f"<@{self.user.id}> ", f"<@!{self.user.id}> "] def run(self): - loop = self.loop - - try: - loop.add_signal_handler(signal.SIGINT, lambda: loop.stop()) - loop.add_signal_handler(signal.SIGTERM, lambda: loop.stop()) - except NotImplementedError: - pass - async def runner(): - try: - retry_intents = False + async with self: try: - await self.start(self.token) + retry_intents = False + try: + await self.start(self.token) + except discord.PrivilegedIntentsRequired: + retry_intents = True + if retry_intents: + await self.http.close() + if self.ws is not None and self.ws.open: + await self.ws.close(code=1000) + self._ready.clear() + + intents = discord.Intents.default() + intents.members = True + intents.message_content = True + # Try again with members intent + self._connection._intents = intents + logger.warning( + "Attempting to login with only the server members and message content privileged intent. Some plugins might not work correctly." + ) + await self.start(self.token) except discord.PrivilegedIntentsRequired: - retry_intents = True - if retry_intents: - await self.http.close() - if self.ws is not None and self.ws.open: - await self.ws.close(code=1000) - self._ready.clear() - intents = discord.Intents.default() - intents.members = True - # Try again with members intent - self._connection._intents = intents - logger.warning( - "Attempting to login with only the server members privileged intent. Some plugins might not work correctly." + logger.critical( + "Privileged intents are not explicitly granted in the discord developers dashboard." ) - await self.start(self.token) - except discord.PrivilegedIntentsRequired: - logger.critical( - "Privileged intents are not explicitly granted in the discord developers dashboard." - ) - except discord.LoginFailure: - logger.critical("Invalid token") - except Exception: - logger.critical("Fatal exception", exc_info=True) - finally: - if not self.is_closed(): - await self.close() - if self._session: - await self._session.close() - - # noinspection PyUnusedLocal - def stop_loop_on_completion(f): - loop.stop() - - def _cancel_tasks(): - task_retriever = asyncio.all_tasks - tasks = {t for t in task_retriever(loop=loop) if not t.done()} - - if not tasks: - return + except discord.LoginFailure: + logger.critical("Invalid token") + except Exception: + logger.critical("Fatal exception", exc_info=True) + finally: + if not self.is_closed(): + await self.close() + if self.session: + await self.session.close() + + async def _cancel_tasks(): + async with self: + task_retriever = asyncio.all_tasks + loop = self.loop + tasks = {t for t in task_retriever() if not t.done() and t.get_coro() != cancel_tasks_coro} + + if not tasks: + return - logger.info("Cleaning up after %d tasks.", len(tasks)) - for task in tasks: - task.cancel() - - loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True)) - logger.info("All tasks finished cancelling.") - - for task in tasks: - if task.cancelled(): - continue - if task.exception() is not None: - loop.call_exception_handler( - { - "message": "Unhandled exception during Client.run shutdown.", - "exception": task.exception(), - "task": task, - } - ) + logger.info("Cleaning up after %d tasks.", len(tasks)) + for task in tasks: + task.cancel() + + await asyncio.gather(*tasks, return_exceptions=True) + logger.info("All tasks finished cancelling.") + + for task in tasks: + try: + if task.exception() is not None: + loop.call_exception_handler( + { + "message": "Unhandled exception during Client.run shutdown.", + "exception": task.exception(), + "task": task, + } + ) + except (asyncio.InvalidStateError, asyncio.CancelledError): + pass - future = asyncio.ensure_future(runner(), loop=loop) - future.add_done_callback(stop_loop_on_completion) try: - loop.run_forever() - except KeyboardInterrupt: + asyncio.run(runner()) + except (KeyboardInterrupt, SystemExit): logger.info("Received signal to terminate bot and event loop.") finally: - future.remove_done_callback(stop_loop_on_completion) logger.info("Cleaning up tasks.") try: - _cancel_tasks() - if sys.version_info >= (3, 6): - loop.run_until_complete(loop.shutdown_asyncgens()) + cancel_tasks_coro = _cancel_tasks() + asyncio.run(cancel_tasks_coro) finally: logger.info("Closing the event loop.") - if not future.cancelled(): - try: - return future.result() - except KeyboardInterrupt: - # I am unsure why this gets raised here but suppress it anyway - return None - @property def bot_owner_ids(self): owner_ids = self.config["owners"] @@ -517,6 +495,8 @@ async def on_connect(self): logger.debug("Connected to gateway.") await self.config.refresh() await self.api.setup_indexes() + await self.load_extensions() + self.session = ClientSession(loop=self.loop) self._connected.set() async def on_ready(self): @@ -1421,7 +1401,7 @@ async def on_message_delete(self, message): if embed.footer.icon: icon_url = embed.footer.icon.url else: - icon_url = discord.Embed.Empty + icon_url = None embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=icon_url) await message.edit(embed=embed) diff --git a/cogs/modmail.py b/cogs/modmail.py index 7900f0eeef..8ef853963c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -2091,5 +2091,5 @@ async def isenable(self, ctx): return await ctx.send(embed=embed) -def setup(bot): - bot.add_cog(Modmail(bot)) +async def setup(bot): + await bot.add_cog(Modmail(bot)) diff --git a/cogs/plugins.py b/cogs/plugins.py index e9adf2a240..37e71a872b 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -123,10 +123,10 @@ def __init__(self, bot): self.loaded_plugins = set() self._ready_event = asyncio.Event() - self.bot.loop.create_task(self.populate_registry()) - + async def async_init(self): + await self.populate_registry() if self.bot.config.get("enable_plugins"): - self.bot.loop.create_task(self.initial_load_plugins()) + await self.initial_load_plugins() else: logger.info("Plugins not loaded since ENABLE_PLUGINS=false.") @@ -258,7 +258,7 @@ async def load_plugin(self, plugin): sys.path.insert(0, USER_SITE) try: - self.bot.load_extension(plugin.ext_string) + await self.bot.load_extension(plugin.ext_string) logger.info("Loaded plugin: %s", plugin.ext_string.split(".")[-1]) self.loaded_plugins.add(plugin) @@ -432,7 +432,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): if self.bot.config.get("enable_plugins"): try: - self.bot.unload_extension(plugin.ext_string) + await self.bot.unload_extension(plugin.ext_string) self.loaded_plugins.remove(plugin) except (commands.ExtensionNotLoaded, KeyError): logger.warning("Plugin was never loaded.") @@ -474,7 +474,7 @@ async def update_plugin(self, ctx, plugin_name): await self.download_plugin(plugin, force=True) if self.bot.config.get("enable_plugins"): try: - self.bot.unload_extension(plugin.ext_string) + await self.bot.unload_extension(plugin.ext_string) except commands.ExtensionError: logger.warning("Plugin unload fail.", exc_info=True) try: @@ -525,7 +525,7 @@ async def plugins_reset(self, ctx): continue try: logger.error("Unloading plugin: %s.", ext) - self.bot.unload_extension(ext) + await self.bot.unload_extension(ext) except Exception: logger.error("Failed to unload plugin: %s.", ext) else: @@ -737,5 +737,5 @@ async def plugins_registry_compact(self, ctx): await paginator.run() -def setup(bot): - bot.add_cog(Plugins(bot)) +async def setup(bot): + await bot.add_cog(Plugins(bot)) diff --git a/cogs/utility.py b/cogs/utility.py index 7278c350fc..aa8adaaf2d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -256,11 +256,13 @@ def __init__(self, bot): }, ) self.bot.help_command.cog = self - self.loop_presence.start() # pylint: disable=no-member if not self.bot.config.get("enable_eval"): self.eval_.enabled = False logger.info("Eval disabled. enable_eval=False") + async def async_init(self): + self.loop_presence.start() # pylint: disable=no-member + def cog_unload(self): self.bot.help_command = self._original_help_command @@ -2099,5 +2101,5 @@ def paginate(text: str): await self.bot.add_reaction(ctx.message, "\u2705") -def setup(bot): - bot.add_cog(Utility(bot)) +async def setup(bot): + await bot.add_cog(Utility(bot)) diff --git a/core/paginator.py b/core/paginator.py index b9cd29a26b..39782817b5 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -308,7 +308,7 @@ def __init__(self, ctx: commands.Context, *embeds, **options): if embed.footer.icon: icon_url = embed.footer.icon.url else: - icon_url = Embed.Empty + icon_url = None embed.set_footer(text=footer_text, icon_url=icon_url) # select menu @@ -369,7 +369,7 @@ def _set_footer(self): if self.embed.footer.icon: icon_url = self.embed.footer.icon.url else: - icon_url = Embed.Empty + icon_url = None self.embed.set_footer(text=footer_text, icon_url=icon_url) diff --git a/core/thread.py b/core/thread.py index 87ffc45ee3..7edfbc1d39 100644 --- a/core/thread.py +++ b/core/thread.py @@ -75,7 +75,7 @@ def __eq__(self, other): async def wait_until_ready(self) -> None: """Blocks execution until the thread is fully set up.""" # timeout after 30 seconds - task = asyncio.create_task(asyncio.wait_for(self._ready_event.wait(), timeout=25)) + task = self.bot.loop.create_task(asyncio.wait_for(self._ready_event.wait(), timeout=25)) self.wait_tasks.append(task) try: await task @@ -367,7 +367,8 @@ def _format_info_embed(self, user, log_url, log_count, color): return embed - def _close_after(self, closer, silent, delete_channel, message): + async def _close_after(self, after, closer, silent, delete_channel, message): + await asyncio.sleep(after) return self.bot.loop.create_task(self._close(closer, silent, delete_channel, message, True)) async def close( @@ -401,7 +402,7 @@ async def close( self.bot.config["closures"][str(self.id)] = items await self.bot.config.update() - task = self.bot.loop.call_later(after, self._close_after, closer, silent, delete_channel, message) + task = asyncio.create_task(self._close_after(after, closer, silent, delete_channel, message)) if auto_close: self.auto_close_task = task @@ -1139,7 +1140,7 @@ def lottie_to_png(data): raise if not from_mod and not note: - mentions = self.get_notifications() + mentions = await self.get_notifications() else: mentions = None @@ -1176,7 +1177,7 @@ def lottie_to_png(data): return msg - def get_notifications(self) -> str: + async def get_notifications(self) -> str: key = str(self.id) mentions = [] diff --git a/pyproject.toml b/pyproject.toml index 031fc5073f..d552a33dee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev6' +version = '4.0.0-dev7' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From d6a3982b823a6cd9cbcb979db5d8503d3edaad46 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Mon, 28 Mar 2022 13:46:32 -0700 Subject: [PATCH 511/705] Update SPONSORS.json --- SPONSORS.json | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/SPONSORS.json b/SPONSORS.json index a1ec35d6dd..2cd08053ec 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -105,5 +105,27 @@ }, "image": "https://cdn.discordapp.com/attachments/472811257913933834/907068966311166043/unknown_2.png" } + }, + { + "embed": { + "footer": { + "text": "Join noch heute!" + }, + "thumbnail": { + "url": "https://i.imgur.com/bp0xfyK.png" + }, + "fields": [ + { + "inline": false, + "name": "Viele Verschiedene Talks", + "value": "Gro\u00dfe Community\nGewinnspiele" + } + ], + "color": 61532, + "type": "rich", + "description": "Die etwas andere Community", + "url": "https://discord.gg/uncommon", + "title": "uncommon community" + } } ] From e0032fd9b9806db75f21167e2c50f36258fbbc99 Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Mon, 28 Mar 2022 13:47:43 -0700 Subject: [PATCH 512/705] Update SPONSORS.json --- SPONSORS.json | 1 - 1 file changed, 1 deletion(-) diff --git a/SPONSORS.json b/SPONSORS.json index 2cd08053ec..1177699d10 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -122,7 +122,6 @@ } ], "color": 61532, - "type": "rich", "description": "Die etwas andere Community", "url": "https://discord.gg/uncommon", "title": "uncommon community" From 57349c6eafa8c8af0f285bd907968669ac60439b Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Fri, 15 Apr 2022 17:45:28 -0700 Subject: [PATCH 513/705] Update sponsors list --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 465b13f1ab..b95dc335a4 100644 --- a/README.md +++ b/README.md @@ -162,13 +162,6 @@ $ docker run --env-file .env kyb3rr/modmail Special thanks to our sponsors for supporting the project. -Kingdom Gaming Discord: -<br> -<a href='https://discord.gg/kingdomgaming'> - <img height=100 src='https://i.imgur.com/GLXfl4E.png' style='margin:5px'> -</a> -<br> -<br> SirReddit: <br> <a href='https://www.youtube.com/channel/UCgSmBJD9imASmJRleycTCwQ/featured'> From be14cca89742cd691f6b91f0d0931a074ad81e3b Mon Sep 17 00:00:00 2001 From: Taku 3 Animals <45324516+Taaku18@users.noreply.github.com> Date: Fri, 15 Apr 2022 17:50:10 -0700 Subject: [PATCH 514/705] Update sponsors syntax issue --- SPONSORS.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SPONSORS.json b/SPONSORS.json index 1177699d10..ce34dc3f9d 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -103,7 +103,9 @@ "footer": { "text": "Grow Your Discord Server" }, - "image": "https://cdn.discordapp.com/attachments/472811257913933834/907068966311166043/unknown_2.png" + "image": { + "url": "https://cdn.discordapp.com/attachments/472811257913933834/907068966311166043/unknown_2.png" + } } }, { From d9c884e55c8d65175ebfe604e25098add7bdaf55 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 19 Apr 2022 23:30:31 +0800 Subject: [PATCH 515/705] dpy-ecb2cf & Fix plugins not loading, resolve #3141 --- Pipfile | 2 +- bot.py | 4 ++-- cogs/plugins.py | 4 +--- cogs/utility.py | 2 +- pyproject.toml | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Pipfile b/Pipfile index 04d998cbc8..1241feeb40 100644 --- a/Pipfile +++ b/Pipfile @@ -11,7 +11,7 @@ pylint = "~=2.9.3" [packages] aiohttp = "==3.7.4.post0" colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 -"discord.py" = {ref = "97fe07edb2f3d0f5a980917fb6ee479bf396fd94", git = "https://github.com/Rapptz/discord.py.git"} +"discord.py" = {ref = "987235d5649e7c2b1a927637bab6547244ecb2cf", git = "https://github.com/Rapptz/discord.py.git"} emoji = "~=1.2.0" isodate = "~=0.6.0" motor = "~=2.4.0" diff --git a/bot.py b/bot.py index c691cea068..6c0719243b 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev7" +__version__ = "4.0.0-dev8" import asyncio @@ -189,6 +189,7 @@ async def get_prefix(self, message=None): def run(self): async def runner(): async with self: + self.session = ClientSession(loop=self.loop) try: retry_intents = False try: @@ -496,7 +497,6 @@ async def on_connect(self): await self.config.refresh() await self.api.setup_indexes() await self.load_extensions() - self.session = ClientSession(loop=self.loop) self._connected.set() async def on_ready(self): diff --git a/cogs/plugins.py b/cogs/plugins.py index 37e71a872b..2bfac509af 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -123,7 +123,7 @@ def __init__(self, bot): self.loaded_plugins = set() self._ready_event = asyncio.Event() - async def async_init(self): + async def cog_load(self): await self.populate_registry() if self.bot.config.get("enable_plugins"): await self.initial_load_plugins() @@ -136,8 +136,6 @@ async def populate_registry(self): self.registry = json.loads(await resp.text()) async def initial_load_plugins(self): - await self.bot.wait_for_connected() - for plugin_name in list(self.bot.config["plugins"]): try: plugin = Plugin.from_string(plugin_name, strict=True) diff --git a/cogs/utility.py b/cogs/utility.py index aa8adaaf2d..6d1ddd0f00 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -260,7 +260,7 @@ def __init__(self, bot): self.eval_.enabled = False logger.info("Eval disabled. enable_eval=False") - async def async_init(self): + async def cog_load(self): self.loop_presence.start() # pylint: disable=no-member def cog_unload(self): diff --git a/pyproject.toml b/pyproject.toml index d552a33dee..ad792dc399 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev7' +version = '4.0.0-dev8' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From f03e20318f52f3682c9173c0cade49ded9a44c88 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 19 Apr 2022 23:43:45 +0800 Subject: [PATCH 516/705] fix blocked, resolve #3131 --- CHANGELOG.md | 1 + bot.py | 1 - cogs/modmail.py | 4 +++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 209bbcfcea..fb025baca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Editing notes now work. ([GH #3094](https://github.com/kyb3r/modmail/issues/3094)) - Commands now work in threads. - Audit log searching now properly works. +- Old data causing `?blocked` to fail. ([GH #3131](https://github.com/kyb3r/modmail/issues/3131)) ### Internal diff --git a/bot.py b/bot.py index 6c0719243b..da1e7117a3 100644 --- a/bot.py +++ b/bot.py @@ -6,7 +6,6 @@ import logging import os import re -import signal import string import struct import sys diff --git a/cogs/modmail.py b/cogs/modmail.py index 8ef853963c..63997b2824 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1565,7 +1565,9 @@ async def blocked(self, ctx): ) if end_time is not None: - after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() + after = ( + datetime.fromisoformat(end_time.group(1)).replace(tzinfo=timezone.utc) - now + ).total_seconds() if after <= 0: # No longer blocked self.bot.blocked_users.pop(str(id_)) From 71daedc219d07c797133adf77eff1f4918faf4b0 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 20 Apr 2022 21:02:32 +0800 Subject: [PATCH 517/705] update reqs.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fb43d23e2b..f0e1933ce0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2 colorama==0.4.4 dnspython==2.1.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.2.0 -git+https://github.com/Rapptz/discord.py.git@45d498c1b76deaf3b394d17ccf56112fa691d160#egg=discord-py +git+https://github.com/Rapptz/discord.py.git@987235d5649e7c2b1a927637bab6547244ecb2cf#egg=discord-py idna==3.3; python_version >= '3.5' isodate==0.6.0 motor==2.4.0 From 0e05f440526c87f486c9ce53f41876dcfd6017f3 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 20 Apr 2022 22:29:13 +0800 Subject: [PATCH 518/705] Fix stop button in paginator --- core/paginator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/paginator.py b/core/paginator.py index 39782817b5..39d0c434a3 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -216,7 +216,7 @@ def __init__(self, handler: PaginatorSession, *args, **kwargs): self.fill_items() @discord.ui.button(label="Stop", style=ButtonStyle.danger) - async def stop_button(self, button: Button, interaction: Interaction): + async def stop_button(self, interaction: Interaction, button: Button): await self.handler.close(interaction=interaction) def fill_items(self): From c57e3421acc8c0aa0aa7120412e00c3f7b15c406 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 20 Apr 2022 22:49:33 +0800 Subject: [PATCH 519/705] Fix one-page paginator --- bot.py | 2 +- core/paginator.py | 34 +++++++++++++++++++++------------- pyproject.toml | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/bot.py b/bot.py index da1e7117a3..592dbcb3b9 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev8" +__version__ = "4.0.0-dev9" import asyncio diff --git a/core/paginator.py b/core/paginator.py index 39d0c434a3..5a6844f382 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -87,27 +87,31 @@ async def show_page(self, index: int) -> typing.Optional[typing.Dict]: def update_disabled_status(self): if self.current == self.first_page(): # disable << button - if self._buttons_map["<<"]: + if self._buttons_map["<<"] is not None: self._buttons_map["<<"].disabled = True - self._buttons_map["<"].disabled = True + if self._buttons_map["<"] is not None: + self._buttons_map["<"].disabled = True else: - if self._buttons_map["<<"]: + if self._buttons_map["<<"] is not None: self._buttons_map["<<"].disabled = False - self._buttons_map["<"].disabled = False + if self._buttons_map["<"] is not None: + self._buttons_map["<"].disabled = False if self.current == self.last_page(): # disable >> button if self._buttons_map[">>"] is not None: self._buttons_map[">>"].disabled = True - self._buttons_map[">"].disabled = True + if self._buttons_map[">"] is not None: + self._buttons_map[">"].disabled = True else: if self._buttons_map[">>"] is not None: self._buttons_map[">>"].disabled = False - self._buttons_map[">"].disabled = False + if self._buttons_map[">"] is not None: + self._buttons_map[">"].disabled = False async def create_base(self, item) -> None: """ @@ -151,7 +155,10 @@ async def run(self) -> typing.Optional[Message]: """ if not self.running: await self.show_page(self.current) - await self.view.wait() + + if self.view is not None: + await self.view.wait() + await self.close(delete=False) async def close( @@ -182,12 +189,13 @@ async def close( self.running = False - self.view.stop() - if delete: - await message.delete() - else: - self.view.clear_items() - await message.edit(view=self.view) + if self.view is not None: + self.view.stop() + if delete: + await message.delete() + else: + self.view.clear_items() + await message.edit(view=self.view) class PaginatorView(View): diff --git a/pyproject.toml b/pyproject.toml index ad792dc399..3b821dd6f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev8' +version = '4.0.0-dev9' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From d54b687bc69933f05f6056d1600331a051bfb65a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 21:40:55 +0800 Subject: [PATCH 520/705] fix gh cmd, resolve #3149 --- core/clients.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/clients.py b/core/clients.py index 5caf58f4d2..a9722776f2 100644 --- a/core/clients.py +++ b/core/clients.py @@ -680,7 +680,7 @@ async def get_user_info(self) -> Optional[dict]: return { "user": { "username": user.username, - "avatar_url": user.display_avatar.url, + "avatar_url": user.avatar_url, "url": user.url, } } From 46f711af61962551cf8c8d03850528efa8b2bdb5 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 21:43:47 +0800 Subject: [PATCH 521/705] add title to ?logs, resolve #3142 --- cogs/modmail.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cogs/modmail.py b/cogs/modmail.py index 63997b2824..ea36bef7b9 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -656,6 +656,9 @@ def format_log_embeds(self, logs, avatar_url): if entry["recipient"]["id"] != entry["creator"]["id"]: embed.add_field(name="Created by", value=f"<@{entry['creator']['id']}>") + if entry["title"]: + embed.add_field(name="Title", value=entry["title"], inline=False) + embed.add_field(name="Preview", value=format_preview(entry["messages"]), inline=False) if closer is not None: From a11c0ed9525dee63522a393b49d30833b559e95a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 21:47:56 +0800 Subject: [PATCH 522/705] fix delete channel autoclose functionality --- CHANGELOG.md | 2 ++ bot.py | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb025baca2..4b75c286aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/kyb3r/modmail/issues/3112)) - `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/kyb3r/modmail/issues/3122)) - Select menus for certain paginators. +- `Title` field in `?logs`. ([GH #3142](https://github.com/kyb3r/modmail/issues/3142)) ### Improved @@ -45,6 +46,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Commands now work in threads. - Audit log searching now properly works. - Old data causing `?blocked` to fail. ([GH #3131](https://github.com/kyb3r/modmail/issues/3131)) +- Delete channel auto close functionality now works. ### Internal diff --git a/bot.py b/bot.py index 592dbcb3b9..4ff3e69091 100644 --- a/bot.py +++ b/bot.py @@ -1336,9 +1336,13 @@ async def on_guild_channel_delete(self, channel): return audit_logs = self.modmail_guild.audit_logs(limit=10, action=discord.AuditLogAction.channel_delete) - entry = await audit_logs.find(lambda a: int(a.target.id) == channel.id) + found_entry = False + async for entry in audit_logs: + if int(entry.target.id) == channel.id: + found_entry = True + break - if entry is None: + if not found_entry: logger.debug("Cannot find the audit log entry for channel delete of %d.", channel.id) return From 4aed3b42d3d94161073d840941419444aac5eb5e Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 21:57:55 +0800 Subject: [PATCH 523/705] Update dpy@a14b43f2fda863ed6555374eb872bf014bdd1adf --- Pipfile | 2 +- Pipfile.lock | 260 ++++++++++++++++++++++++----------------------- bot.py | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- 5 files changed, 135 insertions(+), 133 deletions(-) diff --git a/Pipfile b/Pipfile index 1241feeb40..c74f6cb1a7 100644 --- a/Pipfile +++ b/Pipfile @@ -11,7 +11,7 @@ pylint = "~=2.9.3" [packages] aiohttp = "==3.7.4.post0" colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 -"discord.py" = {ref = "987235d5649e7c2b1a927637bab6547244ecb2cf", git = "https://github.com/Rapptz/discord.py.git"} +"discord.py" = {git = "https://github.com/Rapptz/discord.py.git"} emoji = "~=1.2.0" isodate = "~=0.6.0" motor = "~=2.4.0" diff --git a/Pipfile.lock b/Pipfile.lock index 5cd3d63616..d163dd5ae1 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "5f3ca86a89bbc9bcda36bdb3503c91f81ff9c5e12409c3ad056524aa920f4fad" + "sha256": "c0006885019e90564b0907b571e5a7bcd5f8b47d1dc3c535959f2600d4d15ba6" }, "pipfile-spec": 6, "requires": { @@ -163,11 +163,11 @@ }, "cssselect2": { "hashes": [ - "sha256:8d4690bce5f25013262997e64cef3e7bade877d3ef126f9cc624e5b1f294d934", - "sha256:d98a7bbdd8ebc46093279195d669a3359bd5a23f90c19e82c19d9eeef333e617" + "sha256:3a83b2a68370c69c9cd3fcb88bbfaebe9d22edeef2c22d1ff3e1ed9c7fa45ed8", + "sha256:5b5d6dea81a5eb0c9ca39f116c8578dd413778060c94c1f51196371618909325" ], "markers": "python_version >= '3.7'", - "version": "==0.5.0" + "version": "==0.6.0" }, "defusedxml": { "hashes": [ @@ -179,11 +179,10 @@ }, "discord-py": { "git": "https://github.com/Rapptz/discord.py.git", - "ref": "97fe07edb2f3d0f5a980917fb6ee479bf396fd94" + "ref": "a14b43f2fda863ed6555374eb872bf014bdd1adf" }, "discord.py": { - "git": "https://github.com/Rapptz/discord.py.git", - "ref": "97fe07edb2f3d0f5a980917fb6ee479bf396fd94" + "git": "https://github.com/Rapptz/discord.py.git" }, "dnspython": { "hashes": [ @@ -317,44 +316,47 @@ }, "pillow": { "hashes": [ - "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97", - "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049", - "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c", - "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae", - "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28", - "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030", - "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56", - "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976", - "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e", - "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e", - "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f", - "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b", - "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a", - "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e", - "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa", - "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7", - "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00", - "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838", - "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360", - "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b", - "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a", - "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd", - "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4", - "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70", - "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204", - "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc", - "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b", - "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669", - "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7", - "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e", - "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c", - "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092", - "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c", - "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5", - "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac" + "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e", + "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595", + "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512", + "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c", + "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477", + "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a", + "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4", + "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e", + "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5", + "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378", + "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a", + "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652", + "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7", + "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a", + "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a", + "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6", + "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165", + "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160", + "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331", + "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b", + "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458", + "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033", + "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8", + "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481", + "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58", + "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7", + "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3", + "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea", + "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34", + "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3", + "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8", + "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581", + "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244", + "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef", + "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0", + "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2", + "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97", + "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717" ], "markers": "python_version >= '3.7'", - "version": "==9.0.1" + "version": "==9.1.0" }, "pycparser": { "hashes": [ @@ -513,11 +515,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", - "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" + "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", + "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" ], - "markers": "python_version >= '3.6'", - "version": "==4.1.1" + "markers": "python_version >= '3.7'", + "version": "==4.2.0" }, "uvloop": { "hashes": [ @@ -661,11 +663,11 @@ }, "click": { "hashes": [ - "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1", - "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb" + "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e", + "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72" ], - "markers": "python_version >= '3.6'", - "version": "==8.0.4" + "markers": "python_version >= '3.7'", + "version": "==8.1.2" }, "colorama": { "hashes": [ @@ -820,91 +822,91 @@ }, "regex": { "hashes": [ - "sha256:0066a6631c92774391f2ea0f90268f0d82fffe39cb946f0f9c6b382a1c61a5e5", - "sha256:0100f0ded953b6b17f18207907159ba9be3159649ad2d9b15535a74de70359d3", - "sha256:01c913cf573d1da0b34c9001a94977273b5ee2fe4cb222a5d5b320f3a9d1a835", - "sha256:0214ff6dff1b5a4b4740cfe6e47f2c4c92ba2938fca7abbea1359036305c132f", - "sha256:029e9e7e0d4d7c3446aa92474cbb07dafb0b2ef1d5ca8365f059998c010600e6", - "sha256:0317eb6331146c524751354ebef76a7a531853d7207a4d760dfb5f553137a2a4", - "sha256:04b5ee2b6d29b4a99d38a6469aa1db65bb79d283186e8460542c517da195a8f6", - "sha256:04c09b9651fa814eeeb38e029dc1ae83149203e4eeb94e52bb868fadf64852bc", - "sha256:058054c7a54428d5c3e3739ac1e363dc9347d15e64833817797dc4f01fb94bb8", - "sha256:060f9066d2177905203516c62c8ea0066c16c7342971d54204d4e51b13dfbe2e", - "sha256:0a7b75cc7bb4cc0334380053e4671c560e31272c9d2d5a6c4b8e9ae2c9bd0f82", - "sha256:0e2630ae470d6a9f8e4967388c1eda4762706f5750ecf387785e0df63a4cc5af", - "sha256:174d964bc683b1e8b0970e1325f75e6242786a92a22cedb2a6ec3e4ae25358bd", - "sha256:25ecb1dffc5e409ca42f01a2b2437f93024ff1612c1e7983bad9ee191a5e8828", - "sha256:286908cbe86b1a0240a867aecfe26a439b16a1f585d2de133540549831f8e774", - "sha256:303b15a3d32bf5fe5a73288c316bac5807587f193ceee4eb6d96ee38663789fa", - "sha256:34bb30c095342797608727baf5c8aa122406aa5edfa12107b8e08eb432d4c5d7", - "sha256:3e265b388cc80c7c9c01bb4f26c9e536c40b2c05b7231fbb347381a2e1c8bf43", - "sha256:3e4d710ff6539026e49f15a3797c6b1053573c2b65210373ef0eec24480b900b", - "sha256:42eb13b93765c6698a5ab3bcd318d8c39bb42e5fa8a7fcf7d8d98923f3babdb1", - "sha256:48081b6bff550fe10bcc20c01cf6c83dbca2ccf74eeacbfac240264775fd7ecf", - "sha256:491fc754428514750ab21c2d294486223ce7385446f2c2f5df87ddbed32979ae", - "sha256:4d1445824944e642ffa54c4f512da17a953699c563a356d8b8cbdad26d3b7598", - "sha256:530a3a16e57bd3ea0dff5ec2695c09632c9d6c549f5869d6cf639f5f7153fb9c", - "sha256:591d4fba554f24bfa0421ba040cd199210a24301f923ed4b628e1e15a1001ff4", - "sha256:5a86cac984da35377ca9ac5e2e0589bd11b3aebb61801204bd99c41fac516f0d", - "sha256:5b1ceede92400b3acfebc1425937454aaf2c62cd5261a3fabd560c61e74f6da3", - "sha256:5b2e24f3ae03af3d8e8e6d824c891fea0ca9035c5d06ac194a2700373861a15c", - "sha256:6504c22c173bb74075d7479852356bb7ca80e28c8e548d4d630a104f231e04fb", - "sha256:673f5a393d603c34477dbad70db30025ccd23996a2d0916e942aac91cc42b31a", - "sha256:6ca6dcd17f537e9f3793cdde20ac6076af51b2bd8ad5fe69fa54373b17b48d3c", - "sha256:6e1d8ed9e61f37881c8db383a124829a6e8114a69bd3377a25aecaeb9b3538f8", - "sha256:75a5e6ce18982f0713c4bac0704bf3f65eed9b277edd3fb9d2b0ff1815943327", - "sha256:76435a92e444e5b8f346aed76801db1c1e5176c4c7e17daba074fbb46cb8d783", - "sha256:764e66a0e382829f6ad3bbce0987153080a511c19eb3d2f8ead3f766d14433ac", - "sha256:78ce90c50d0ec970bd0002462430e00d1ecfd1255218d52d08b3a143fe4bde18", - "sha256:794a6bc66c43db8ed06698fc32aaeaac5c4812d9f825e9589e56f311da7becd9", - "sha256:797437e6024dc1589163675ae82f303103063a0a580c6fd8d0b9a0a6708da29e", - "sha256:7b7494df3fdcc95a1f76cf134d00b54962dd83189520fd35b8fcd474c0aa616d", - "sha256:7d1a6e403ac8f1d91d8f51c441c3f99367488ed822bda2b40836690d5d0059f5", - "sha256:7f63877c87552992894ea1444378b9c3a1d80819880ae226bb30b04789c0828c", - "sha256:8923e1c5231549fee78ff9b2914fad25f2e3517572bb34bfaa3aea682a758683", - "sha256:8afcd1c2297bc989dceaa0379ba15a6df16da69493635e53431d2d0c30356086", - "sha256:8b1cc70e31aacc152a12b39245974c8fccf313187eead559ee5966d50e1b5817", - "sha256:8d1f3ea0d1924feb4cf6afb2699259f658a08ac6f8f3a4a806661c2dfcd66db1", - "sha256:940570c1a305bac10e8b2bc934b85a7709c649317dd16520471e85660275083a", - "sha256:947a8525c0a95ba8dc873191f9017d1b1e3024d4dc757f694e0af3026e34044a", - "sha256:9beb03ff6fe509d6455971c2489dceb31687b38781206bcec8e68bdfcf5f1db2", - "sha256:9c144405220c5ad3f5deab4c77f3e80d52e83804a6b48b6bed3d81a9a0238e4c", - "sha256:a98ae493e4e80b3ded6503ff087a8492db058e9c68de371ac3df78e88360b374", - "sha256:aa2ce79f3889720b46e0aaba338148a1069aea55fda2c29e0626b4db20d9fcb7", - "sha256:aa5eedfc2461c16a092a2fabc5895f159915f25731740c9152a1b00f4bcf629a", - "sha256:ab5d89cfaf71807da93c131bb7a19c3e19eaefd613d14f3bce4e97de830b15df", - "sha256:b4829db3737480a9d5bfb1c0320c4ee13736f555f53a056aacc874f140e98f64", - "sha256:b52771f05cff7517f7067fef19ffe545b1f05959e440d42247a17cd9bddae11b", - "sha256:b8248f19a878c72d8c0a785a2cd45d69432e443c9f10ab924c29adda77b324ae", - "sha256:b9809404528a999cf02a400ee5677c81959bc5cb938fdc696b62eb40214e3632", - "sha256:c155a1a80c5e7a8fa1d9bb1bf3c8a953532b53ab1196092749bafb9d3a7cbb60", - "sha256:c33ce0c665dd325200209340a88438ba7a470bd5f09f7424e520e1a3ff835b52", - "sha256:c5adc854764732dbd95a713f2e6c3e914e17f2ccdc331b9ecb777484c31f73b6", - "sha256:cb374a2a4dba7c4be0b19dc7b1adc50e6c2c26c3369ac629f50f3c198f3743a4", - "sha256:cd00859291658fe1fda48a99559fb34da891c50385b0bfb35b808f98956ef1e7", - "sha256:ce3057777a14a9a1399b81eca6a6bfc9612047811234398b84c54aeff6d536ea", - "sha256:d0a5a1fdc9f148a8827d55b05425801acebeeefc9e86065c7ac8b8cc740a91ff", - "sha256:dad3991f0678facca1a0831ec1ddece2eb4d1dd0f5150acb9440f73a3b863907", - "sha256:dc7b7c16a519d924c50876fb152af661a20749dcbf653c8759e715c1a7a95b18", - "sha256:dcbb7665a9db9f8d7642171152c45da60e16c4f706191d66a1dc47ec9f820aed", - "sha256:df037c01d68d1958dad3463e2881d3638a0d6693483f58ad41001aa53a83fcea", - "sha256:f08a7e4d62ea2a45557f561eea87c907222575ca2134180b6974f8ac81e24f06", - "sha256:f16cf7e4e1bf88fecf7f41da4061f181a6170e179d956420f84e700fb8a3fd6b", - "sha256:f2c53f3af011393ab5ed9ab640fa0876757498aac188f782a0c620e33faa2a3d", - "sha256:f320c070dea3f20c11213e56dbbd7294c05743417cde01392148964b7bc2d31a", - "sha256:f553a1190ae6cd26e553a79f6b6cfba7b8f304da2071052fa33469da075ea625", - "sha256:fc8c7958d14e8270171b3d72792b609c057ec0fa17d507729835b5cff6b7f69a" + "sha256:02543d6d5c32d361b7cc468079ba4cddaaf4a6544f655901ba1ff9d8e3f18755", + "sha256:036d1c1fbe69eba3ee253c107e71749cdbb4776db93d674bc0d5e28f30300734", + "sha256:071bcb625e890f28b7c4573124a6512ea65107152b1d3ca101ce33a52dad4593", + "sha256:0f8da3145f4b72f7ce6181c804eaa44cdcea313c8998cdade3d9e20a8717a9cb", + "sha256:0fb6cb16518ac7eff29d1e0b0cce90275dfae0f17154165491058c31d58bdd1d", + "sha256:0fd464e547dbabf4652ca5fe9d88d75ec30182981e737c07b3410235a44b9939", + "sha256:12af15b6edb00e425f713160cfd361126e624ec0de86e74f7cad4b97b7f169b3", + "sha256:165cc75cfa5aa0f12adb2ac6286330e7229a06dc0e6c004ec35da682b5b89579", + "sha256:1a07e8366115069f26822c47732122ab61598830a69f5629a37ea8881487c107", + "sha256:1c2de7f32fa87d04d40f54bce3843af430697aba51c3a114aa62837a0772f219", + "sha256:253f858a0255cd91a0424a4b15c2eedb12f20274f85731b0d861c8137e843065", + "sha256:275afc7352982ee947fc88f67a034b52c78395977b5fc7c9be15f7dc95b76f06", + "sha256:2bde99f2cdfd6db1ec7e02d68cadd384ffe7413831373ea7cc68c5415a0cb577", + "sha256:3241db067a7f69da57fba8bca543ac8a7ca415d91e77315690202749b9fdaba1", + "sha256:37903d5ca11fa47577e8952d2e2c6de28553b11c70defee827afb941ab2c6729", + "sha256:3dfbadb7b74d95f72f9f9dbf9778f7de92722ab520a109ceaf7927461fa85b10", + "sha256:3e35c50b27f36176c792738cb9b858523053bc495044d2c2b44db24376b266f1", + "sha256:3e9e983fc8e0d4d5ded7caa5aed39ca2cf6026d7e39801ef6f0af0b1b6cd9276", + "sha256:3f6bd8178cce5bb56336722d5569d19c50bba5915a69a2050c497fb921e7cb0f", + "sha256:43ee0df35925ae4b0cc6ee3f60b73369e559dd2ac40945044da9394dd9d3a51d", + "sha256:45b761406777a681db0c24686178532134c937d24448d9e085279b69e9eb7da4", + "sha256:46cbc5b23f85e94161b093dba1b49035697cf44c7db3c930adabfc0e6d861b95", + "sha256:4f2e2cef324ca9355049ee1e712f68e2e92716eba24275e6767b9bfa15f1f478", + "sha256:50b77622016f03989cd06ecf6b602c7a6b4ed2e3ce04133876b041d109c934ee", + "sha256:582ea06079a03750b5f71e20a87cd99e646d796638b5894ff85987ebf5e04924", + "sha256:58521abdab76583bd41ef47e5e2ddd93b32501aee4ee8cee71dee10a45ba46b1", + "sha256:5b9c7b6895a01204296e9523b3e12b43e013835a9de035a783907c2c1bc447f0", + "sha256:6165e737acb3bea3271372e8aa5ebe7226c8a8e8da1b94af2d6547c5a09d689d", + "sha256:66fb765b2173d90389384708e3e1d3e4be1148bd8d4d50476b1469da5a2f0229", + "sha256:68aed3fb0c61296bd6d234f558f78c51671f79ccb069cbcd428c2eea6fee7a5b", + "sha256:6a0ef57cccd8089b4249eebad95065390e56c04d4a92c51316eab4131bca96a9", + "sha256:709396c0c95b95045fac89b94f997410ff39b81a09863fe21002f390d48cc7d3", + "sha256:73ed1b06abadbf6b61f6033a07c06f36ec0ddca117e41ef2ac37056705e46458", + "sha256:7a608022f4593fc67518c6c599ae5abdb03bb8acd75993c82cd7a4c8100eff81", + "sha256:7c4d9770e579eb11b582b2e2fd19fa204a15cb1589ae73cd4dcbb63b64f3e828", + "sha256:7dbc96419ef0fb6ac56626014e6d3a345aeb8b17a3df8830235a88626ffc8d84", + "sha256:7f271d0831d8ebc56e17b37f9fa1824b0379221d1238ae77c18a6e8c47f1fdce", + "sha256:82b7fc67e49fdce671bdbec1127189fc979badf062ce6e79dc95ef5e07a8bf92", + "sha256:85b7ee4d0c7a46296d884f6b489af8b960c4291d76aea4b22fd4fbe05e6ec08e", + "sha256:8b747cef8e5dcdaf394192d43a0c02f5825aeb0ecd3d43e63ae500332ab830b0", + "sha256:8bf867ba71856414a482e4b683500f946c300c4896e472e51d3db8dfa8dc8f32", + "sha256:8e0da7ef160d4f3eb3d4d3e39a02c3c42f7dbcfce62c81f784cc99fc7059765f", + "sha256:8e7d33f93cdd01868327d834d0f5bb029241cd293b47d51b96814dec27fc9b4b", + "sha256:92183e9180c392371079262879c6532ccf55f808e6900df5d9f03c9ca8807255", + "sha256:92ad03f928675ca05b79d3b1d3dfc149e2226d57ed9d57808f82105d511d0212", + "sha256:97af238389cb029d63d5f2d931a7e8f5954ad96e812de5faaed373b68e74df86", + "sha256:9913bcf730eb6e9b441fb176832eea9acbebab6035542c7c89d90c803f5cd3be", + "sha256:9dae5affbb66178dad6c6fd5b02221ca9917e016c75ee3945e9a9563eb1fbb6f", + "sha256:a850f5f369f1e3b6239da7fb43d1d029c1e178263df671819889c47caf7e4ff3", + "sha256:aa6daa189db9104787ff1fd7a7623ce017077aa59eaac609d0d25ba95ed251a0", + "sha256:aabc28f7599f781ddaeac168d0b566d0db82182cc3dcf62129f0a4fc2927b811", + "sha256:af1e687ffab18a75409e5e5d6215b6ccd41a5a1a0ea6ce9665e01253f737a0d3", + "sha256:b1d53835922cd0f9b74b2742453a444865a70abae38d12eb41c59271da66f38d", + "sha256:b2df3ede85d778c949d9bd2a50237072cee3df0a423c91f5514f78f8035bde87", + "sha256:b415b82e5be7389ec5ee7ee35431e4a549ea327caacf73b697c6b3538cb5c87f", + "sha256:b7ba3c304a4a5d8112dbd30df8b3e4ef59b4b07807957d3c410d9713abaee9a8", + "sha256:bcc6f7a3a95119c3568c572ca167ada75f8319890706283b9ba59b3489c9bcb3", + "sha256:be392d9cd5309509175a9d7660dc17bf57084501108dbff0c5a8bfc3646048c3", + "sha256:bea61de0c688198e3d9479344228c7accaa22a78b58ec408e41750ebafee6c08", + "sha256:bedb3d01ad35ea1745bdb1d57f3ee0f996f988c98f5bbae9d068c3bb3065d210", + "sha256:c36906a7855ec33a9083608e6cd595e4729dab18aeb9aad0dd0b039240266239", + "sha256:c4fdf837666f7793a5c3cfa2f2f39f03eb6c7e92e831bc64486c2f547580c2b3", + "sha256:cfad3a770839aa456ff9a9aa0e253d98b628d005a3ccb37da1ff9be7c84fee16", + "sha256:d128e278e5e554c5c022c7bed410ca851e00bacebbb4460de546a73bc53f8de4", + "sha256:dffd9114ade73137ab2b79a8faf864683dbd2dbbb6b23a305fbbd4cbaeeb2187", + "sha256:e2acf5c66fbb62b5fe4c40978ddebafa50818f00bf79d60569d9762f6356336e", + "sha256:e65580ae3137bce712f505ec7c2d700aef0014a3878c4767b74aff5895fc454f", + "sha256:e944268445b5694f5d41292c9228f0ca46d5a32a67f195d5f8547c1f1d91f4bc", + "sha256:ed26c3d2d62c6588e0dad175b8d8cc0942a638f32d07b80f92043e5d73b7db67", + "sha256:ed625205f5f26984382b68e4cbcbc08e6603c9e84c14b38457170b0cc71c823b", + "sha256:f2a5d9f612091812dee18375a45d046526452142e7b78c4e21ab192db15453d5", + "sha256:f86aef546add4ff1202e1f31e9bb54f9268f17d996b2428877283146bf9bc013", + "sha256:f89d26e50a4c7453cb8c415acd09e72fbade2610606a9c500a1e48c43210a42d", + "sha256:fb7107faf0168de087f62a2f2ed00f9e9da12e0b801582b516ddac236b871cda" ], "markers": "python_version >= '3.6'", - "version": "==2022.3.15" + "version": "==2022.4.24" }, "setuptools": { "hashes": [ - "sha256:6599055eeb23bfef457d5605d33a4d68804266e6cb430b0fb12417c5efeae36c", - "sha256:782ef48d58982ddb49920c11a0c5c9c0b02e7d7d1c2ad0aa44e1a1e133051c96" + "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8", + "sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592" ], "markers": "python_version >= '3.7'", - "version": "==60.10.0" + "version": "==62.1.0" }, "smmap": { "hashes": [ diff --git a/bot.py b/bot.py index 4ff3e69091..2887fd79dc 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev9" +__version__ = "4.0.0-dev10" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 3b821dd6f8..9d08c1d2b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev9' +version = '4.0.0-dev10' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ diff --git a/requirements.txt b/requirements.txt index f0e1933ce0..5a595bb521 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2 colorama==0.4.4 dnspython==2.1.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.2.0 -git+https://github.com/Rapptz/discord.py.git@987235d5649e7c2b1a927637bab6547244ecb2cf#egg=discord-py +git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord-py idna==3.3; python_version >= '3.5' isodate==0.6.0 motor==2.4.0 From 16816f32158b8b1819ab645b52b3dda7d0cc47a8 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 22:01:35 +0800 Subject: [PATCH 524/705] formatting --- cogs/utility.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 7facfbf1d2..df904cd331 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -914,9 +914,7 @@ def fmt(val): for i, (current_key, info) in enumerate(config_help.items()): if current_key == key: index = i - embed = discord.Embed( - title=f"{current_key}", color=self.bot.main_color - ) + embed = discord.Embed(title=f"{current_key}", color=self.bot.main_color) embed.add_field(name="Default:", value=fmt(info["default"]), inline=False) embed.add_field(name="Information:", value=fmt(info["description"]), inline=False) if info["examples"]: From 4f15cf6666f59f915d9ed6eeab03fe1154151203 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 22:06:27 +0800 Subject: [PATCH 525/705] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4696b7067c..55a23a8db3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,13 +25,13 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/kyb3r/modmail/issues/3122)) - Select menus for certain paginators. - `Title` field in `?logs`. ([GH #3142](https://github.com/kyb3r/modmail/issues/3142)) +- Snippets can be used in aliases. ([GH #3108](https://github.com/kyb3r/modmail/issues/3108), [PR #3124](https://github.com/kyb3r/modmail/pull/3124)) ### Improved - Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/kyb3r/modmail/issues/3048)) - Use discord relative timedeltas. ([GH #3046](https://github.com/kyb3r/modmail/issues/3046)) - Use discord native buttons for all paginator sessions. -- Snippets can be used in aliases. ([GH #3108](https://github.com/kyb3r/modmail/issues/3108), [PR #3124](https://github.com/kyb3r/modmail/pull/3124)) ### Fixed From 70decd82e835e942be08e8552567e3f97e830763 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 22:16:59 +0800 Subject: [PATCH 526/705] Fix reqs --- Pipfile | 5 +-- Pipfile.lock | 9 +++--- requirements.txt | 79 ++++++++++++++++++++++++------------------------ 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/Pipfile b/Pipfile index c74f6cb1a7..9c537d8bd2 100644 --- a/Pipfile +++ b/Pipfile @@ -11,7 +11,7 @@ pylint = "~=2.9.3" [packages] aiohttp = "==3.7.4.post0" colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 -"discord.py" = {git = "https://github.com/Rapptz/discord.py.git"} +"discord.py" = {ref = "a14b43f2fda863ed6555374eb872bf014bdd1adf", git = "https://github.com/Rapptz/discord.py.git"} emoji = "~=1.2.0" isodate = "~=0.6.0" motor = "~=2.4.0" @@ -25,6 +25,3 @@ lottie = {version = "==0.6.10", extras = ["pdf"]} [scripts] bot = "python bot.py" - -[requires] -python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock index d163dd5ae1..ec6f1fc5c6 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,12 +1,10 @@ { "_meta": { "hash": { - "sha256": "c0006885019e90564b0907b571e5a7bcd5f8b47d1dc3c535959f2600d4d15ba6" + "sha256": "5280f0d7e4c267e164f83139d89bec37c4691a5815b831b871a3091db1af56eb" }, "pipfile-spec": 6, - "requires": { - "python_version": "3.9" - }, + "requires": {}, "sources": [ { "name": "pypi", @@ -182,7 +180,8 @@ "ref": "a14b43f2fda863ed6555374eb872bf014bdd1adf" }, "discord.py": { - "git": "https://github.com/Rapptz/discord.py.git" + "git": "https://github.com/Rapptz/discord.py.git", + "ref": "a14b43f2fda863ed6555374eb872bf014bdd1adf" }, "dnspython": { "hashes": [ diff --git a/requirements.txt b/requirements.txt index 8b6e2499cc..34852a4e37 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,39 +1,40 @@ -# -# These requirements were autogenerated by pipenv -# To regenerate from the project's Pipfile, run: -# -# pipenv lock --requirements -# - --i https://pypi.org/simple -aiohttp==3.7.4.post0 -async-timeout==3.0.1; python_full_version >= '3.5.3' -attrs==21.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -cairocffi==1.3.0; python_version >= '3.7' -cairosvg==2.5.2; python_version >= '3.5' -cffi==1.15.0 -chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -colorama==0.4.4 -cssselect2==0.4.1; python_version >= '3.6' -defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -dnspython==2.1.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -emoji==1.2.0 -git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord-py -idna==3.3; python_version >= '3.5' -isodate==0.6.0 -lottie[pdf]==0.6.10 -motor==2.4.0 -multidict==5.2.0; python_version >= '3.6' -natural==0.2.0 -parsedatetime==2.6 -pillow==8.4.0; python_version >= '3.6' -pycparser==2.21 -pymongo[srv]==3.12.1 -python-dateutil==2.8.2 -python-dotenv==0.18.0 -six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -tinycss2==1.1.0; python_version >= '3.6' -typing-extensions==4.0.0; python_version >= '3.6' -uvloop==0.16.0; sys_platform != 'win32' -webencodings==0.5.1 -yarl==1.7.2; python_version >= '3.6' \ No newline at end of file +# +# These requirements were autogenerated by pipenv +# To regenerate from the project's Pipfile, run: +# +# pipenv lock --requirements +# + +-i https://pypi.org/simple +aiohttp==3.7.4.post0 +async-timeout==3.0.1; python_full_version >= '3.5.3' +attrs==21.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +cairocffi==1.3.0; python_version >= '3.7' +cairosvg==2.5.2; python_version >= '3.5' +cffi==1.15.0 +chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +colorama==0.4.4 +cssselect2==0.6.0; python_version >= '3.7' +defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +emoji==1.2.0 +git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord-py +git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord.py +idna==3.3; python_version >= '3.5' +isodate==0.6.1 +lottie[pdf]==0.6.10 +motor==2.4.0 +multidict==6.0.2; python_version >= '3.7' +natural==0.2.0 +parsedatetime==2.6 +pillow==9.1.0; python_version >= '3.7' +pycparser==2.21 +pymongo[srv]==3.12.3 +python-dateutil==2.8.2 +python-dotenv==0.18.0 +six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +tinycss2==1.1.1; python_version >= '3.6' +typing-extensions==4.2.0; python_version >= '3.7' +uvloop==0.16.0; sys_platform != 'win32' +webencodings==0.5.1 +yarl==1.7.2; python_version >= '3.6' From ef100c283fdb84da6b4c6e52f21f9b2440036719 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 22:19:59 +0800 Subject: [PATCH 527/705] another attempt to fix reqs --- .github/workflows/lints.yml | 2 +- requirements.txt | 80 ++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 091e012dd9..8498875fd3 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -21,7 +21,7 @@ jobs: python-version: 3.9 - name: Install dependencies run: | - python -m pip install --upgrade pip pipenv + python -m pip install --upgrade pip pipenv click==8.1.2 pipenv install --dev --system # - name: Bandit syntax check # run: bandit -r . -b .bandit_baseline.json diff --git a/requirements.txt b/requirements.txt index 34852a4e37..ecff8c80c8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,40 +1,40 @@ -# -# These requirements were autogenerated by pipenv -# To regenerate from the project's Pipfile, run: -# -# pipenv lock --requirements -# - --i https://pypi.org/simple -aiohttp==3.7.4.post0 -async-timeout==3.0.1; python_full_version >= '3.5.3' -attrs==21.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -cairocffi==1.3.0; python_version >= '3.7' -cairosvg==2.5.2; python_version >= '3.5' -cffi==1.15.0 -chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -colorama==0.4.4 -cssselect2==0.6.0; python_version >= '3.7' -defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -emoji==1.2.0 -git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord-py -git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord.py -idna==3.3; python_version >= '3.5' -isodate==0.6.1 -lottie[pdf]==0.6.10 -motor==2.4.0 -multidict==6.0.2; python_version >= '3.7' -natural==0.2.0 -parsedatetime==2.6 -pillow==9.1.0; python_version >= '3.7' -pycparser==2.21 -pymongo[srv]==3.12.3 -python-dateutil==2.8.2 -python-dotenv==0.18.0 -six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -tinycss2==1.1.1; python_version >= '3.6' -typing-extensions==4.2.0; python_version >= '3.7' -uvloop==0.16.0; sys_platform != 'win32' -webencodings==0.5.1 -yarl==1.7.2; python_version >= '3.6' +# +# These requirements were autogenerated by pipenv +# To regenerate from the project's Pipfile, run: +# +# pipenv lock --requirements +# + +-i https://pypi.org/simple + +aiohttp==3.7.4.post0 +async-timeout==3.0.1; python_full_version >= '3.5.3' +attrs==21.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +cairocffi==1.3.0; python_version >= '3.7' +cairosvg==2.5.2; python_version >= '3.5' +cffi==1.15.0 +chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +colorama==0.4.4 +cssselect2==0.6.0; python_version >= '3.7' +defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +emoji==1.2.0 +git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord.py +idna==3.3; python_version >= '3.5' +isodate==0.6.1 +lottie[pdf]==0.6.10 +motor==2.4.0 +multidict==6.0.2; python_version >= '3.7' +natural==0.2.0 +parsedatetime==2.6 +pillow==9.1.0; python_version >= '3.7' +pycparser==2.21 +pymongo[srv]==3.12.3 +python-dateutil==2.8.2 +python-dotenv==0.18.0 +six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +tinycss2==1.1.1; python_version >= '3.6' +typing-extensions==4.2.0; python_version >= '3.7' +uvloop==0.16.0; sys_platform != 'win32' +webencodings==0.5.1 +yarl==1.7.2; python_version >= '3.6' From c8b1a78caa12dee7239c1d7bda92e7ad1c6dbc91 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 22:31:01 +0800 Subject: [PATCH 528/705] bump black https://github.com/psf/black/issues/2964 --- .github/workflows/lints.yml | 2 +- Pipfile | 2 +- Pipfile.lock | 132 +++++++++++------------------------- 3 files changed, 43 insertions(+), 93 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 8498875fd3..091e012dd9 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -21,7 +21,7 @@ jobs: python-version: 3.9 - name: Install dependencies run: | - python -m pip install --upgrade pip pipenv click==8.1.2 + python -m pip install --upgrade pip pipenv pipenv install --dev --system # - name: Bandit syntax check # run: bandit -r . -b .bandit_baseline.json diff --git a/Pipfile b/Pipfile index 9c537d8bd2..268523dd92 100644 --- a/Pipfile +++ b/Pipfile @@ -5,7 +5,7 @@ verify_ssl = true [dev-packages] bandit = "~=1.7.0" -black = "==21.6b0" +black = "==22.3.0" pylint = "~=2.9.3" [packages] diff --git a/Pipfile.lock b/Pipfile.lock index ec6f1fc5c6..f60ea59424 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "5280f0d7e4c267e164f83139d89bec37c4691a5815b831b871a3091db1af56eb" + "sha256": "d7f737bdd78a969ba477bc9d9b334a1429a70cb78fec53d8b95c5732bbb6a3bd" }, "pipfile-spec": 6, "requires": {}, @@ -629,13 +629,6 @@ } }, "develop": { - "appdirs": { - "hashes": [ - "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", - "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" - ], - "version": "==1.4.4" - }, "astroid": { "hashes": [ "sha256:3975a0bd5373bdce166e60c851cfcbaf21ee96de80ec518c1f4cb3e94c3fb334", @@ -654,11 +647,32 @@ }, "black": { "hashes": [ - "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04", - "sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7" + "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b", + "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176", + "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09", + "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a", + "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015", + "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79", + "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb", + "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20", + "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464", + "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968", + "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82", + "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21", + "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0", + "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265", + "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b", + "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a", + "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72", + "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce", + "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0", + "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a", + "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163", + "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad", + "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d" ], "index": "pypi", - "version": "==21.6b0" + "version": "==22.3.0" }, "click": { "hashes": [ @@ -772,6 +786,14 @@ "markers": "python_version >= '2.6'", "version": "==5.8.1" }, + "platformdirs": { + "hashes": [ + "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", + "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" + ], + "markers": "python_version >= '3.7'", + "version": "==2.5.2" + }, "pylint": { "hashes": [ "sha256:2e1a0eb2e8ab41d6b5dbada87f066492bb1557b12b76c47c2ee8aa8a11186594", @@ -819,86 +841,6 @@ "markers": "python_version >= '3.6'", "version": "==6.0" }, - "regex": { - "hashes": [ - "sha256:02543d6d5c32d361b7cc468079ba4cddaaf4a6544f655901ba1ff9d8e3f18755", - "sha256:036d1c1fbe69eba3ee253c107e71749cdbb4776db93d674bc0d5e28f30300734", - "sha256:071bcb625e890f28b7c4573124a6512ea65107152b1d3ca101ce33a52dad4593", - "sha256:0f8da3145f4b72f7ce6181c804eaa44cdcea313c8998cdade3d9e20a8717a9cb", - "sha256:0fb6cb16518ac7eff29d1e0b0cce90275dfae0f17154165491058c31d58bdd1d", - "sha256:0fd464e547dbabf4652ca5fe9d88d75ec30182981e737c07b3410235a44b9939", - "sha256:12af15b6edb00e425f713160cfd361126e624ec0de86e74f7cad4b97b7f169b3", - "sha256:165cc75cfa5aa0f12adb2ac6286330e7229a06dc0e6c004ec35da682b5b89579", - "sha256:1a07e8366115069f26822c47732122ab61598830a69f5629a37ea8881487c107", - "sha256:1c2de7f32fa87d04d40f54bce3843af430697aba51c3a114aa62837a0772f219", - "sha256:253f858a0255cd91a0424a4b15c2eedb12f20274f85731b0d861c8137e843065", - "sha256:275afc7352982ee947fc88f67a034b52c78395977b5fc7c9be15f7dc95b76f06", - "sha256:2bde99f2cdfd6db1ec7e02d68cadd384ffe7413831373ea7cc68c5415a0cb577", - "sha256:3241db067a7f69da57fba8bca543ac8a7ca415d91e77315690202749b9fdaba1", - "sha256:37903d5ca11fa47577e8952d2e2c6de28553b11c70defee827afb941ab2c6729", - "sha256:3dfbadb7b74d95f72f9f9dbf9778f7de92722ab520a109ceaf7927461fa85b10", - "sha256:3e35c50b27f36176c792738cb9b858523053bc495044d2c2b44db24376b266f1", - "sha256:3e9e983fc8e0d4d5ded7caa5aed39ca2cf6026d7e39801ef6f0af0b1b6cd9276", - "sha256:3f6bd8178cce5bb56336722d5569d19c50bba5915a69a2050c497fb921e7cb0f", - "sha256:43ee0df35925ae4b0cc6ee3f60b73369e559dd2ac40945044da9394dd9d3a51d", - "sha256:45b761406777a681db0c24686178532134c937d24448d9e085279b69e9eb7da4", - "sha256:46cbc5b23f85e94161b093dba1b49035697cf44c7db3c930adabfc0e6d861b95", - "sha256:4f2e2cef324ca9355049ee1e712f68e2e92716eba24275e6767b9bfa15f1f478", - "sha256:50b77622016f03989cd06ecf6b602c7a6b4ed2e3ce04133876b041d109c934ee", - "sha256:582ea06079a03750b5f71e20a87cd99e646d796638b5894ff85987ebf5e04924", - "sha256:58521abdab76583bd41ef47e5e2ddd93b32501aee4ee8cee71dee10a45ba46b1", - "sha256:5b9c7b6895a01204296e9523b3e12b43e013835a9de035a783907c2c1bc447f0", - "sha256:6165e737acb3bea3271372e8aa5ebe7226c8a8e8da1b94af2d6547c5a09d689d", - "sha256:66fb765b2173d90389384708e3e1d3e4be1148bd8d4d50476b1469da5a2f0229", - "sha256:68aed3fb0c61296bd6d234f558f78c51671f79ccb069cbcd428c2eea6fee7a5b", - "sha256:6a0ef57cccd8089b4249eebad95065390e56c04d4a92c51316eab4131bca96a9", - "sha256:709396c0c95b95045fac89b94f997410ff39b81a09863fe21002f390d48cc7d3", - "sha256:73ed1b06abadbf6b61f6033a07c06f36ec0ddca117e41ef2ac37056705e46458", - "sha256:7a608022f4593fc67518c6c599ae5abdb03bb8acd75993c82cd7a4c8100eff81", - "sha256:7c4d9770e579eb11b582b2e2fd19fa204a15cb1589ae73cd4dcbb63b64f3e828", - "sha256:7dbc96419ef0fb6ac56626014e6d3a345aeb8b17a3df8830235a88626ffc8d84", - "sha256:7f271d0831d8ebc56e17b37f9fa1824b0379221d1238ae77c18a6e8c47f1fdce", - "sha256:82b7fc67e49fdce671bdbec1127189fc979badf062ce6e79dc95ef5e07a8bf92", - "sha256:85b7ee4d0c7a46296d884f6b489af8b960c4291d76aea4b22fd4fbe05e6ec08e", - "sha256:8b747cef8e5dcdaf394192d43a0c02f5825aeb0ecd3d43e63ae500332ab830b0", - "sha256:8bf867ba71856414a482e4b683500f946c300c4896e472e51d3db8dfa8dc8f32", - "sha256:8e0da7ef160d4f3eb3d4d3e39a02c3c42f7dbcfce62c81f784cc99fc7059765f", - "sha256:8e7d33f93cdd01868327d834d0f5bb029241cd293b47d51b96814dec27fc9b4b", - "sha256:92183e9180c392371079262879c6532ccf55f808e6900df5d9f03c9ca8807255", - "sha256:92ad03f928675ca05b79d3b1d3dfc149e2226d57ed9d57808f82105d511d0212", - "sha256:97af238389cb029d63d5f2d931a7e8f5954ad96e812de5faaed373b68e74df86", - "sha256:9913bcf730eb6e9b441fb176832eea9acbebab6035542c7c89d90c803f5cd3be", - "sha256:9dae5affbb66178dad6c6fd5b02221ca9917e016c75ee3945e9a9563eb1fbb6f", - "sha256:a850f5f369f1e3b6239da7fb43d1d029c1e178263df671819889c47caf7e4ff3", - "sha256:aa6daa189db9104787ff1fd7a7623ce017077aa59eaac609d0d25ba95ed251a0", - "sha256:aabc28f7599f781ddaeac168d0b566d0db82182cc3dcf62129f0a4fc2927b811", - "sha256:af1e687ffab18a75409e5e5d6215b6ccd41a5a1a0ea6ce9665e01253f737a0d3", - "sha256:b1d53835922cd0f9b74b2742453a444865a70abae38d12eb41c59271da66f38d", - "sha256:b2df3ede85d778c949d9bd2a50237072cee3df0a423c91f5514f78f8035bde87", - "sha256:b415b82e5be7389ec5ee7ee35431e4a549ea327caacf73b697c6b3538cb5c87f", - "sha256:b7ba3c304a4a5d8112dbd30df8b3e4ef59b4b07807957d3c410d9713abaee9a8", - "sha256:bcc6f7a3a95119c3568c572ca167ada75f8319890706283b9ba59b3489c9bcb3", - "sha256:be392d9cd5309509175a9d7660dc17bf57084501108dbff0c5a8bfc3646048c3", - "sha256:bea61de0c688198e3d9479344228c7accaa22a78b58ec408e41750ebafee6c08", - "sha256:bedb3d01ad35ea1745bdb1d57f3ee0f996f988c98f5bbae9d068c3bb3065d210", - "sha256:c36906a7855ec33a9083608e6cd595e4729dab18aeb9aad0dd0b039240266239", - "sha256:c4fdf837666f7793a5c3cfa2f2f39f03eb6c7e92e831bc64486c2f547580c2b3", - "sha256:cfad3a770839aa456ff9a9aa0e253d98b628d005a3ccb37da1ff9be7c84fee16", - "sha256:d128e278e5e554c5c022c7bed410ca851e00bacebbb4460de546a73bc53f8de4", - "sha256:dffd9114ade73137ab2b79a8faf864683dbd2dbbb6b23a305fbbd4cbaeeb2187", - "sha256:e2acf5c66fbb62b5fe4c40978ddebafa50818f00bf79d60569d9762f6356336e", - "sha256:e65580ae3137bce712f505ec7c2d700aef0014a3878c4767b74aff5895fc454f", - "sha256:e944268445b5694f5d41292c9228f0ca46d5a32a67f195d5f8547c1f1d91f4bc", - "sha256:ed26c3d2d62c6588e0dad175b8d8cc0942a638f32d07b80f92043e5d73b7db67", - "sha256:ed625205f5f26984382b68e4cbcbc08e6603c9e84c14b38457170b0cc71c823b", - "sha256:f2a5d9f612091812dee18375a45d046526452142e7b78c4e21ab192db15453d5", - "sha256:f86aef546add4ff1202e1f31e9bb54f9268f17d996b2428877283146bf9bc013", - "sha256:f89d26e50a4c7453cb8c415acd09e72fbade2610606a9c500a1e48c43210a42d", - "sha256:fb7107faf0168de087f62a2f2ed00f9e9da12e0b801582b516ddac236b871cda" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.4.24" - }, "setuptools": { "hashes": [ "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8", @@ -931,6 +873,14 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, + "tomli": { + "hashes": [ + "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + ], + "markers": "python_version < '3.11'", + "version": "==2.0.1" + }, "wrapt": { "hashes": [ "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" From fe074f1d86f206e6ad7f457cc79a4d9ae099ee12 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 22:54:43 +0800 Subject: [PATCH 529/705] bump range of dependencies, resolve #3126 --- CHANGELOG.md | 5 + Pipfile | 10 +- Pipfile.lock | 391 ++++++++++++++++++++++----------------------------- 3 files changed, 177 insertions(+), 229 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55a23a8db3..e97b127b95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,11 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Improve regex parsing of channel topics. ([GH #3114](https://github.com/kyb3r/modmail/issues/3114), [PR #3111](https://github.com/kyb3r/modmail/pull/3111)) - Add warning if deploying on a developmental version. - Extensions are now loaded `on_connect`. +- MongoDB v5.0 clients are now supported. ([GH #3126](https://github.com/kyb3r/modmail/issues/3126)) +- Bump python-dotenv to v0.20.0, support for python 3.10 +- Bump emoji to v1.7.0 +- Bump aiohttp to v3.8.1 +- Bump lottie to v0.6.11 # v3.10.3 diff --git a/Pipfile b/Pipfile index 268523dd92..99d50e47e4 100644 --- a/Pipfile +++ b/Pipfile @@ -9,19 +9,19 @@ black = "==22.3.0" pylint = "~=2.9.3" [packages] -aiohttp = "==3.7.4.post0" +aiohttp = "==3.8.1" colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 "discord.py" = {ref = "a14b43f2fda863ed6555374eb872bf014bdd1adf", git = "https://github.com/Rapptz/discord.py.git"} -emoji = "~=1.2.0" +emoji = "==1.7.0" isodate = "~=0.6.0" -motor = "~=2.4.0" +motor = "==2.5.1" natural = "~=0.2.0" parsedatetime = "~=2.6" pymongo = {extras = ["srv"], version = "*"} # Required by motor python-dateutil = "~=2.8.1" -python-dotenv = "~=0.18.0" +python-dotenv = "==0.20.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} -lottie = {version = "==0.6.10", extras = ["pdf"]} +lottie = "==0.6.11" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index f60ea59424..3ce9602d5e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d7f737bdd78a969ba477bc9d9b334a1429a70cb78fec53d8b95c5732bbb6a3bd" + "sha256": "dea4d7675ab1e4a2c4d3f4f8ddcff27db7c0b3851a37e598b10dc429c2eaa5df" }, "pipfile-spec": 6, "requires": {}, @@ -16,54 +16,97 @@ "default": { "aiohttp": { "hashes": [ - "sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe", - "sha256:0563c1b3826945eecd62186f3f5c7d31abb7391fedc893b7e2b26303b5a9f3fe", - "sha256:114b281e4d68302a324dd33abb04778e8557d88947875cbf4e842c2c01a030c5", - "sha256:14762875b22d0055f05d12abc7f7d61d5fd4fe4642ce1a249abdf8c700bf1fd8", - "sha256:15492a6368d985b76a2a5fdd2166cddfea5d24e69eefed4630cbaae5c81d89bd", - "sha256:17c073de315745a1510393a96e680d20af8e67e324f70b42accbd4cb3315c9fb", - "sha256:209b4a8ee987eccc91e2bd3ac36adee0e53a5970b8ac52c273f7f8fd4872c94c", - "sha256:230a8f7e24298dea47659251abc0fd8b3c4e38a664c59d4b89cca7f6c09c9e87", - "sha256:2e19413bf84934d651344783c9f5e22dee452e251cfd220ebadbed2d9931dbf0", - "sha256:393f389841e8f2dfc86f774ad22f00923fdee66d238af89b70ea314c4aefd290", - "sha256:3cf75f7cdc2397ed4442594b935a11ed5569961333d49b7539ea741be2cc79d5", - "sha256:3d78619672183be860b96ed96f533046ec97ca067fd46ac1f6a09cd9b7484287", - "sha256:40eced07f07a9e60e825554a31f923e8d3997cfc7fb31dbc1328c70826e04cde", - "sha256:493d3299ebe5f5a7c66b9819eacdcfbbaaf1a8e84911ddffcdc48888497afecf", - "sha256:4b302b45040890cea949ad092479e01ba25911a15e648429c7c5aae9650c67a8", - "sha256:515dfef7f869a0feb2afee66b957cc7bbe9ad0cdee45aec7fdc623f4ecd4fb16", - "sha256:547da6cacac20666422d4882cfcd51298d45f7ccb60a04ec27424d2f36ba3eaf", - "sha256:5df68496d19f849921f05f14f31bd6ef53ad4b00245da3195048c69934521809", - "sha256:64322071e046020e8797117b3658b9c2f80e3267daec409b350b6a7a05041213", - "sha256:7615dab56bb07bff74bc865307aeb89a8bfd9941d2ef9d817b9436da3a0ea54f", - "sha256:79ebfc238612123a713a457d92afb4096e2148be17df6c50fb9bf7a81c2f8013", - "sha256:7b18b97cf8ee5452fa5f4e3af95d01d84d86d32c5e2bfa260cf041749d66360b", - "sha256:932bb1ea39a54e9ea27fc9232163059a0b8855256f4052e776357ad9add6f1c9", - "sha256:a00bb73540af068ca7390e636c01cbc4f644961896fa9363154ff43fd37af2f5", - "sha256:a5ca29ee66f8343ed336816c553e82d6cade48a3ad702b9ffa6125d187e2dedb", - "sha256:af9aa9ef5ba1fd5b8c948bb11f44891968ab30356d65fd0cc6707d989cd521df", - "sha256:bb437315738aa441251214dad17428cafda9cdc9729499f1d6001748e1d432f4", - "sha256:bdb230b4943891321e06fc7def63c7aace16095be7d9cf3b1e01be2f10fba439", - "sha256:c6e9dcb4cb338d91a73f178d866d051efe7c62a7166653a91e7d9fb18274058f", - "sha256:cffe3ab27871bc3ea47df5d8f7013945712c46a3cc5a95b6bee15887f1675c22", - "sha256:d012ad7911653a906425d8473a1465caa9f8dea7fcf07b6d870397b774ea7c0f", - "sha256:d9e13b33afd39ddeb377eff2c1c4f00544e191e1d1dee5b6c51ddee8ea6f0cf5", - "sha256:e4b2b334e68b18ac9817d828ba44d8fcb391f6acb398bcc5062b14b2cbeac970", - "sha256:e54962802d4b8b18b6207d4a927032826af39395a3bd9196a5af43fc4e60b009", - "sha256:f705e12750171c0ab4ef2a3c76b9a4024a62c4103e3a55dd6f99265b9bc6fcfc", - "sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a", - "sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95" + "sha256:01d7bdb774a9acc838e6b8f1d114f45303841b89b95984cbb7d80ea41172a9e3", + "sha256:03a6d5349c9ee8f79ab3ff3694d6ce1cfc3ced1c9d36200cb8f08ba06bd3b782", + "sha256:04d48b8ce6ab3cf2097b1855e1505181bdd05586ca275f2505514a6e274e8e75", + "sha256:0770e2806a30e744b4e21c9d73b7bee18a1cfa3c47991ee2e5a65b887c49d5cf", + "sha256:07b05cd3305e8a73112103c834e91cd27ce5b4bd07850c4b4dbd1877d3f45be7", + "sha256:086f92daf51a032d062ec5f58af5ca6a44d082c35299c96376a41cbb33034675", + "sha256:099ebd2c37ac74cce10a3527d2b49af80243e2a4fa39e7bce41617fbc35fa3c1", + "sha256:0c7ebbbde809ff4e970824b2b6cb7e4222be6b95a296e46c03cf050878fc1785", + "sha256:102e487eeb82afac440581e5d7f8f44560b36cf0bdd11abc51a46c1cd88914d4", + "sha256:11691cf4dc5b94236ccc609b70fec991234e7ef8d4c02dd0c9668d1e486f5abf", + "sha256:11a67c0d562e07067c4e86bffc1553f2cf5b664d6111c894671b2b8712f3aba5", + "sha256:12de6add4038df8f72fac606dff775791a60f113a725c960f2bab01d8b8e6b15", + "sha256:13487abd2f761d4be7c8ff9080de2671e53fff69711d46de703c310c4c9317ca", + "sha256:15b09b06dae900777833fe7fc4b4aa426556ce95847a3e8d7548e2d19e34edb8", + "sha256:1c182cb873bc91b411e184dab7a2b664d4fea2743df0e4d57402f7f3fa644bac", + "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8", + "sha256:28d490af82bc6b7ce53ff31337a18a10498303fe66f701ab65ef27e143c3b0ef", + "sha256:2e5d962cf7e1d426aa0e528a7e198658cdc8aa4fe87f781d039ad75dcd52c516", + "sha256:2ed076098b171573161eb146afcb9129b5ff63308960aeca4b676d9d3c35e700", + "sha256:2f2f69dca064926e79997f45b2f34e202b320fd3782f17a91941f7eb85502ee2", + "sha256:31560d268ff62143e92423ef183680b9829b1b482c011713ae941997921eebc8", + "sha256:31d1e1c0dbf19ebccbfd62eff461518dcb1e307b195e93bba60c965a4dcf1ba0", + "sha256:37951ad2f4a6df6506750a23f7cbabad24c73c65f23f72e95897bb2cecbae676", + "sha256:3af642b43ce56c24d063325dd2cf20ee012d2b9ba4c3c008755a301aaea720ad", + "sha256:44db35a9e15d6fe5c40d74952e803b1d96e964f683b5a78c3cc64eb177878155", + "sha256:473d93d4450880fe278696549f2e7aed8cd23708c3c1997981464475f32137db", + "sha256:477c3ea0ba410b2b56b7efb072c36fa91b1e6fc331761798fa3f28bb224830dd", + "sha256:4a4a4e30bf1edcad13fb0804300557aedd07a92cabc74382fdd0ba6ca2661091", + "sha256:4aed991a28ea3ce320dc8ce655875e1e00a11bdd29fe9444dd4f88c30d558602", + "sha256:51467000f3647d519272392f484126aa716f747859794ac9924a7aafa86cd411", + "sha256:55c3d1072704d27401c92339144d199d9de7b52627f724a949fc7d5fc56d8b93", + "sha256:589c72667a5febd36f1315aa6e5f56dd4aa4862df295cb51c769d16142ddd7cd", + "sha256:5bfde62d1d2641a1f5173b8c8c2d96ceb4854f54a44c23102e2ccc7e02f003ec", + "sha256:5c23b1ad869653bc818e972b7a3a79852d0e494e9ab7e1a701a3decc49c20d51", + "sha256:61bfc23df345d8c9716d03717c2ed5e27374e0fe6f659ea64edcd27b4b044cf7", + "sha256:6ae828d3a003f03ae31915c31fa684b9890ea44c9c989056fea96e3d12a9fa17", + "sha256:6c7cefb4b0640703eb1069835c02486669312bf2f12b48a748e0a7756d0de33d", + "sha256:6d69f36d445c45cda7b3b26afef2fc34ef5ac0cdc75584a87ef307ee3c8c6d00", + "sha256:6f0d5f33feb5f69ddd57a4a4bd3d56c719a141080b445cbf18f238973c5c9923", + "sha256:6f8b01295e26c68b3a1b90efb7a89029110d3a4139270b24fda961893216c440", + "sha256:713ac174a629d39b7c6a3aa757b337599798da4c1157114a314e4e391cd28e32", + "sha256:718626a174e7e467f0558954f94af117b7d4695d48eb980146016afa4b580b2e", + "sha256:7187a76598bdb895af0adbd2fb7474d7f6025d170bc0a1130242da817ce9e7d1", + "sha256:71927042ed6365a09a98a6377501af5c9f0a4d38083652bcd2281a06a5976724", + "sha256:7d08744e9bae2ca9c382581f7dce1273fe3c9bae94ff572c3626e8da5b193c6a", + "sha256:7dadf3c307b31e0e61689cbf9e06be7a867c563d5a63ce9dca578f956609abf8", + "sha256:81e3d8c34c623ca4e36c46524a3530e99c0bc95ed068fd6e9b55cb721d408fb2", + "sha256:844a9b460871ee0a0b0b68a64890dae9c415e513db0f4a7e3cab41a0f2fedf33", + "sha256:8b7ef7cbd4fec9a1e811a5de813311ed4f7ac7d93e0fda233c9b3e1428f7dd7b", + "sha256:97ef77eb6b044134c0b3a96e16abcb05ecce892965a2124c566af0fd60f717e2", + "sha256:99b5eeae8e019e7aad8af8bb314fb908dd2e028b3cdaad87ec05095394cce632", + "sha256:a25fa703a527158aaf10dafd956f7d42ac6d30ec80e9a70846253dd13e2f067b", + "sha256:a2f635ce61a89c5732537a7896b6319a8fcfa23ba09bec36e1b1ac0ab31270d2", + "sha256:a79004bb58748f31ae1cbe9fa891054baaa46fb106c2dc7af9f8e3304dc30316", + "sha256:a996d01ca39b8dfe77440f3cd600825d05841088fd6bc0144cc6c2ec14cc5f74", + "sha256:b0e20cddbd676ab8a64c774fefa0ad787cc506afd844de95da56060348021e96", + "sha256:b6613280ccedf24354406caf785db748bebbddcf31408b20c0b48cb86af76866", + "sha256:b9d00268fcb9f66fbcc7cd9fe423741d90c75ee029a1d15c09b22d23253c0a44", + "sha256:bb01ba6b0d3f6c68b89fce7305080145d4877ad3acaed424bae4d4ee75faa950", + "sha256:c2aef4703f1f2ddc6df17519885dbfa3514929149d3ff900b73f45998f2532fa", + "sha256:c34dc4958b232ef6188c4318cb7b2c2d80521c9a56c52449f8f93ab7bc2a8a1c", + "sha256:c3630c3ef435c0a7c549ba170a0633a56e92629aeed0e707fec832dee313fb7a", + "sha256:c3d6a4d0619e09dcd61021debf7059955c2004fa29f48788a3dfaf9c9901a7cd", + "sha256:d15367ce87c8e9e09b0f989bfd72dc641bcd04ba091c68cd305312d00962addd", + "sha256:d2f9b69293c33aaa53d923032fe227feac867f81682f002ce33ffae978f0a9a9", + "sha256:e999f2d0e12eea01caeecb17b653f3713d758f6dcc770417cf29ef08d3931421", + "sha256:ea302f34477fda3f85560a06d9ebdc7fa41e82420e892fc50b577e35fc6a50b2", + "sha256:eaba923151d9deea315be1f3e2b31cc39a6d1d2f682f942905951f4e40200922", + "sha256:ef9612483cb35171d51d9173647eed5d0069eaa2ee812793a75373447d487aa4", + "sha256:f5315a2eb0239185af1bddb1abf472d877fede3cc8d143c6cddad37678293237", + "sha256:fa0ffcace9b3aa34d205d8130f7873fcfefcb6a4dd3dd705b0dab69af6712642", + "sha256:fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578" ], "index": "pypi", - "version": "==3.7.4.post0" + "version": "==3.8.1" + }, + "aiosignal": { + "hashes": [ + "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a", + "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2" + ], + "markers": "python_version >= '3.6'", + "version": "==1.2.0" }, "async-timeout": { "hashes": [ - "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", - "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" + "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", + "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" ], - "markers": "python_full_version >= '3.5.3'", - "version": "==3.0.1" + "markers": "python_version >= '3.6'", + "version": "==4.0.2" }, "attrs": { "hashes": [ @@ -73,83 +116,13 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==21.4.0" }, - "cairocffi": { + "charset-normalizer": { "hashes": [ - "sha256:108a3a7cb09e203bdd8501d9baad91d786d204561bd71e9364e8b34897c47b91" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.0" - }, - "cairosvg": { - "hashes": [ - "sha256:98c276b7e4f0caf01e5c7176765c104ffa1aa1461d63b2053b04ab663cf7052b", - "sha256:b0b9929cf5dba005178d746a8036fcf0025550f498ca54db61873322384783bc" + "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", + "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" ], "markers": "python_version >= '3.5'", - "version": "==2.5.2" - }, - "cffi": { - "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "version": "==1.15.0" - }, - "chardet": { - "hashes": [ - "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", - "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.0.0" + "version": "==2.0.12" }, "colorama": { "hashes": [ @@ -159,22 +132,6 @@ "index": "pypi", "version": "==0.4.4" }, - "cssselect2": { - "hashes": [ - "sha256:3a83b2a68370c69c9cd3fcb88bbfaebe9d22edeef2c22d1ff3e1ed9c7fa45ed8", - "sha256:5b5d6dea81a5eb0c9ca39f116c8578dd413778060c94c1f51196371618909325" - ], - "markers": "python_version >= '3.7'", - "version": "==0.6.0" - }, - "defusedxml": { - "hashes": [ - "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", - "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.7.1" - }, "discord-py": { "git": "https://github.com/Rapptz/discord.py.git", "ref": "a14b43f2fda863ed6555374eb872bf014bdd1adf" @@ -193,11 +150,75 @@ }, "emoji": { "hashes": [ - "sha256:496f432058567985838c13d67dde84ca081614a8286c0b9cdc7d63dfa89d51a3", - "sha256:6b19b65da8d6f30551eead1705539cc0eadcd9e33a6ecbc421a29b87f96287eb" + "sha256:65c54533ea3c78f30d0729288998715f418d7467de89ec258a31c0ce8660a1d1" ], "index": "pypi", - "version": "==1.2.0" + "version": "==1.7.0" + }, + "frozenlist": { + "hashes": [ + "sha256:006d3595e7d4108a12025ddf415ae0f6c9e736e726a5db0183326fd191b14c5e", + "sha256:01a73627448b1f2145bddb6e6c2259988bb8aee0fb361776ff8604b99616cd08", + "sha256:03a7dd1bfce30216a3f51a84e6dd0e4a573d23ca50f0346634916ff105ba6e6b", + "sha256:0437fe763fb5d4adad1756050cbf855bbb2bf0d9385c7bb13d7a10b0dd550486", + "sha256:04cb491c4b1c051734d41ea2552fde292f5f3a9c911363f74f39c23659c4af78", + "sha256:0c36e78b9509e97042ef869c0e1e6ef6429e55817c12d78245eb915e1cca7468", + "sha256:25af28b560e0c76fa41f550eacb389905633e7ac02d6eb3c09017fa1c8cdfde1", + "sha256:2fdc3cd845e5a1f71a0c3518528bfdbfe2efaf9886d6f49eacc5ee4fd9a10953", + "sha256:30530930410855c451bea83f7b272fb1c495ed9d5cc72895ac29e91279401db3", + "sha256:31977f84828b5bb856ca1eb07bf7e3a34f33a5cddce981d880240ba06639b94d", + "sha256:3c62964192a1c0c30b49f403495911298810bada64e4f03249ca35a33ca0417a", + "sha256:3f7c935c7b58b0d78c0beea0c7358e165f95f1fd8a7e98baa40d22a05b4a8141", + "sha256:40dff8962b8eba91fd3848d857203f0bd704b5f1fa2b3fc9af64901a190bba08", + "sha256:40ec383bc194accba825fbb7d0ef3dda5736ceab2375462f1d8672d9f6b68d07", + "sha256:436496321dad302b8b27ca955364a439ed1f0999311c393dccb243e451ff66aa", + "sha256:4406cfabef8f07b3b3af0f50f70938ec06d9f0fc26cbdeaab431cbc3ca3caeaa", + "sha256:45334234ec30fc4ea677f43171b18a27505bfb2dba9aca4398a62692c0ea8868", + "sha256:47be22dc27ed933d55ee55845d34a3e4e9f6fee93039e7f8ebadb0c2f60d403f", + "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b", + "sha256:4eda49bea3602812518765810af732229b4291d2695ed24a0a20e098c45a707b", + "sha256:57f4d3f03a18facacb2a6bcd21bccd011e3b75d463dc49f838fd699d074fabd1", + "sha256:603b9091bd70fae7be28bdb8aa5c9990f4241aa33abb673390a7f7329296695f", + "sha256:65bc6e2fece04e2145ab6e3c47428d1bbc05aede61ae365b2c1bddd94906e478", + "sha256:691ddf6dc50480ce49f68441f1d16a4c3325887453837036e0fb94736eae1e58", + "sha256:6983a31698490825171be44ffbafeaa930ddf590d3f051e397143a5045513b01", + "sha256:6a202458d1298ced3768f5a7d44301e7c86defac162ace0ab7434c2e961166e8", + "sha256:6eb275c6385dd72594758cbe96c07cdb9bd6becf84235f4a594bdf21e3596c9d", + "sha256:754728d65f1acc61e0f4df784456106e35afb7bf39cfe37227ab00436fb38676", + "sha256:768efd082074bb203c934e83a61654ed4931ef02412c2fbdecea0cff7ecd0274", + "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab", + "sha256:871d42623ae15eb0b0e9df65baeee6976b2e161d0ba93155411d58ff27483ad8", + "sha256:88aafd445a233dbbf8a65a62bc3249a0acd0d81ab18f6feb461cc5a938610d24", + "sha256:8c905a5186d77111f02144fab5b849ab524f1e876a1e75205cd1386a9be4b00a", + "sha256:8cf829bd2e2956066dd4de43fd8ec881d87842a06708c035b37ef632930505a2", + "sha256:92e650bd09b5dda929523b9f8e7f99b24deac61240ecc1a32aeba487afcd970f", + "sha256:93641a51f89473837333b2f8100f3f89795295b858cd4c7d4a1f18e299dc0a4f", + "sha256:94c7a8a9fc9383b52c410a2ec952521906d355d18fccc927fca52ab575ee8b93", + "sha256:9f892d6a94ec5c7b785e548e42722e6f3a52f5f32a8461e82ac3e67a3bd073f1", + "sha256:acb267b09a509c1df5a4ca04140da96016f40d2ed183cdc356d237286c971b51", + "sha256:adac9700675cf99e3615eb6a0eb5e9f5a4143c7d42c05cea2e7f71c27a3d0846", + "sha256:aff388be97ef2677ae185e72dc500d19ecaf31b698986800d3fc4f399a5e30a5", + "sha256:b5009062d78a8c6890d50b4e53b0ddda31841b3935c1937e2ed8c1bda1c7fb9d", + "sha256:b684c68077b84522b5c7eafc1dc735bfa5b341fb011d5552ebe0968e22ed641c", + "sha256:b9e3e9e365991f8cc5f5edc1fd65b58b41d0514a6a7ad95ef5c7f34eb49b3d3e", + "sha256:bd89acd1b8bb4f31b47072615d72e7f53a948d302b7c1d1455e42622de180eae", + "sha256:bde99812f237f79eaf3f04ebffd74f6718bbd216101b35ac7955c2d47c17da02", + "sha256:c6c321dd013e8fc20735b92cb4892c115f5cdb82c817b1e5b07f6b95d952b2f0", + "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b", + "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3", + "sha256:d26b650b71fdc88065b7a21f8ace70175bcf3b5bdba5ea22df4bfd893e795a3b", + "sha256:d6d32ff213aef0fd0bcf803bffe15cfa2d4fde237d1d4838e62aec242a8362fa", + "sha256:e1e26ac0a253a2907d654a37e390904426d5ae5483150ce3adedb35c8c06614a", + "sha256:e30b2f9683812eb30cf3f0a8e9f79f8d590a7999f731cf39f9105a7c4a39489d", + "sha256:e84cb61b0ac40a0c3e0e8b79c575161c5300d1d89e13c0e02f76193982f066ed", + "sha256:e982878792c971cbd60ee510c4ee5bf089a8246226dea1f2138aa0bb67aff148", + "sha256:f20baa05eaa2bcd5404c445ec51aed1c268d62600362dc6cfe04fae34a424bd9", + "sha256:f7353ba3367473d1d616ee727945f439e027f0bb16ac1a750219a8344d1d5d3c", + "sha256:f96293d6f982c58ebebb428c50163d010c2f05de0cde99fd681bfdc18d4b2dc2", + "sha256:ff9310f05b9d9c5c4dd472983dc956901ee6cb2c3ec1ab116ecdde25f3ce4951" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0" }, "idna": { "hashes": [ @@ -216,22 +237,20 @@ "version": "==0.6.1" }, "lottie": { - "extras": [ - "pdf" - ], + "extras": [], "hashes": [ - "sha256:d3281d09a8db94da49f60267123b9e0473e3a51c282da2d5e61908d33843f1cc" + "sha256:d53e96265887aa9187c7c707fd612b3d52f38da64c81ea82297783efb47f7e3f" ], "index": "pypi", - "version": "==0.6.10" + "version": "==0.6.11" }, "motor": { "hashes": [ - "sha256:1196db507142ef8f00d953efa2f37b39335ef2d72af6ce4fbccfd870b65c5e9f", - "sha256:839c11a43897dbec8e5ba0e87a9c9b877239803126877b2efa5cef89aa6b687a" + "sha256:663473f4498f955d35db7b6f25651cb165514c247136f368b84419cb7635f6b8", + "sha256:961fdceacaae2c7236c939166f66415be81be8bbb762da528386738de3a0f509" ], "index": "pypi", - "version": "==2.4.0" + "version": "==2.5.1" }, "multidict": { "hashes": [ @@ -313,61 +332,8 @@ "index": "pypi", "version": "==2.6" }, - "pillow": { - "hashes": [ - "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e", - "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595", - "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512", - "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c", - "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477", - "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a", - "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4", - "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e", - "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5", - "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378", - "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a", - "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652", - "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7", - "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a", - "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a", - "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6", - "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165", - "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160", - "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331", - "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b", - "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458", - "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033", - "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8", - "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481", - "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58", - "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7", - "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3", - "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea", - "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34", - "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3", - "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8", - "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581", - "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244", - "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef", - "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0", - "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2", - "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97", - "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717" - ], - "markers": "python_version >= '3.7'", - "version": "==9.1.0" - }, - "pycparser": { - "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" - ], - "version": "==2.21" - }, "pymongo": { - "extras": [ - "srv" - ], + "extras": [], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -490,11 +456,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:dd8fe852847f4fbfadabf6183ddd4c824a9651f02d51714fa075c95561959c7d", - "sha256:effaac3c1e58d89b3ccb4d04a40dc7ad6e0275fda25fd75ae9d323e2465e202d" + "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f", + "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938" ], "index": "pypi", - "version": "==0.18.0" + "version": "==0.20.0" }, "six": { "hashes": [ @@ -504,22 +470,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, - "tinycss2": { - "hashes": [ - "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf", - "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8" - ], - "markers": "python_version >= '3.6'", - "version": "==1.1.1" - }, - "typing-extensions": { - "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" - ], - "markers": "python_version >= '3.7'", - "version": "==4.2.0" - }, "uvloop": { "hashes": [ "sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450", @@ -542,13 +492,6 @@ "markers": "sys_platform != 'win32'", "version": "==0.16.0" }, - "webencodings": { - "hashes": [ - "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", - "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" - ], - "version": "==0.5.1" - }, "yarl": { "hashes": [ "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac", From ab8662b9b5625f2fbc1792252dc7c2851deb6ae3 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 23:02:29 +0800 Subject: [PATCH 530/705] complete deps --- Pipfile | 1 + Pipfile.lock | 15 ++++++++++++--- requirements.txt | 28 ++++++++++------------------ 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Pipfile b/Pipfile index 99d50e47e4..15e7bec22a 100644 --- a/Pipfile +++ b/Pipfile @@ -22,6 +22,7 @@ python-dateutil = "~=2.8.1" python-dotenv = "==0.20.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} lottie = "==0.6.11" +typing-extensions = "==4.2.0" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 3ce9602d5e..5b55df924e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "dea4d7675ab1e4a2c4d3f4f8ddcff27db7c0b3851a37e598b10dc429c2eaa5df" + "sha256": "8fca2257520573284e4ecaa536309d9e21bee280144e019b7ed97eae0160deee" }, "pipfile-spec": 6, "requires": {}, @@ -237,7 +237,6 @@ "version": "==0.6.1" }, "lottie": { - "extras": [], "hashes": [ "sha256:d53e96265887aa9187c7c707fd612b3d52f38da64c81ea82297783efb47f7e3f" ], @@ -333,7 +332,9 @@ "version": "==2.6" }, "pymongo": { - "extras": [], + "extras": [ + "srv" + ], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -470,6 +471,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, + "typing-extensions": { + "hashes": [ + "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", + "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + ], + "index": "pypi", + "version": "==4.2.0" + }, "uvloop": { "hashes": [ "sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450", diff --git a/requirements.txt b/requirements.txt index ecff8c80c8..f17ff47f04 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,35 +6,27 @@ # -i https://pypi.org/simple - -aiohttp==3.7.4.post0 -async-timeout==3.0.1; python_full_version >= '3.5.3' +aiohttp==3.8.1 +aiosignal==1.2.0; python_version >= '3.6' +async-timeout==4.0.2; python_version >= '3.6' attrs==21.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -cairocffi==1.3.0; python_version >= '3.7' -cairosvg==2.5.2; python_version >= '3.5' -cffi==1.15.0 -chardet==4.0.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +charset-normalizer==2.0.12; python_version >= '3.5' colorama==0.4.4 -cssselect2==0.6.0; python_version >= '3.7' -defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -emoji==1.2.0 +emoji==1.7.0 +frozenlist==1.3.0; python_version >= '3.7' git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord.py idna==3.3; python_version >= '3.5' isodate==0.6.1 -lottie[pdf]==0.6.10 -motor==2.4.0 +lottie==0.6.11 +motor==2.5.1 multidict==6.0.2; python_version >= '3.7' natural==0.2.0 parsedatetime==2.6 -pillow==9.1.0; python_version >= '3.7' -pycparser==2.21 pymongo[srv]==3.12.3 python-dateutil==2.8.2 -python-dotenv==0.18.0 +python-dotenv==0.20.0 six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -tinycss2==1.1.1; python_version >= '3.6' -typing-extensions==4.2.0; python_version >= '3.7' +typing-extensions==4.2.0 uvloop==0.16.0; sys_platform != 'win32' -webencodings==0.5.1 yarl==1.7.2; python_version >= '3.6' From 99a6a5ed917ccc11d6cd3e04db2c5c3f55e42925 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 23:06:37 +0800 Subject: [PATCH 531/705] Fix lottie req & bump ver --- Pipfile | 2 +- Pipfile.lock | 160 +++++++++++++++++++++++++++++++++++++++++++++-- bot.py | 2 +- pyproject.toml | 2 +- requirements.txt | 16 ++++- 5 files changed, 172 insertions(+), 10 deletions(-) diff --git a/Pipfile b/Pipfile index 15e7bec22a..6d1693e1a4 100644 --- a/Pipfile +++ b/Pipfile @@ -21,7 +21,7 @@ pymongo = {extras = ["srv"], version = "*"} # Required by motor python-dateutil = "~=2.8.1" python-dotenv = "==0.20.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} -lottie = "==0.6.11" +lottie = {version = "==0.6.11", extras = ["pdf"]} typing-extensions = "==4.2.0" [scripts] diff --git a/Pipfile.lock b/Pipfile.lock index 5b55df924e..c0ceed0b44 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8fca2257520573284e4ecaa536309d9e21bee280144e019b7ed97eae0160deee" + "sha256": "2d6a4df6161cc1c6fb1c60ceb7bc39d5c4d5a7371564b1b8c2a517c22685d56c" }, "pipfile-spec": 6, "requires": {}, @@ -116,6 +116,75 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==21.4.0" }, + "cairocffi": { + "hashes": [ + "sha256:108a3a7cb09e203bdd8501d9baad91d786d204561bd71e9364e8b34897c47b91" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0" + }, + "cairosvg": { + "hashes": [ + "sha256:98c276b7e4f0caf01e5c7176765c104ffa1aa1461d63b2053b04ab663cf7052b", + "sha256:b0b9929cf5dba005178d746a8036fcf0025550f498ca54db61873322384783bc" + ], + "version": "==2.5.2" + }, + "cffi": { + "hashes": [ + "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", + "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", + "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", + "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", + "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", + "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", + "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", + "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", + "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", + "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", + "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", + "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", + "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", + "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", + "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", + "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", + "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", + "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", + "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", + "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", + "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", + "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", + "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", + "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", + "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", + "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", + "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", + "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", + "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", + "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", + "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", + "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", + "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", + "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", + "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", + "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", + "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", + "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", + "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", + "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", + "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", + "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", + "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", + "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", + "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", + "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", + "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", + "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", + "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", + "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" + ], + "version": "==1.15.0" + }, "charset-normalizer": { "hashes": [ "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", @@ -132,6 +201,22 @@ "index": "pypi", "version": "==0.4.4" }, + "cssselect2": { + "hashes": [ + "sha256:3a83b2a68370c69c9cd3fcb88bbfaebe9d22edeef2c22d1ff3e1ed9c7fa45ed8", + "sha256:5b5d6dea81a5eb0c9ca39f116c8578dd413778060c94c1f51196371618909325" + ], + "markers": "python_version >= '3.7'", + "version": "==0.6.0" + }, + "defusedxml": { + "hashes": [ + "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", + "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.7.1" + }, "discord-py": { "git": "https://github.com/Rapptz/discord.py.git", "ref": "a14b43f2fda863ed6555374eb872bf014bdd1adf" @@ -237,6 +322,9 @@ "version": "==0.6.1" }, "lottie": { + "extras": [ + "pdf" + ], "hashes": [ "sha256:d53e96265887aa9187c7c707fd612b3d52f38da64c81ea82297783efb47f7e3f" ], @@ -331,10 +419,59 @@ "index": "pypi", "version": "==2.6" }, - "pymongo": { - "extras": [ - "srv" + "pillow": { + "hashes": [ + "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e", + "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595", + "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512", + "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c", + "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477", + "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a", + "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4", + "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e", + "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5", + "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378", + "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a", + "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652", + "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7", + "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a", + "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a", + "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6", + "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165", + "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160", + "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331", + "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b", + "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458", + "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033", + "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8", + "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481", + "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58", + "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7", + "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3", + "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea", + "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34", + "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3", + "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8", + "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581", + "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244", + "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef", + "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0", + "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2", + "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97", + "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717" ], + "markers": "python_version >= '3.7'", + "version": "==9.1.0" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "version": "==2.21" + }, + "pymongo": { + "extras": [], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -471,6 +608,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, + "tinycss2": { + "hashes": [ + "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf", + "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8" + ], + "markers": "python_version >= '3.6'", + "version": "==1.1.1" + }, "typing-extensions": { "hashes": [ "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", @@ -501,6 +646,13 @@ "markers": "sys_platform != 'win32'", "version": "==0.16.0" }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, "yarl": { "hashes": [ "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac", diff --git a/bot.py b/bot.py index 4fb57f1886..55670607fe 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev10" +__version__ = "4.0.0-dev11" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 9d08c1d2b2..80217af8fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev10' +version = '4.0.0-dev11' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ diff --git a/requirements.txt b/requirements.txt index f17ff47f04..541a8411c2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,23 +10,33 @@ aiohttp==3.8.1 aiosignal==1.2.0; python_version >= '3.6' async-timeout==4.0.2; python_version >= '3.6' attrs==21.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -charset-normalizer==2.0.12; python_version >= '3.5' +cairocffi==1.3.0; python_version >= '3.7' +cairosvg==2.5.2 +cffi==1.15.0 +charset-normalizer==2.0.12; python_version >= '3.5' colorama==0.4.4 +cssselect2==0.6.0; python_version >= '3.7' +defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.7.0 frozenlist==1.3.0; python_version >= '3.7' +git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord-py git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord.py idna==3.3; python_version >= '3.5' isodate==0.6.1 -lottie==0.6.11 +lottie[pdf]==0.6.11 motor==2.5.1 multidict==6.0.2; python_version >= '3.7' natural==0.2.0 parsedatetime==2.6 -pymongo[srv]==3.12.3 +pillow==9.1.0; python_version >= '3.7' +pycparser==2.21 +pymongo==3.12.3 python-dateutil==2.8.2 python-dotenv==0.20.0 six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +tinycss2==1.1.1; python_version >= '3.6' typing-extensions==4.2.0 uvloop==0.16.0; sys_platform != 'win32' +webencodings==0.5.1 yarl==1.7.2; python_version >= '3.6' From c6ed564db714c3296a74046ac98df2ef27bcc2c8 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 23:17:51 +0800 Subject: [PATCH 532/705] shift to devpkgs --- Pipfile | 2 +- Pipfile.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Pipfile b/Pipfile index 6d1693e1a4..e9b1e58f76 100644 --- a/Pipfile +++ b/Pipfile @@ -7,6 +7,7 @@ verify_ssl = true bandit = "~=1.7.0" black = "==22.3.0" pylint = "~=2.9.3" +typing-extensions = "==4.2.0" [packages] aiohttp = "==3.8.1" @@ -22,7 +23,6 @@ python-dateutil = "~=2.8.1" python-dotenv = "==0.20.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} lottie = {version = "==0.6.11", extras = ["pdf"]} -typing-extensions = "==4.2.0" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index c0ceed0b44..8dff48027a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2d6a4df6161cc1c6fb1c60ceb7bc39d5c4d5a7371564b1b8c2a517c22685d56c" + "sha256": "b6bc030eedf7606f6ceeda324e896c29d5771108afa224c712d4c92d81875899" }, "pipfile-spec": 6, "requires": {}, @@ -616,14 +616,6 @@ "markers": "python_version >= '3.6'", "version": "==1.1.1" }, - "typing-extensions": { - "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" - ], - "index": "pypi", - "version": "==4.2.0" - }, "uvloop": { "hashes": [ "sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450", @@ -985,6 +977,14 @@ "markers": "python_version < '3.11'", "version": "==2.0.1" }, + "typing-extensions": { + "hashes": [ + "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", + "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + ], + "index": "pypi", + "version": "==4.2.0" + }, "wrapt": { "hashes": [ "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" From fff100dd11ee259f1897d2864e8ad03bac58ca97 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Thu, 28 Apr 2022 23:19:11 +0800 Subject: [PATCH 533/705] update reqs.txt --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 541a8411c2..e7223057ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,6 @@ defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.7.0 frozenlist==1.3.0; python_version >= '3.7' -git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord-py git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord.py idna==3.3; python_version >= '3.5' isodate==0.6.1 @@ -36,7 +35,6 @@ python-dateutil==2.8.2 python-dotenv==0.20.0 six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' tinycss2==1.1.1; python_version >= '3.6' -typing-extensions==4.2.0 uvloop==0.16.0; sys_platform != 'win32' webencodings==0.5.1 yarl==1.7.2; python_version >= '3.6' From 17b2f89e9ae402b27516c86562a7d67c0008ed7f Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:23:47 +0800 Subject: [PATCH 534/705] add use_random_channel_name, resolve #3143 --- CHANGELOG.md | 1 + bot.py | 9 +++++++-- core/config.py | 2 ++ core/config_help.json | 25 +++++++++++++++++++------ pyproject.toml | 2 +- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e97b127b95..fa5d0ad75a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/kyb3r/modmail/issues/3083)) - `?fpareply` and `?fpreply` to reply to messages with variables plainly. - `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/kyb3r/modmail/issues/3112)) +- `use_random_channel_name` config to use random nicknames vaguely tied to user ID. It is unable to be computed in reverse. ([GH #3143](https://github.com/kyb3r/modmail/issues/3143) - `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/kyb3r/modmail/issues/3122)) - Select menus for certain paginators. - `Title` field in `?logs`. ([GH #3142](https://github.com/kyb3r/modmail/issues/3142)) diff --git a/bot.py b/bot.py index 55670607fe..bcd6acfee9 100644 --- a/bot.py +++ b/bot.py @@ -1,8 +1,9 @@ -__version__ = "4.0.0-dev11" +__version__ = "4.0.0-dev12" import asyncio import copy +import hashlib import logging import os import re @@ -1690,7 +1691,11 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): if force_null: name = new_name = "null" else: - if self.config["use_user_id_channel_name"]: + if self.config["use_random_channel_name"]: + to_hash = self.token.split(".")[-1] + str(author.id) + digest = hashlib.md5(to_hash.encode("utf8")) + name = new_name = digest.hexdigest()[-8:] + elif self.config["use_user_id_channel_name"]: name = new_name = str(author.id) elif self.config["use_timestamp_channel_name"]: name = new_name = author.created_at.isoformat(sep="-", timespec="minutes") diff --git a/core/config.py b/core/config.py index 14f86ecd2e..6cff7f0bd7 100644 --- a/core/config.py +++ b/core/config.py @@ -53,6 +53,7 @@ class ConfigManager: "use_user_id_channel_name": False, "use_timestamp_channel_name": False, "use_nickname_channel_name": False, + "use_random_channel_name": False, "recipient_thread_close": False, "thread_show_roles": True, "thread_show_account_age": True, @@ -187,6 +188,7 @@ class ConfigManager: "use_user_id_channel_name", "use_timestamp_channel_name", "use_nickname_channel_name", + "use_random_channel_name", "user_typing", "mod_typing", "reply_without_command", diff --git a/core/config_help.json b/core/config_help.json index 342652456d..e7ebb9590d 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -106,8 +106,8 @@ ], "notes": [ "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", - "This cannot be applied with `use_timestamp_channel_name` or `use_nickname_channel_name`.", - "See also: `use_timestamp_channel_name`, `use_nickname_channel_name`." + "This cannot be applied with `use_timestamp_channel_name`, `use_random_channel_name` or `use_nickname_channel_name`.", + "See also: `use_timestamp_channel_name`, `use_nickname_channel_name`, `use_random_channel_name`." ] }, "use_timestamp_channel_name": { @@ -119,8 +119,8 @@ ], "notes": [ "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", - "This cannot be applied with `use_user_id_channel_name` or `use_nickname_channel_name`.", - "See also: `use_user_id_channel_name`, `use_nickname_channel_name`." + "This cannot be applied with `use_user_id_channel_name`, `use_random_channel_name` or `use_nickname_channel_name`.", + "See also: `use_user_id_channel_name`, `use_nickname_channel_name`, `use_random_channel_name`." ] }, "use_nickname_channel_name": { @@ -132,8 +132,21 @@ ], "notes": [ "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", - "This cannot be applied with `use_timestamp_channel_name` or `use_user_id_channel_name`.", - "See also: `use_timestamp_channel_name`, `use_user_id_channel_name`." + "This cannot be applied with `use_timestamp_channel_name`, `use_random_channel_name` or `use_user_id_channel_name`.", + "See also: `use_timestamp_channel_name`, `use_user_id_channel_name`, `use_random_channel_name`." + ] + }, + "use_random_channel_name": { + "default": "No", + "description": "When this is set to `yes`, new thread channels will be named with random characters tied to their user ID.", + "examples": [ + "`{prefix}config set use_random_channel_name yes`", + "`{prefix}config set use_random_channel_name no`" + ], + "notes": [ + "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", + "This cannot be applied with `use_timestamp_channel_name`, `use_nickname_channel_name`, or `use_user_id_channel_name`.", + "See also: `use_timestamp_channel_name`, `use_user_id_channel_name`, `use_nickname_channel_name`." ] }, "mod_typing": { diff --git a/pyproject.toml b/pyproject.toml index 80217af8fb..aafdcd0d49 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev11' +version = '4.0.0-dev12' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 2214cbe1b7a79895367292b43d27965ed9d3242c Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:33:41 +0800 Subject: [PATCH 535/705] bump dpy@e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd --- Pipfile | 2 +- Pipfile.lock | 20 +++++++++++--------- requirements.txt | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Pipfile b/Pipfile index e9b1e58f76..88d49f59fd 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ typing-extensions = "==4.2.0" [packages] aiohttp = "==3.8.1" colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 -"discord.py" = {ref = "a14b43f2fda863ed6555374eb872bf014bdd1adf", git = "https://github.com/Rapptz/discord.py.git"} +"discord.py" = {ref = "e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd", git = "https://github.com/Rapptz/discord.py.git"} emoji = "==1.7.0" isodate = "~=0.6.0" motor = "==2.5.1" diff --git a/Pipfile.lock b/Pipfile.lock index 8dff48027a..163d09bdcd 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b6bc030eedf7606f6ceeda324e896c29d5771108afa224c712d4c92d81875899" + "sha256": "4035fc1c98c21d437f41fcd2f32ca38089131e4a60ef0f4453caf4019dae7bd3" }, "pipfile-spec": 6, "requires": {}, @@ -190,7 +190,7 @@ "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" ], - "markers": "python_version >= '3.5'", + "markers": "python_full_version >= '3.5.0'", "version": "==2.0.12" }, "colorama": { @@ -219,11 +219,11 @@ }, "discord-py": { "git": "https://github.com/Rapptz/discord.py.git", - "ref": "a14b43f2fda863ed6555374eb872bf014bdd1adf" + "ref": "e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd" }, "discord.py": { "git": "https://github.com/Rapptz/discord.py.git", - "ref": "a14b43f2fda863ed6555374eb872bf014bdd1adf" + "ref": "e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd" }, "dnspython": { "hashes": [ @@ -310,7 +310,7 @@ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_version >= '3.5'", + "markers": "python_full_version >= '3.5.0'", "version": "==3.3" }, "isodate": { @@ -471,7 +471,9 @@ "version": "==2.21" }, "pymongo": { - "extras": [], + "extras": [ + "srv" + ], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -772,11 +774,11 @@ }, "click": { "hashes": [ - "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e", - "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72" + "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", + "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" ], "markers": "python_version >= '3.7'", - "version": "==8.1.2" + "version": "==8.1.3" }, "colorama": { "hashes": [ diff --git a/requirements.txt b/requirements.txt index e7223057ad..edc784029b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,7 @@ defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.7.0 frozenlist==1.3.0; python_version >= '3.7' -git+https://github.com/Rapptz/discord.py.git@a14b43f2fda863ed6555374eb872bf014bdd1adf#egg=discord.py +git+https://github.com/Rapptz/discord.py.git@e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd#egg=discord.py idna==3.3; python_version >= '3.5' isodate==0.6.1 lottie[pdf]==0.6.11 From 97c70bfb475cccd2453d8e73486e377f26706920 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:40:00 +0800 Subject: [PATCH 536/705] fix typing --- bot.py | 6 +++--- cogs/modmail.py | 4 ++-- core/thread.py | 2 +- core/utils.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bot.py b/bot.py index bcd6acfee9..c8eb75512c 100644 --- a/bot.py +++ b/bot.py @@ -1227,7 +1227,7 @@ async def on_typing(self, channel, user, _): thread = await self.threads.find(recipient=user) if thread: - await thread.channel.trigger_typing() + await thread.channel.typing() else: if not self.config.get("mod_typing"): return @@ -1237,7 +1237,7 @@ async def on_typing(self, channel, user, _): for user in thread.recipients: if await self.is_blocked(user): continue - await user.trigger_typing() + await user.typing() async def handle_reaction_events(self, payload): user = self.get_user(payload.user_id) @@ -1508,7 +1508,7 @@ async def on_error(self, event_method, *args, **kwargs): async def on_command_error(self, context, exception): if isinstance(exception, (commands.BadArgument, commands.BadUnionArgument)): - await context.trigger_typing() + await context.typing() await context.send(embed=discord.Embed(color=self.error_color, description=str(exception))) elif isinstance(exception, commands.CommandNotFound): logger.warning("CommandNotFound: %s", exception) diff --git a/cogs/modmail.py b/cogs/modmail.py index bb8c90e29e..f1c6c20ee8 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1158,7 +1158,7 @@ async def logs(self, ctx, *, user: User = None): `user` may be a user ID, mention, or name. """ - await ctx.trigger_typing() + await ctx.typing() if not user: thread = ctx.thread @@ -1268,7 +1268,7 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): Provide a `limit` to specify the maximum number of logs the bot should find. """ - await ctx.trigger_typing() + await ctx.typing() entries = await self.bot.api.search_by_text(query, limit) diff --git a/core/thread.py b/core/thread.py index 7edfbc1d39..e39076d702 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1134,7 +1134,7 @@ def lottie_to_png(data): logger.info("Sending a message to %s when DM disabled is set.", self.recipient) try: - await destination.trigger_typing() + await destination.typing() except discord.NotFound: logger.warning("Channel not found.") raise diff --git a/core/utils.py b/core/utils.py index 9b56cbe31d..425b245511 100644 --- a/core/utils.py +++ b/core/utils.py @@ -397,8 +397,8 @@ def format_description(i, names): def trigger_typing(func): @functools.wraps(func) async def wrapper(self, ctx: commands.Context, *args, **kwargs): - await ctx.trigger_typing() - return await func(self, ctx, *args, **kwargs) + async with ctx.typing(): + return await func(self, ctx, *args, **kwargs) return wrapper From afb9e3a935c5fe6c11911d2c4a7f1202be6e0a19 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:40:42 +0800 Subject: [PATCH 537/705] remove deprecated decorators.py --- core/decorators.py | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 core/decorators.py diff --git a/core/decorators.py b/core/decorators.py deleted file mode 100644 index 0107a6b2d6..0000000000 --- a/core/decorators.py +++ /dev/null @@ -1,12 +0,0 @@ -import warnings - -from core.utils import trigger_typing as _trigger_typing - - -def trigger_typing(func): - warnings.warn( - "trigger_typing has been moved to core.utils.trigger_typing, this will be removed.", - DeprecationWarning, - stacklevel=2, - ) - return _trigger_typing(func) From 8d1e4f70fed97f9f49526d24290c3481597a76e7 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:41:30 +0800 Subject: [PATCH 538/705] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa5d0ad75a..f592f3278c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Bump emoji to v1.7.0 - Bump aiohttp to v3.8.1 - Bump lottie to v0.6.11 +- Remove deprecated `core/decorators.py` from v3.3.0 # v3.10.3 From ecc92e4bbf44d0f44d2df902e16a30734320070e Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:48:20 +0800 Subject: [PATCH 539/705] fix <3.9 features --- bot.py | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index c8eb75512c..f1dc8b6b59 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev12" +__version__ = "4.0.0-dev13" import asyncio @@ -995,7 +995,7 @@ async def get_contexts(self, message, *, cls=commands.Context): # This needs to be done before checking for aliases since # snippets can have multiple words. try: - snippet_text = self.snippets[message.content.removeprefix(invoked_prefix)] + snippet_text = self.snippets[message.content.strip(invoked_prefix)] except KeyError: snippet_text = None diff --git a/pyproject.toml b/pyproject.toml index aafdcd0d49..c69f704341 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev12' +version = '4.0.0-dev13' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From e1efa8c2f65ba3c09a594604dba0c98eed942321 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:53:33 +0800 Subject: [PATCH 540/705] update jobs to cover 3.7-3.10 and all platforms --- .github/workflows/lints.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 091e012dd9..1be351818e 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -5,20 +5,21 @@ on: [push, pull_request] jobs: code-style: -# runs-on: ${{ matrix.os }} -# strategy: -# fail-fast: false -# matrix: -# os: [ubuntu-latest, windows-latest, macOS-latest] -# python-version: [3.6, 3.7] + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + python-version: [3.7, 3.8, 3.9, 3.10] + + name: Python ${{ matrix.python-version }} Test - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.9 - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 with: - python-version: 3.9 + python-version: ${{ matrix.python-version }} + architecture: x64 - name: Install dependencies run: | python -m pip install --upgrade pip pipenv From 927fd37b0e4b8d6c76ed233968e38f0a8c860d70 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:56:04 +0800 Subject: [PATCH 541/705] fix linting file --- .github/workflows/lints.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 1be351818e..3ededb294a 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -4,12 +4,11 @@ on: [push, pull_request] jobs: code-style: - - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - python-version: [3.7, 3.8, 3.9, 3.10] + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + python-version: [3.7, 3.8, 3.9, 3.10] name: Python ${{ matrix.python-version }} Test From 0a7f86281aa327767d5168cb9b0ce541c4577343 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 22:57:27 +0800 Subject: [PATCH 542/705] fix lint gh-action --- .github/workflows/lints.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 3ededb294a..fddccac8f1 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -8,9 +8,9 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - python-version: [3.7, 3.8, 3.9, 3.10] + python-version: ['3.7', '3.8', '3.9', '3.10'] - name: Python ${{ matrix.python-version }} Test + name: Python ${{ matrix.python-version }} on ${{ matrix.os }} steps: - uses: actions/checkout@v3 From daa4ce7e357163c270c1f10ed5478b25e2f5b0a4 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 23:00:40 +0800 Subject: [PATCH 543/705] only formally support Python 3.8+ --- .github/workflows/lints.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index fddccac8f1..a7418930be 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - python-version: ['3.7', '3.8', '3.9', '3.10'] + python-version: ['3.8', '3.9', '3.10'] name: Python ${{ matrix.python-version }} on ${{ matrix.os }} diff --git a/README.md b/README.md index 4487438a5c..1558a04755 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ If you don't want to go through the trouble of setting up your very own Modmail ### Locally -Local hosting of Modmail is also possible. First, you will need [`Python 3.8`](https://www.python.org/downloads/release/python-376/). +Local hosting of Modmail is also possible. First, you will need at least [`Python 3.8`](https://www.python.org/downloads/release/python-376/). Follow the [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) and disregard deploying the Heroku bot application. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. From 5a32966c10b96c31febcdacfddbe851aed7f40b4 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 23:02:45 +0800 Subject: [PATCH 544/705] fix type annotation for PY3.8 --- cogs/modmail.py | 4 ++-- runtime.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 runtime.txt diff --git a/cogs/modmail.py b/cogs/modmail.py index f1c6c20ee8..a45b44e573 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -2,7 +2,7 @@ import re from datetime import datetime, timezone from itertools import zip_longest -from typing import Optional, Union +from typing import Optional, Union, List, Tuple from types import SimpleNamespace import discord @@ -249,7 +249,7 @@ async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_conte ) return await ctx.send(embed=embed) - def _fix_aliases(self, snippet_being_deleted: str) -> tuple[list[str]]: + def _fix_aliases(self, snippet_being_deleted: str) -> Tuple[List[str]]: """ Remove references to the snippet being deleted from aliases. diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 0000000000..30e81e3130 --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.10.3 From b8df285b6826d4f3d4dd59f3415ab0e228c564be Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 23:16:18 +0800 Subject: [PATCH 545/705] improve multi-page pagination dropdown and titles --- cogs/modmail.py | 33 +++++++++++++++++++++------------ cogs/utility.py | 8 ++++++-- core/utils.py | 4 ++-- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index a45b44e573..19a6842dc7 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1637,8 +1637,6 @@ async def contact( async def blocked(self, ctx): """Retrieve a list of blocked users.""" - embeds = [discord.Embed(title="Blocked Users", color=self.bot.main_color, description="")] - roles = [] users = [] now = ctx.message.created_at @@ -1700,43 +1698,54 @@ async def blocked(self, ctx): if role: roles.append((role.mention, reason)) + user_embeds = [discord.Embed(title="Blocked Users", color=self.bot.main_color, description="")] + if users: - embed = embeds[0] + embed = user_embeds[0] for mention, reason in users: line = mention + f" - {reason or 'No Reason Provided'}\n" if len(embed.description) + len(line) > 2048: embed = discord.Embed( - title="Blocked Users (Continued)", + title="Blocked Users", color=self.bot.main_color, description=line, ) - embeds.append(embed) + user_embeds.append(embed) else: embed.description += line else: - embeds[0].description = "Currently there are no blocked users." + user_embeds[0].description = "Currently there are no blocked users." + + if len(user_embeds) > 1: + for n, em in enumerate(user_embeds): + em.title = f'{em.title} [{n + 1}]' - embeds.append(discord.Embed(title="Blocked Roles", color=self.bot.main_color, description="")) + role_embeds = [discord.Embed(title="Blocked Roles", color=self.bot.main_color, description="")] if roles: - embed = embeds[-1] + embed = role_embeds[-1] for mention, reason in roles: line = mention + f" - {reason or 'No Reason Provided'}\n" if len(embed.description) + len(line) > 2048: + role_embeds[-1].set_author() embed = discord.Embed( - title="Blocked Roles (Continued)", + title="Blocked Roles", color=self.bot.main_color, description=line, ) - embeds.append(embed) + role_embeds.append(embed) else: embed.description += line else: - embeds[-1].description = "Currently there are no blocked roles." + role_embeds[-1].description = "Currently there are no blocked roles." - session = EmbedPaginatorSession(ctx, *embeds) + if len(role_embeds) > 1: + for n, em in enumerate(role_embeds): + em.title = f'{em.title} [{n + 1}]' + + session = EmbedPaginatorSession(ctx, *user_embeds, *role_embeds) await session.run() diff --git a/cogs/utility.py b/cogs/utility.py index 23827aa0c4..538ddc18e1 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -89,15 +89,19 @@ async def format_cog_help(self, cog, *, no_cog=False): embed.add_field(name="Commands", value=format_ or "No commands.") - continued = " (Continued)" if embeds else "" name = cog.qualified_name + " - Help" if not no_cog else "Miscellaneous Commands" - embed.set_author(name=name + continued, icon_url=bot.user.display_avatar.url) + embed.set_author(name=name, icon_url=bot.user.display_avatar.url) embed.set_footer( text=f'Type "{prefix}{self.command_attrs["name"]} command" ' "for more info on a specific command." ) embeds.append(embed) + + if len(embeds) > 1: + for n, em in enumerate(embeds): + em.set_author(name=f'{em.author.name} [{n + 1}]', icon_url=em.author.icon_url) + return embeds def process_help_msg(self, help_: str): diff --git a/core/utils.py b/core/utils.py index 425b245511..32f12c72e8 100644 --- a/core/utils.py +++ b/core/utils.py @@ -397,8 +397,8 @@ def format_description(i, names): def trigger_typing(func): @functools.wraps(func) async def wrapper(self, ctx: commands.Context, *args, **kwargs): - async with ctx.typing(): - return await func(self, ctx, *args, **kwargs) + await ctx.typing() + return await func(self, ctx, *args, **kwargs) return wrapper From 77489be6a21cf4befeab1dc7fa2c2d2098104cbc Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 23:16:44 +0800 Subject: [PATCH 546/705] bump version --- bot.py | 2 +- cogs/modmail.py | 4 ++-- cogs/utility.py | 2 +- pyproject.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index f1dc8b6b59..a506addfd9 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev13" +__version__ = "4.0.0-dev14" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index 19a6842dc7..deb29d160d 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1719,7 +1719,7 @@ async def blocked(self, ctx): if len(user_embeds) > 1: for n, em in enumerate(user_embeds): - em.title = f'{em.title} [{n + 1}]' + em.title = f"{em.title} [{n + 1}]" role_embeds = [discord.Embed(title="Blocked Roles", color=self.bot.main_color, description="")] @@ -1743,7 +1743,7 @@ async def blocked(self, ctx): if len(role_embeds) > 1: for n, em in enumerate(role_embeds): - em.title = f'{em.title} [{n + 1}]' + em.title = f"{em.title} [{n + 1}]" session = EmbedPaginatorSession(ctx, *user_embeds, *role_embeds) diff --git a/cogs/utility.py b/cogs/utility.py index 538ddc18e1..0e86934af2 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -100,7 +100,7 @@ async def format_cog_help(self, cog, *, no_cog=False): if len(embeds) > 1: for n, em in enumerate(embeds): - em.set_author(name=f'{em.author.name} [{n + 1}]', icon_url=em.author.icon_url) + em.set_author(name=f"{em.author.name} [{n + 1}]", icon_url=em.author.icon_url) return embeds diff --git a/pyproject.toml b/pyproject.toml index c69f704341..56f30163c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev13' +version = '4.0.0-dev14' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 454bdae898da6e431783b1f14d2ae8b51cdf2580 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 3 May 2022 23:31:10 +0800 Subject: [PATCH 547/705] fix typos --- CHANGELOG.md | 3 ++- cogs/utility.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f592f3278c..c096d05d7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/kyb3r/modmail/issues/3083)) - `?fpareply` and `?fpreply` to reply to messages with variables plainly. - `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/kyb3r/modmail/issues/3112)) -- `use_random_channel_name` config to use random nicknames vaguely tied to user ID. It is unable to be computed in reverse. ([GH #3143](https://github.com/kyb3r/modmail/issues/3143) +- `use_random_channel_name` config to use random nicknames vaguely tied to user ID. It is unable to be computed in reverse. ([GH #3143](https://github.com/kyb3r/modmail/issues/3143)) - `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/kyb3r/modmail/issues/3122)) - Select menus for certain paginators. - `Title` field in `?logs`. ([GH #3142](https://github.com/kyb3r/modmail/issues/3142)) @@ -33,6 +33,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/kyb3r/modmail/issues/3048)) - Use discord relative timedeltas. ([GH #3046](https://github.com/kyb3r/modmail/issues/3046)) - Use discord native buttons for all paginator sessions. +- `?help` and `?blocked` paginator sessions now have better multi-page UI. ### Fixed diff --git a/cogs/utility.py b/cogs/utility.py index 0e86934af2..0baa82cfcd 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -39,7 +39,7 @@ class ModmailHelpCommand(commands.HelpCommand): async def command_callback(self, ctx, *, command=None): - """Ovrwrites original command_callback to ensure `help` without any arguments + """Overwrites original command_callback to ensure `help` without any arguments returns with checks, `help all` returns without checks""" if command is None: self.verify_checks = True From e3571cdb3a75a27898c1622a3d78a8285f4cc90a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 4 May 2022 00:33:27 +0800 Subject: [PATCH 548/705] update gtk message --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index a506addfd9..14ac7b4d8f 100644 --- a/bot.py +++ b/bot.py @@ -1742,7 +1742,7 @@ def main(): ) else: logger.error( - "Unable to import cairosvg, install GTK Installer for Windows: https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/latest" + "Unable to import cairosvg, install GTK Installer for Windows and restart your system (https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/latest)" ) else: logger.error( From fa135eb53b278148fb411a2b1282c2fb28efad10 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <hidzrie@gmail.com> Date: Tue, 7 Jun 2022 00:52:22 +0000 Subject: [PATCH 549/705] Improve and error handling for update and autoupdate features. --- bot.py | 65 ++++++++++++++++++--------------- cogs/utility.py | 38 +++++++++++++------- core/clients.py | 96 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 136 insertions(+), 63 deletions(-) diff --git a/bot.py b/bot.py index a506addfd9..5db1aab550 100644 --- a/bot.py +++ b/bot.py @@ -17,7 +17,7 @@ import discord import isodate -from aiohttp import ClientSession +from aiohttp import ClientSession, ClientResponseError from discord.ext import commands, tasks from discord.ext.commands.view import StringView from emoji import UNICODE_EMOJI @@ -630,6 +630,8 @@ async def on_ready(self): ) logger.warning("If the external servers are valid, you may ignore this message.") + self.post_metadata.start() + self.autoupdate.start() self._started = True async def convert_emoji(self, name: str) -> str: @@ -1581,6 +1583,7 @@ async def before_post_metadata(self): await self.wait_for_connected() if not self.config.get("data_collection") or not self.guild: self.post_metadata.cancel() + return logger.debug("Starting metadata loop.") logger.line("debug") @@ -1591,44 +1594,50 @@ async def autoupdate(self): latest = changelog.latest_version if self.version < parse_version(latest.version): - if self.hosting_method == HostingMethod.HEROKU: + try: + # update fork if gh_token exists data = await self.api.update_repository() + except InvalidConfigError: + data = {} + except ClientResponseError as exc: + logger.error(f"Autoupdate failed! Status {exc.status}.") + logger.error(f"Message: {exc.message}") + self.autoupdate.cancel() + return + if self.hosting_method == HostingMethod.HEROKU: + commit_data = data.get("data") + if not commit_data: + return - embed = discord.Embed(color=self.main_color) + logger.info("Bot has been updated.") + + if not self.config["update_notifications"]: + return - commit_data = data["data"] + embed = discord.Embed(color=self.main_color) + message = commit_data["commit"]["message"] + html_url = commit_data["html_url"] + short_sha = commit_data["sha"][:6] user = data["user"] + embed.add_field( + name="Merge Commit", + value=f"[`{short_sha}`]({html_url}) " f"{message} - {user['username']}", + ) embed.set_author( name=user["username"] + " - Updating Bot", icon_url=user["avatar_url"], url=user["url"], ) - embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + embed.set_footer(text=f"Updating Modmail v{self.version} -> v{latest.version}") embed.description = latest.description for name, value in latest.fields.items(): embed.add_field(name=name, value=value) - if commit_data: - message = commit_data["commit"]["message"] - html_url = commit_data["html_url"] - short_sha = commit_data["sha"][:6] - embed.add_field( - name="Merge Commit", - value=f"[`{short_sha}`]({html_url}) " f"{message} - {user['username']}", - ) - logger.info("Bot has been updated.") - channel = self.log_channel - if self.config["update_notifications"]: - await channel.send(embed=embed) + channel = self.update_channel + await channel.send(embed=embed) else: - try: - # update fork if gh_token exists - await self.api.update_repository() - except InvalidConfigError: - pass - command = "git pull" proc = await asyncio.create_subprocess_shell( command, @@ -1642,7 +1651,7 @@ async def autoupdate(self): if err and not res: logger.warning(f"Autoupdate failed: {err}") - self.autoupdate_loop.cancel() + self.autoupdate.cancel() return elif res != "Already up to date.": @@ -1659,7 +1668,7 @@ async def autoupdate(self): description="If you do not have an auto-restart setup, please manually start the bot.", color=self.main_color, ) - embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + embed.set_footer(text=f"Updating Modmail v{self.version} -> v{latest.version}") if self.config["update_notifications"]: await channel.send(embed=embed) return await self.close() @@ -1671,16 +1680,16 @@ async def before_autoupdate(self): if self.config.get("disable_autoupdates"): logger.warning("Autoupdates disabled.") - self.autoupdate_loop.cancel() + self.autoupdate.cancel() if self.hosting_method == HostingMethod.DOCKER: logger.warning("Autoupdates disabled as using Docker.") - self.autoupdate_loop.cancel() + self.autoupdate.cancel() if not self.config.get("github_token") and self.hosting_method == HostingMethod.HEROKU: logger.warning("GitHub access token not found.") logger.warning("Autoupdates disabled.") - self.autoupdate_loop.cancel() + self.autoupdate.cancel() def format_channel_name(self, author, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names diff --git a/cogs/utility.py b/cogs/utility.py index 0e86934af2..5d35a20211 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1931,7 +1931,7 @@ async def github(self, ctx): async def update(self, ctx, *, flag: str = ""): """ Update Modmail. - To stay up-to-date with the latest commit rom GitHub, specify "force" as the flag. + To stay up-to-date with the latest commit from GitHub, specify "force" as the flag. """ changelog = await Changelog.from_url(self.bot) @@ -1939,7 +1939,7 @@ async def update(self, ctx, *, flag: str = ""): desc = ( f"The latest version is [`{self.bot.version}`]" - "(https://github.com/kyb3r/modmail/blob/master/bot.py#L25)" + "(https://github.com/kyb3r/modmail/blob/master/bot.py#L1)" ) if self.bot.version >= parse_version(latest.version) and flag.lower() != "force": @@ -1951,16 +1951,35 @@ async def update(self, ctx, *, flag: str = ""): embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) await ctx.send(embed=embed) else: - if self.bot.hosting_method == HostingMethod.HEROKU: + try: + # update fork if gh_token exists data = await self.bot.api.update_repository() + except InvalidConfigError: + data = {} + except ClientResponseError as exc: + embed = discord.Embed( + title="Update failed", + description=f"Error status {exc.status}. {exc.message}", + color=self.bot.error_color, + ) + return await ctx.send(embed=embed) + + if self.bot.hosting_method == HostingMethod.HEROKU: + if not data: + # invalid gh_token + embed = discord.Embed( + title="Update failed", + description="Invalid Github token.", + color=self.bot.error_color, + ) + return await ctx.send(embed=embed) commit_data = data["data"] user = data["user"] - if commit_data and commit_data.get("html_url"): embed = discord.Embed(color=self.bot.main_color) - embed.set_footer(text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}") + embed.set_footer(text=f"Updating Modmail v{self.bot.version} -> v{latest.version}") embed.set_author( name=user["username"] + " - Updating bot", @@ -1978,21 +1997,14 @@ async def update(self, ctx, *, flag: str = ""): else: embed = discord.Embed( title="Already up to date", - description="No further updates required", + description="No further updates required.", color=self.bot.main_color, ) embed.set_footer(text="Force update") embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) await ctx.send(embed=embed) else: - # update fork if gh_token exists - try: - await self.bot.api.update_repository() - except InvalidConfigError: - pass - command = "git pull" - proc = await asyncio.create_subprocess_shell( command, stderr=PIPE, diff --git a/core/clients.py b/core/clients.py index a9722776f2..862c665310 100644 --- a/core/clients.py +++ b/core/clients.py @@ -1,7 +1,7 @@ import secrets import sys from json import JSONDecodeError -from typing import Union, Optional +from typing import Any, Dict, Union, Optional import discord from discord import Member, DMChannel, TextChannel, Message @@ -19,6 +19,7 @@ class GitHub: """ The client for interacting with GitHub API. + Parameters ---------- bot : Bot @@ -31,6 +32,7 @@ class GitHub: URL to the avatar in GitHub. url : str, optional URL to the GitHub profile. + Attributes ---------- bot : Bot @@ -43,6 +45,7 @@ class GitHub: URL to the avatar in GitHub. url : str URL to the GitHub profile. + Class Attributes ---------------- BASE : str @@ -77,7 +80,7 @@ def __init__(self, bot, access_token: str = "", username: str = "", **kwargs): self.headers = {"Authorization": "token " + str(access_token)} @property - def BRANCH(self): + def BRANCH(self) -> str: return "master" if not self.bot.version.is_prerelease else "development" async def request( @@ -85,11 +88,13 @@ async def request( url: str, method: str = "GET", payload: dict = None, - return_response: bool = False, headers: dict = None, - ) -> Union[ClientResponse, dict, str]: + return_response: bool = False, + read_before_return: bool = True, + ) -> Union[ClientResponse, Dict[str, Any], str]: """ Makes a HTTP request. + Parameters ---------- url : str @@ -98,16 +103,20 @@ async def request( The HTTP method (POST, GET, PUT, DELETE, FETCH, etc.). payload : Dict[str, Any] The json payload to be sent along the request. - return_response : bool - Whether the `ClientResponse` object should be returned. headers : Dict[str, str] Additional headers to `headers`. + return_response : bool + Whether the `ClientResponse` object should be returned. + read_before_return : bool + Whether to perform `.read()` method before returning the `ClientResponse` object. + Only valid if `return_response` is set to `True`. + Returns ------- ClientResponse or Dict[str, Any] or List[Any] or str `ClientResponse` if `return_response` is `True`. - `dict` if the returned data is a json object. - `list` if the returned data is a json list. + `Dict[str, Any]` if the returned data is a json object. + `List[Any]` if the returned data is a json list. `str` if the returned data is not a valid json data, the raw response. """ @@ -117,19 +126,24 @@ async def request( headers = self.headers async with self.session.request(method, url, headers=headers, json=payload) as resp: if return_response: + if read_before_return: + await resp.read() return resp + try: return await resp.json() except (JSONDecodeError, ClientResponseError): return await resp.text() - def filter_valid(self, data): + def filter_valid(self, data) -> Dict[str, Any]: """ Filters configuration keys that are accepted. + Parameters ---------- data : Dict[str, Any] The data that needs to be cleaned. + Returns ------- Dict[str, Any] @@ -138,42 +152,73 @@ def filter_valid(self, data): valid_keys = self.bot.config.valid_keys.difference(self.bot.config.protected_keys) return {k: v for k, v in data.items() if k in valid_keys} - async def update_repository(self, sha: str = None) -> Optional[dict]: + async def update_repository(self, sha: str = None) -> Dict[str, Any]: """ Update the repository from Modmail main repo. + Parameters ---------- - sha : Optional[str], optional - The commit SHA to update the repository. + sha : Optional[str] + The commit SHA to update the repository. If `None`, the latest + commit SHA will be fetched. + Returns ------- - Optional[dict] - If the response is a dict. + Dict[str, Any] + A dictionary that contains response data. """ if not self.username: raise commands.CommandInvokeError("Username not found.") if sha is None: - resp: dict = await self.request(self.REPO + "/git/refs/heads/" + self.BRANCH) + resp = await self.request(self.REPO + "/git/refs/heads/" + self.BRANCH) sha = resp["object"]["sha"] payload = {"base": self.BRANCH, "head": sha, "commit_message": "Updating bot"} merge_url = self.MERGE_URL.format(username=self.username) - resp = await self.request(merge_url, method="POST", payload=payload) - if isinstance(resp, dict): - return resp + resp = await self.request( + merge_url, + method="POST", + payload=payload, + return_response=True, + read_before_return=True, + ) + + repo_url = self.BASE + f"/repos/{self.username}/modmail" + status_map = { + 201: "Successful response.", + 204: "Already merged.", + 403: "Forbidden.", + 404: f"Repository '{repo_url}' not found.", + 409: "There is a merge conflict.", + 422: "Validation failed.", + } + # source https://docs.github.com/en/rest/branches/branches#merge-a-branch + + status = resp.status + if status in (201, 204): + try: + return await resp.json() + except (JSONDecodeError, ClientResponseError): + return await resp.text() + + args = (resp.request_info, resp.history) + kwargs = {"status": status, "message": status_map.get(status)} + # just raise + raise ClientResponseError(*args, **kwargs) async def fork_repository(self) -> None: """ Forks Modmail's repository. """ - await self.request(self.FORK_URL, method="POST") + await self.request(self.FORK_URL, method="POST", return_response=True) async def has_starred(self) -> bool: """ Checks if shared Modmail. + Returns ------- bool @@ -187,23 +232,30 @@ async def star_repository(self) -> None: """ Stars Modmail's repository. """ - await self.request(self.STAR_URL, method="PUT", headers={"Content-Length": "0"}) + await self.request( + self.STAR_URL, + method="PUT", + headers={"Content-Length": "0"}, + return_response=True, + ) @classmethod async def login(cls, bot) -> "GitHub": """ Logs in to GitHub with configuration variable information. + Parameters ---------- bot : Bot The Modmail bot. + Returns ------- GitHub The newly created `GitHub` object. """ self = cls(bot, bot.config.get("github_token")) - resp: dict = await self.request("https://api.github.com/user") + resp: Dict[str, Any] = await self.request(self.BASE + "/user") if resp.get("login"): self.username = resp["login"] self.avatar_url = resp["avatar_url"] @@ -666,7 +718,7 @@ async def update_repository(self) -> dict: "data": data, "user": { "username": user.username, - "avatar_url": user.display_avatar.url, + "avatar_url": user.avatar_url, "url": user.url, }, } From 23221a2fd691733ede405a44b9da5f593e2d74c7 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <hidzrie@gmail.com> Date: Tue, 7 Jun 2022 14:36:09 +0000 Subject: [PATCH 550/705] Fix previous commit. - Return only if hosting method is HEROKU. - Try to get the response error message first if any. --- bot.py | 18 +++++++++++++----- cogs/utility.py | 18 +++++++++++------- core/clients.py | 32 +++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/bot.py b/bot.py index 5db1aab550..f3dc071fab 100644 --- a/bot.py +++ b/bot.py @@ -1594,17 +1594,22 @@ async def autoupdate(self): latest = changelog.latest_version if self.version < parse_version(latest.version): + error = None + data = {} try: # update fork if gh_token exists data = await self.api.update_repository() except InvalidConfigError: - data = {} + pass except ClientResponseError as exc: - logger.error(f"Autoupdate failed! Status {exc.status}.") - logger.error(f"Message: {exc.message}") - self.autoupdate.cancel() - return + error = exc if self.hosting_method == HostingMethod.HEROKU: + if error is not None: + logger.error(f"Autoupdate failed! Status: {error.status}.") + logger.error(f"Error message: {error.message}") + self.autoupdate.cancel() + return + commit_data = data.get("data") if not commit_data: return @@ -1681,15 +1686,18 @@ async def before_autoupdate(self): if self.config.get("disable_autoupdates"): logger.warning("Autoupdates disabled.") self.autoupdate.cancel() + return if self.hosting_method == HostingMethod.DOCKER: logger.warning("Autoupdates disabled as using Docker.") self.autoupdate.cancel() + return if not self.config.get("github_token") and self.hosting_method == HostingMethod.HEROKU: logger.warning("GitHub access token not found.") logger.warning("Autoupdates disabled.") self.autoupdate.cancel() + return def format_channel_name(self, author, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names diff --git a/cogs/utility.py b/cogs/utility.py index 5d35a20211..ba60253370 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1951,20 +1951,24 @@ async def update(self, ctx, *, flag: str = ""): embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) await ctx.send(embed=embed) else: + error = None + data = {} try: # update fork if gh_token exists data = await self.bot.api.update_repository() except InvalidConfigError: - data = {} + pass except ClientResponseError as exc: - embed = discord.Embed( - title="Update failed", - description=f"Error status {exc.status}. {exc.message}", - color=self.bot.error_color, - ) - return await ctx.send(embed=embed) + error = exc if self.bot.hosting_method == HostingMethod.HEROKU: + if error is not None: + embed = discord.Embed( + title="Update failed", + description=f"Error status: {error.status}.\nError message: {error.message}", + color=self.bot.error_color, + ) + return await ctx.send(embed=embed) if not data: # invalid gh_token embed = discord.Embed( diff --git a/core/clients.py b/core/clients.py index 862c665310..df7e1b7b56 100644 --- a/core/clients.py +++ b/core/clients.py @@ -130,10 +130,18 @@ async def request( await resp.read() return resp - try: - return await resp.json() - except (JSONDecodeError, ClientResponseError): - return await resp.text() + return await self._get_response_data(resp) + + @staticmethod + async def _get_response_data(response: ClientResponse) -> Union[Dict[str, Any], str]: + """ + Internal method to convert the response data to `dict` if the data is a + json object, or to `str` (raw response) if the data is not a valid json. + """ + try: + return await response.json() + except (JSONDecodeError, ClientResponseError): + return await response.text() def filter_valid(self, data) -> Dict[str, Any]: """ @@ -198,14 +206,20 @@ async def update_repository(self, sha: str = None) -> Dict[str, Any]: # source https://docs.github.com/en/rest/branches/branches#merge-a-branch status = resp.status + data = await self._get_response_data(resp) if status in (201, 204): - try: - return await resp.json() - except (JSONDecodeError, ClientResponseError): - return await resp.text() + return data args = (resp.request_info, resp.history) - kwargs = {"status": status, "message": status_map.get(status)} + try: + # try to get the response error message if any + message = data.get("message") + except AttributeError: + message = None + kwargs = { + "status": status, + "message": message if message else status_map.get(status), + } # just raise raise ClientResponseError(*args, **kwargs) From f2865d22d489334893a679312cd5451203243e19 Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sat, 25 Jun 2022 09:06:34 +0530 Subject: [PATCH 551/705] Remove the set title after creating thread --- core/thread.py | 1 - 1 file changed, 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index e39076d702..606a204b37 100644 --- a/core/thread.py +++ b/core/thread.py @@ -196,7 +196,6 @@ async def setup(self, *, creator=None, category=None, initial_message=None): log_url = log_count = None # ensure core functionality still works - await channel.edit(topic=f"User ID: {recipient.id}") self.ready = True if creator is not None and creator != recipient: From 80fe41e3d6468eb7da440b3671ff1455bf919cc0 Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sat, 25 Jun 2022 09:07:26 +0530 Subject: [PATCH 552/705] Add the set title during creating the thread --- core/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/utils.py b/core/utils.py index 32f12c72e8..30efb05e75 100644 --- a/core/utils.py +++ b/core/utils.py @@ -432,6 +432,7 @@ async def create_thread_channel(bot, recipient, category, overwrites, *, name=No name=name, category=category, overwrites=overwrites, + topic=f"User ID: {recipient.id}", reason="Creating a thread channel.", ) except discord.HTTPException as e: From c05725dcf251871910a691d535352a6464e2f977 Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sat, 25 Jun 2022 10:09:31 +0530 Subject: [PATCH 553/705] Update bot.py --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index a506addfd9..e234eace55 100644 --- a/bot.py +++ b/bot.py @@ -1099,7 +1099,7 @@ async def get_context(self, message, *, cls=commands.Context): view = StringView(message.content) ctx = cls(prefix=self.prefix, view=view, bot=self, message=message) - if self._skip_check(message.author.id, self.user.id): + if message.author.id == self.user.id: return ctx ctx.thread = await self.threads.find(channel=ctx.channel) From 19b42f03f1c63c05e7c17f376b3ffee6e587eae1 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <hidzrie@gmail.com> Date: Sat, 25 Jun 2022 08:24:35 +0000 Subject: [PATCH 554/705] Fix Future attached to different loop, issue #3165 --- bot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index a506addfd9..8b912f4286 100644 --- a/bot.py +++ b/bot.py @@ -71,7 +71,7 @@ def __init__(self): self._api = None self.formatter = SafeFormatter() self.loaded_cogs = ["cogs.modmail", "cogs.plugins", "cogs.utility"] - self._connected = asyncio.Event() + self._connected = None self.start_time = discord.utils.utcnow() self._started = False @@ -213,6 +213,7 @@ async def get_prefix(self, message=None): def run(self): async def runner(): async with self: + self._connected = asyncio.Event() self.session = ClientSession(loop=self.loop) try: retry_intents = False From 30a0daa356b220181babad3b0d92e5acd6801b2b Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 3 Jul 2022 21:50:56 +0800 Subject: [PATCH 555/705] update changelog w new PRs --- CHANGELOG.md | 1 + bot.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c096d05d7f..054f126f7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Audit log searching now properly works. - Old data causing `?blocked` to fail. ([GH #3131](https://github.com/kyb3r/modmail/issues/3131)) - Delete channel auto close functionality now works. +- Improved error handling for autoupdate. ([PR #3161](https://github.com/kyb3r/modmail/pull/3161)) ### Internal diff --git a/bot.py b/bot.py index 788ba64604..3723e94325 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev14" +__version__ = "4.0.0-dev15" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 56f30163c2..8b306b2d18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev14' +version = '4.0.0-dev15' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 109197d9f509eb4ae5b1c8e7c0d59e79a222ea0b Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Sun, 3 Jul 2022 21:54:30 +0800 Subject: [PATCH 556/705] update contributing.md --- .github/CONTRIBUTING.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 568e5f2175..b1309b6402 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -33,6 +33,17 @@ In short, when you submit code changes, your submissions are understood to be un ## Report bugs using [Github Issues](https://github.com/kyb3r/modmail/issues) We use GitHub issues to track public bugs. Report a bug by [opening a new Issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! +## Find pre-existing issues to tackle +Check out our [unstaged issue tracker](https://github.com/kyb3r/modmail/issues?q=is%3Aissue+is%3Aopen+-label%3Astaged) and start helping out! + +Ways to help out: +- Help out new members +- Highlight invalid bugs/unsupported use cases +- Code review of pull requests +- Add on new use cases or reproduction steps +- Point out duplicate issues and guide them to the right direction +- Create a pull request to resolve the issue! + ## Write bug reports with detail, background, and sample code **Great Bug Reports** tend to have: @@ -43,7 +54,6 @@ We use GitHub issues to track public bugs. Report a bug by [opening a new Issue] - What *actually* happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) - ## Use a Consistent Coding Style We use [black](https://github.com/python/black) for a unified code style. From 3fe1ce8d5e495c06d814ed718ec40e7e2aa8e79a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 6 Jul 2022 01:18:32 +0800 Subject: [PATCH 557/705] update dpy@37c9ab7 and colorama --- Pipfile | 4 +- Pipfile.lock | 260 +++++++++++++++++++++++++++++---------------------- 2 files changed, 148 insertions(+), 116 deletions(-) diff --git a/Pipfile b/Pipfile index 88d49f59fd..82ec35158d 100644 --- a/Pipfile +++ b/Pipfile @@ -11,8 +11,8 @@ typing-extensions = "==4.2.0" [packages] aiohttp = "==3.8.1" -colorama = "~=0.4.4" # Doesn't officially support Python 3.9 yet, v0.4.5 will support 3.9 -"discord.py" = {ref = "e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd", git = "https://github.com/Rapptz/discord.py.git"} +colorama = "~=0.4.5" +"discord.py" = {ref = "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7", git = "https://github.com/Rapptz/discord.py.git"} emoji = "==1.7.0" isodate = "~=0.6.0" motor = "==2.5.1" diff --git a/Pipfile.lock b/Pipfile.lock index 163d09bdcd..87a2f247fc 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "4035fc1c98c21d437f41fcd2f32ca38089131e4a60ef0f4453caf4019dae7bd3" + "sha256": "89578b9ae8a9a0b580e0af21767bd2f062388ad43c9bdc6e5d113de91361bea3" }, "pipfile-spec": 6, "requires": {}, @@ -132,74 +132,88 @@ }, "cffi": { "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "version": "==1.15.0" + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "version": "==1.15.1" }, "charset-normalizer": { "hashes": [ - "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" + "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", + "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" ], - "markers": "python_full_version >= '3.5.0'", - "version": "==2.0.12" + "markers": "python_version >= '3.6'", + "version": "==2.1.0" }, "colorama": { "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", + "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" ], "index": "pypi", - "version": "==0.4.4" + "version": "==0.4.5" }, "cssselect2": { "hashes": [ @@ -219,11 +233,11 @@ }, "discord-py": { "git": "https://github.com/Rapptz/discord.py.git", - "ref": "e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd" + "ref": "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7" }, "discord.py": { "git": "https://github.com/Rapptz/discord.py.git", - "ref": "e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd" + "ref": "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7" }, "dnspython": { "hashes": [ @@ -310,7 +324,7 @@ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_full_version >= '3.5.0'", + "markers": "python_version >= '3.5'", "version": "==3.3" }, "isodate": { @@ -421,47 +435,67 @@ }, "pillow": { "hashes": [ - "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e", - "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595", - "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512", - "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c", - "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477", - "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a", - "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4", - "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e", - "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5", - "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378", - "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a", - "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652", - "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7", - "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a", - "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a", - "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6", - "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165", - "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160", - "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331", - "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b", - "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458", - "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033", - "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8", - "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481", - "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58", - "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7", - "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3", - "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea", - "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34", - "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3", - "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8", - "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581", - "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244", - "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef", - "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0", - "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2", - "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97", - "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717" + "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927", + "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14", + "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc", + "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58", + "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60", + "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76", + "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c", + "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac", + "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490", + "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1", + "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f", + "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d", + "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", + "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", + "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", + "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", + "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", + "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", + "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8", + "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff", + "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da", + "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004", + "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f", + "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20", + "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d", + "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c", + "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544", + "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9", + "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3", + "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04", + "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c", + "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5", + "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4", + "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb", + "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4", + "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c", + "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467", + "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e", + "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421", + "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b", + "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", + "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", + "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", + "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", + "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", + "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", + "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28", + "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0", + "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1", + "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8", + "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd", + "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4", + "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8", + "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f", + "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013", + "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59", + "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc", + "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4" ], "markers": "python_version >= '3.7'", - "version": "==9.1.0" + "version": "==9.2.0" }, "pycparser": { "hashes": [ @@ -471,9 +505,7 @@ "version": "==2.21" }, "pymongo": { - "extras": [ - "srv" - ], + "extras": [], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -782,11 +814,11 @@ }, "colorama": { "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", + "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" ], "index": "pypi", - "version": "==0.4.4" + "version": "==0.4.5" }, "gitdb": { "hashes": [ @@ -878,11 +910,11 @@ }, "pbr": { "hashes": [ - "sha256:27108648368782d07bbf1cb468ad2e2eeef29086affd14087a6d04b7de8af4ec", - "sha256:66bc5a34912f408bb3925bf21231cb6f59206267b7f63f3503ef865c1a292e25" + "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a", + "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308" ], "markers": "python_version >= '2.6'", - "version": "==5.8.1" + "version": "==5.9.0" }, "platformdirs": { "hashes": [ @@ -941,11 +973,11 @@ }, "setuptools": { "hashes": [ - "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8", - "sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592" + "sha256:16923d366ced322712c71ccb97164d07472abeecd13f3a6c283f6d5d26722793", + "sha256:db3b8e2f922b2a910a29804776c643ea609badb6a32c4bcc226fd4fd902cce65" ], "markers": "python_version >= '3.7'", - "version": "==62.1.0" + "version": "==63.1.0" }, "smmap": { "hashes": [ From a93d81eac495df7fe26a6aabc04c88019f35b3b2 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 6 Jul 2022 01:18:57 +0800 Subject: [PATCH 558/705] fix typo https://github.com/kyb3r/modmail/pull/3161#discussion_r912533027 --- core/clients.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/clients.py b/core/clients.py index df7e1b7b56..eebe3bcff6 100644 --- a/core/clients.py +++ b/core/clients.py @@ -90,7 +90,7 @@ async def request( payload: dict = None, headers: dict = None, return_response: bool = False, - read_before_return: bool = True, + read_before_return: bool = False, ) -> Union[ClientResponse, Dict[str, Any], str]: """ Makes a HTTP request. From ee47143fd01cbc204275397c46b67c7e17efd341 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 6 Jul 2022 01:19:47 +0800 Subject: [PATCH 559/705] update version dv16 --- bot.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index 3723e94325..f3d7198428 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev15" +__version__ = "4.0.0-dev16" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 8b306b2d18..7c1dc0e952 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev15' +version = '4.0.0-dev16' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 07c6dc12bec2ae0a4735c5965ee00d686622a21e Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Fri, 22 Jul 2022 23:38:18 +0530 Subject: [PATCH 560/705] Prevents loaded cogs from being loaded again Fixes #3171 Haven't tested this, but pretty sure it should work. --- bot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bot.py b/bot.py index f3d7198428..5a1c0a18a5 100644 --- a/bot.py +++ b/bot.py @@ -157,6 +157,8 @@ def startup(self): async def load_extensions(self): for cog in self.loaded_cogs: + if cog in self.bot.extensions: + continue logger.debug("Loading %s.", cog) try: await self.load_extension(cog) From f274a79b98fdd67cafdd3b00fd3888639b9da80f Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sat, 23 Jul 2022 19:03:26 +0530 Subject: [PATCH 561/705] Update bot.py --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 5a1c0a18a5..bcb0685f08 100644 --- a/bot.py +++ b/bot.py @@ -157,7 +157,7 @@ def startup(self): async def load_extensions(self): for cog in self.loaded_cogs: - if cog in self.bot.extensions: + if cog in self.extensions: continue logger.debug("Loading %s.", cog) try: From c7072eff17c9a35dc9fbf44855970df0da66ea1f Mon Sep 17 00:00:00 2001 From: Stephen <48072084+StephenDaDev@users.noreply.github.com> Date: Sat, 6 Aug 2022 19:20:00 -0400 Subject: [PATCH 562/705] Add aliases to snippet add command. --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index deb29d160d..7fc9e5b975 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -193,7 +193,7 @@ async def snippet_raw(self, ctx, *, name: str.lower): return await ctx.send(embed=embed) - @snippet.command(name="add") + @snippet.command(name="add", aliases=["create", "make"]) @checks.has_permissions(PermissionLevel.SUPPORTER) async def snippet_add(self, ctx, name: str.lower, *, value: commands.clean_content): """ From 7bc33401aa56523fc60d9345fe222ef90f2df4cb Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Aug 2022 22:17:15 +0800 Subject: [PATCH 563/705] Bump dpy-2.0 --- CHANGELOG.md | 2 +- Pipfile | 2 +- Pipfile.lock | 307 ++++++++++++++++++++++++------------------------- bot.py | 6 +- pyproject.toml | 2 +- 5 files changed, 154 insertions(+), 165 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 054f126f7f..0070eecf0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Breaking - Modmail now requires [`Message Content` privileged intent](https://support-dev.discord.com/hc/en-us/articles/4404772028055-Message-Content-Privileged-Intent-for-Verified-Bots). -- Upgraded to discord.py v2.0 master ([internal changes](https://gist.github.com/apple502j/f75b4f24652f04de85c7084ffd73ec58), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). +- Upgraded to discord.py v2.0 ([internal changes](https://discordpy.readthedocs.io/en/latest/migrating.html), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). - Python 3.8 or higher is required. - Asyncio changes ([gist](https://gist.github.com/Rapptz/6706e1c8f23ac27c98cee4dd985c8120)) diff --git a/Pipfile b/Pipfile index 82ec35158d..12de060a72 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ typing-extensions = "==4.2.0" [packages] aiohttp = "==3.8.1" colorama = "~=0.4.5" -"discord.py" = {ref = "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7", git = "https://github.com/Rapptz/discord.py.git"} +"discord.py" = "==2.0.0" emoji = "==1.7.0" isodate = "~=0.6.0" motor = "==2.5.1" diff --git a/Pipfile.lock b/Pipfile.lock index 87a2f247fc..ed19b5883c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "89578b9ae8a9a0b580e0af21767bd2f062388ad43c9bdc6e5d113de91361bea3" + "sha256": "aa752693f18b9d6058209883bdcece4e37a1a7a62a5fd564d64e551d91ea49f4" }, "pipfile-spec": 6, "requires": {}, @@ -110,11 +110,11 @@ }, "attrs": { "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" + "markers": "python_version >= '3.5'", + "version": "==22.1.0" }, "cairocffi": { "hashes": [ @@ -201,11 +201,11 @@ }, "charset-normalizer": { "hashes": [ - "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", - "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" + "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", + "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" ], "markers": "python_version >= '3.6'", - "version": "==2.1.0" + "version": "==2.1.1" }, "colorama": { "hashes": [ @@ -231,13 +231,13 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.7.1" }, - "discord-py": { - "git": "https://github.com/Rapptz/discord.py.git", - "ref": "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7" - }, "discord.py": { - "git": "https://github.com/Rapptz/discord.py.git", - "ref": "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7" + "hashes": [ + "sha256:18b06870bdc85d29e0d55f4a4b2abe9d7cdae2b197e23d49f82886ba27ba1aec", + "sha256:c36f26935938194c3465c2abf8ecfbbf5560c50b189f1b746d6f00d1e78c0d3b" + ], + "index": "pypi", + "version": "==2.0.0" }, "dnspython": { "hashes": [ @@ -256,68 +256,68 @@ }, "frozenlist": { "hashes": [ - "sha256:006d3595e7d4108a12025ddf415ae0f6c9e736e726a5db0183326fd191b14c5e", - "sha256:01a73627448b1f2145bddb6e6c2259988bb8aee0fb361776ff8604b99616cd08", - "sha256:03a7dd1bfce30216a3f51a84e6dd0e4a573d23ca50f0346634916ff105ba6e6b", - "sha256:0437fe763fb5d4adad1756050cbf855bbb2bf0d9385c7bb13d7a10b0dd550486", - "sha256:04cb491c4b1c051734d41ea2552fde292f5f3a9c911363f74f39c23659c4af78", - "sha256:0c36e78b9509e97042ef869c0e1e6ef6429e55817c12d78245eb915e1cca7468", - "sha256:25af28b560e0c76fa41f550eacb389905633e7ac02d6eb3c09017fa1c8cdfde1", - "sha256:2fdc3cd845e5a1f71a0c3518528bfdbfe2efaf9886d6f49eacc5ee4fd9a10953", - "sha256:30530930410855c451bea83f7b272fb1c495ed9d5cc72895ac29e91279401db3", - "sha256:31977f84828b5bb856ca1eb07bf7e3a34f33a5cddce981d880240ba06639b94d", - "sha256:3c62964192a1c0c30b49f403495911298810bada64e4f03249ca35a33ca0417a", - "sha256:3f7c935c7b58b0d78c0beea0c7358e165f95f1fd8a7e98baa40d22a05b4a8141", - "sha256:40dff8962b8eba91fd3848d857203f0bd704b5f1fa2b3fc9af64901a190bba08", - "sha256:40ec383bc194accba825fbb7d0ef3dda5736ceab2375462f1d8672d9f6b68d07", - "sha256:436496321dad302b8b27ca955364a439ed1f0999311c393dccb243e451ff66aa", - "sha256:4406cfabef8f07b3b3af0f50f70938ec06d9f0fc26cbdeaab431cbc3ca3caeaa", - "sha256:45334234ec30fc4ea677f43171b18a27505bfb2dba9aca4398a62692c0ea8868", - "sha256:47be22dc27ed933d55ee55845d34a3e4e9f6fee93039e7f8ebadb0c2f60d403f", - "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b", - "sha256:4eda49bea3602812518765810af732229b4291d2695ed24a0a20e098c45a707b", - "sha256:57f4d3f03a18facacb2a6bcd21bccd011e3b75d463dc49f838fd699d074fabd1", - "sha256:603b9091bd70fae7be28bdb8aa5c9990f4241aa33abb673390a7f7329296695f", - "sha256:65bc6e2fece04e2145ab6e3c47428d1bbc05aede61ae365b2c1bddd94906e478", - "sha256:691ddf6dc50480ce49f68441f1d16a4c3325887453837036e0fb94736eae1e58", - "sha256:6983a31698490825171be44ffbafeaa930ddf590d3f051e397143a5045513b01", - "sha256:6a202458d1298ced3768f5a7d44301e7c86defac162ace0ab7434c2e961166e8", - "sha256:6eb275c6385dd72594758cbe96c07cdb9bd6becf84235f4a594bdf21e3596c9d", - "sha256:754728d65f1acc61e0f4df784456106e35afb7bf39cfe37227ab00436fb38676", - "sha256:768efd082074bb203c934e83a61654ed4931ef02412c2fbdecea0cff7ecd0274", - "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab", - "sha256:871d42623ae15eb0b0e9df65baeee6976b2e161d0ba93155411d58ff27483ad8", - "sha256:88aafd445a233dbbf8a65a62bc3249a0acd0d81ab18f6feb461cc5a938610d24", - "sha256:8c905a5186d77111f02144fab5b849ab524f1e876a1e75205cd1386a9be4b00a", - "sha256:8cf829bd2e2956066dd4de43fd8ec881d87842a06708c035b37ef632930505a2", - "sha256:92e650bd09b5dda929523b9f8e7f99b24deac61240ecc1a32aeba487afcd970f", - "sha256:93641a51f89473837333b2f8100f3f89795295b858cd4c7d4a1f18e299dc0a4f", - "sha256:94c7a8a9fc9383b52c410a2ec952521906d355d18fccc927fca52ab575ee8b93", - "sha256:9f892d6a94ec5c7b785e548e42722e6f3a52f5f32a8461e82ac3e67a3bd073f1", - "sha256:acb267b09a509c1df5a4ca04140da96016f40d2ed183cdc356d237286c971b51", - "sha256:adac9700675cf99e3615eb6a0eb5e9f5a4143c7d42c05cea2e7f71c27a3d0846", - "sha256:aff388be97ef2677ae185e72dc500d19ecaf31b698986800d3fc4f399a5e30a5", - "sha256:b5009062d78a8c6890d50b4e53b0ddda31841b3935c1937e2ed8c1bda1c7fb9d", - "sha256:b684c68077b84522b5c7eafc1dc735bfa5b341fb011d5552ebe0968e22ed641c", - "sha256:b9e3e9e365991f8cc5f5edc1fd65b58b41d0514a6a7ad95ef5c7f34eb49b3d3e", - "sha256:bd89acd1b8bb4f31b47072615d72e7f53a948d302b7c1d1455e42622de180eae", - "sha256:bde99812f237f79eaf3f04ebffd74f6718bbd216101b35ac7955c2d47c17da02", - "sha256:c6c321dd013e8fc20735b92cb4892c115f5cdb82c817b1e5b07f6b95d952b2f0", - "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b", - "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3", - "sha256:d26b650b71fdc88065b7a21f8ace70175bcf3b5bdba5ea22df4bfd893e795a3b", - "sha256:d6d32ff213aef0fd0bcf803bffe15cfa2d4fde237d1d4838e62aec242a8362fa", - "sha256:e1e26ac0a253a2907d654a37e390904426d5ae5483150ce3adedb35c8c06614a", - "sha256:e30b2f9683812eb30cf3f0a8e9f79f8d590a7999f731cf39f9105a7c4a39489d", - "sha256:e84cb61b0ac40a0c3e0e8b79c575161c5300d1d89e13c0e02f76193982f066ed", - "sha256:e982878792c971cbd60ee510c4ee5bf089a8246226dea1f2138aa0bb67aff148", - "sha256:f20baa05eaa2bcd5404c445ec51aed1c268d62600362dc6cfe04fae34a424bd9", - "sha256:f7353ba3367473d1d616ee727945f439e027f0bb16ac1a750219a8344d1d5d3c", - "sha256:f96293d6f982c58ebebb428c50163d010c2f05de0cde99fd681bfdc18d4b2dc2", - "sha256:ff9310f05b9d9c5c4dd472983dc956901ee6cb2c3ec1ab116ecdde25f3ce4951" + "sha256:022178b277cb9277d7d3b3f2762d294f15e85cd2534047e68a118c2bb0058f3e", + "sha256:086ca1ac0a40e722d6833d4ce74f5bf1aba2c77cbfdc0cd83722ffea6da52a04", + "sha256:0bc75692fb3770cf2b5856a6c2c9de967ca744863c5e89595df64e252e4b3944", + "sha256:0dde791b9b97f189874d654c55c24bf7b6782343e14909c84beebd28b7217845", + "sha256:12607804084d2244a7bd4685c9d0dca5df17a6a926d4f1967aa7978b1028f89f", + "sha256:19127f8dcbc157ccb14c30e6f00392f372ddb64a6ffa7106b26ff2196477ee9f", + "sha256:1b51eb355e7f813bcda00276b0114c4172872dc5fb30e3fea059b9367c18fbcb", + "sha256:1e1cf7bc8cbbe6ce3881863671bac258b7d6bfc3706c600008925fb799a256e2", + "sha256:219a9676e2eae91cb5cc695a78b4cb43d8123e4160441d2b6ce8d2c70c60e2f3", + "sha256:2743bb63095ef306041c8f8ea22bd6e4d91adabf41887b1ad7886c4c1eb43d5f", + "sha256:2af6f7a4e93f5d08ee3f9152bce41a6015b5cf87546cb63872cc19b45476e98a", + "sha256:31b44f1feb3630146cffe56344704b730c33e042ffc78d21f2125a6a91168131", + "sha256:31bf9539284f39ff9398deabf5561c2b0da5bb475590b4e13dd8b268d7a3c5c1", + "sha256:35c3d79b81908579beb1fb4e7fcd802b7b4921f1b66055af2578ff7734711cfa", + "sha256:3a735e4211a04ccfa3f4833547acdf5d2f863bfeb01cfd3edaffbc251f15cec8", + "sha256:42719a8bd3792744c9b523674b752091a7962d0d2d117f0b417a3eba97d1164b", + "sha256:49459f193324fbd6413e8e03bd65789e5198a9fa3095e03f3620dee2f2dabff2", + "sha256:4c0c99e31491a1d92cde8648f2e7ccad0e9abb181f6ac3ddb9fc48b63301808e", + "sha256:52137f0aea43e1993264a5180c467a08a3e372ca9d378244c2d86133f948b26b", + "sha256:526d5f20e954d103b1d47232e3839f3453c02077b74203e43407b962ab131e7b", + "sha256:53b2b45052e7149ee8b96067793db8ecc1ae1111f2f96fe1f88ea5ad5fd92d10", + "sha256:572ce381e9fe027ad5e055f143763637dcbac2542cfe27f1d688846baeef5170", + "sha256:58fb94a01414cddcdc6839807db77ae8057d02ddafc94a42faee6004e46c9ba8", + "sha256:5e77a8bd41e54b05e4fb2708dc6ce28ee70325f8c6f50f3df86a44ecb1d7a19b", + "sha256:5f271c93f001748fc26ddea409241312a75e13466b06c94798d1a341cf0e6989", + "sha256:5f63c308f82a7954bf8263a6e6de0adc67c48a8b484fab18ff87f349af356efd", + "sha256:61d7857950a3139bce035ad0b0945f839532987dfb4c06cfe160254f4d19df03", + "sha256:61e8cb51fba9f1f33887e22488bad1e28dd8325b72425f04517a4d285a04c519", + "sha256:625d8472c67f2d96f9a4302a947f92a7adbc1e20bedb6aff8dbc8ff039ca6189", + "sha256:6e19add867cebfb249b4e7beac382d33215d6d54476bb6be46b01f8cafb4878b", + "sha256:717470bfafbb9d9be624da7780c4296aa7935294bd43a075139c3d55659038ca", + "sha256:74140933d45271c1a1283f708c35187f94e1256079b3c43f0c2267f9db5845ff", + "sha256:74e6b2b456f21fc93ce1aff2b9728049f1464428ee2c9752a4b4f61e98c4db96", + "sha256:9494122bf39da6422b0972c4579e248867b6b1b50c9b05df7e04a3f30b9a413d", + "sha256:94e680aeedc7fd3b892b6fa8395b7b7cc4b344046c065ed4e7a1e390084e8cb5", + "sha256:97d9e00f3ac7c18e685320601f91468ec06c58acc185d18bb8e511f196c8d4b2", + "sha256:9c6ef8014b842f01f5d2b55315f1af5cbfde284eb184075c189fd657c2fd8204", + "sha256:a027f8f723d07c3f21963caa7d585dcc9b089335565dabe9c814b5f70c52705a", + "sha256:a718b427ff781c4f4e975525edb092ee2cdef6a9e7bc49e15063b088961806f8", + "sha256:ab386503f53bbbc64d1ad4b6865bf001414930841a870fc97f1546d4d133f141", + "sha256:ab6fa8c7871877810e1b4e9392c187a60611fbf0226a9e0b11b7b92f5ac72792", + "sha256:b47d64cdd973aede3dd71a9364742c542587db214e63b7529fbb487ed67cddd9", + "sha256:b499c6abe62a7a8d023e2c4b2834fce78a6115856ae95522f2f974139814538c", + "sha256:bbb1a71b1784e68870800b1bc9f3313918edc63dbb8f29fbd2e767ce5821696c", + "sha256:c3b31180b82c519b8926e629bf9f19952c743e089c41380ddca5db556817b221", + "sha256:c56c299602c70bc1bb5d1e75f7d8c007ca40c9d7aebaf6e4ba52925d88ef826d", + "sha256:c92deb5d9acce226a501b77307b3b60b264ca21862bd7d3e0c1f3594022f01bc", + "sha256:cc2f3e368ee5242a2cbe28323a866656006382872c40869b49b265add546703f", + "sha256:d82bed73544e91fb081ab93e3725e45dd8515c675c0e9926b4e1f420a93a6ab9", + "sha256:da1cdfa96425cbe51f8afa43e392366ed0b36ce398f08b60de6b97e3ed4affef", + "sha256:da5ba7b59d954f1f214d352308d1d86994d713b13edd4b24a556bcc43d2ddbc3", + "sha256:e0c8c803f2f8db7217898d11657cb6042b9b0553a997c4a0601f48a691480fab", + "sha256:ee4c5120ddf7d4dd1eaf079af3af7102b56d919fa13ad55600a4e0ebe532779b", + "sha256:eee0c5ecb58296580fc495ac99b003f64f82a74f9576a244d04978a7e97166db", + "sha256:f5abc8b4d0c5b556ed8cd41490b606fe99293175a82b98e652c3f2711b452988", + "sha256:f810e764617b0748b49a731ffaa525d9bb36ff38332411704c2400125af859a6", + "sha256:f89139662cc4e65a4813f4babb9ca9544e42bddb823d2ec434e18dad582543bc", + "sha256:fa47319a10e0a076709644a0efbcaab9e91902c8bd8ef74c6adb19d320f69b83", + "sha256:fabb953ab913dadc1ff9dcc3a7a7d3dc6a92efab3a0373989b8063347f8705be" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.3.1" }, "idna": { "hashes": [ @@ -505,7 +505,9 @@ "version": "==2.21" }, "pymongo": { - "extras": [], + "extras": [ + "srv" + ], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -681,81 +683,68 @@ }, "yarl": { "hashes": [ - "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac", - "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8", - "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e", - "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746", - "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98", - "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125", - "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d", - "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d", - "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986", - "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d", - "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec", - "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8", - "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee", - "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3", - "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1", - "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd", - "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b", - "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de", - "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0", - "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8", - "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6", - "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245", - "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23", - "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332", - "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1", - "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c", - "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4", - "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0", - "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8", - "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832", - "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58", - "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6", - "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1", - "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52", - "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92", - "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185", - "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d", - "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d", - "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b", - "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739", - "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05", - "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63", - "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d", - "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa", - "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913", - "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe", - "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b", - "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b", - "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656", - "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1", - "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4", - "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e", - "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63", - "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271", - "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed", - "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d", - "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda", - "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265", - "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f", - "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c", - "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba", - "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c", - "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b", - "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523", - "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a", - "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef", - "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95", - "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72", - "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794", - "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41", - "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576", - "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59" + "sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb", + "sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3", + "sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035", + "sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453", + "sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d", + "sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a", + "sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231", + "sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f", + "sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae", + "sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b", + "sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3", + "sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507", + "sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd", + "sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae", + "sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe", + "sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c", + "sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4", + "sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64", + "sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357", + "sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54", + "sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461", + "sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4", + "sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497", + "sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0", + "sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1", + "sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957", + "sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350", + "sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780", + "sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843", + "sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548", + "sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6", + "sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40", + "sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee", + "sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b", + "sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6", + "sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0", + "sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e", + "sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880", + "sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc", + "sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e", + "sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead", + "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28", + "sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf", + "sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd", + "sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae", + "sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0", + "sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0", + "sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae", + "sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda", + "sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546", + "sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802", + "sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be", + "sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07", + "sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936", + "sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272", + "sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc", + "sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a", + "sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28", + "sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b" ], - "markers": "python_version >= '3.6'", - "version": "==1.7.2" + "markers": "python_version >= '3.7'", + "version": "==1.8.1" } }, "develop": { @@ -910,11 +899,11 @@ }, "pbr": { "hashes": [ - "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a", - "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308" + "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a", + "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf" ], "markers": "python_version >= '2.6'", - "version": "==5.9.0" + "version": "==5.10.0" }, "platformdirs": { "hashes": [ @@ -973,11 +962,11 @@ }, "setuptools": { "hashes": [ - "sha256:16923d366ced322712c71ccb97164d07472abeecd13f3a6c283f6d5d26722793", - "sha256:db3b8e2f922b2a910a29804776c643ea609badb6a32c4bcc226fd4fd902cce65" + "sha256:7f4bc85450898a09f76ebf28b72fa25bc7111f6c7d665d514a60bba9c75ef2a9", + "sha256:a3ca5857c89f82f5c9410e8508cb32f4872a3bafd4aa7ae122a24ca33bccc750" ], "markers": "python_version >= '3.7'", - "version": "==63.1.0" + "version": "==65.2.0" }, "smmap": { "hashes": [ @@ -989,11 +978,11 @@ }, "stevedore": { "hashes": [ - "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c", - "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335" + "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8", + "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786" ], - "markers": "python_version >= '3.6'", - "version": "==3.5.0" + "markers": "python_version >= '3.8'", + "version": "==4.0.0" }, "toml": { "hashes": [ diff --git a/bot.py b/bot.py index f3d7198428..fb373f9e76 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev16" +__version__ = "4.0.0-dev17" import asyncio @@ -1769,9 +1769,9 @@ def main(): sys.exit(0) # check discord version - if discord.__version__ != "2.0.0a": + if discord.__version__ != "2.0.0": logger.error( - "Dependencies are not updated, run pipenv install. discord.py version expected 2.0.0a, received %s", + "Dependencies are not updated, run pipenv install. discord.py version expected 2.0.0, received %s", discord.__version__, ) sys.exit(0) diff --git a/pyproject.toml b/pyproject.toml index 7c1dc0e952..b3dea8293f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev16' +version = '4.0.0-dev17' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From ac2e36ced9ce3fbc27a02ef9f8653c211629a1ee Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Aug 2022 22:20:30 +0800 Subject: [PATCH 564/705] Bump dpy-2.0 --- CHANGELOG.md | 2 +- Pipfile | 2 +- Pipfile.lock | 307 ++++++++++++++++++++++++------------------------- bot.py | 6 +- pyproject.toml | 2 +- 5 files changed, 154 insertions(+), 165 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 054f126f7f..0070eecf0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Breaking - Modmail now requires [`Message Content` privileged intent](https://support-dev.discord.com/hc/en-us/articles/4404772028055-Message-Content-Privileged-Intent-for-Verified-Bots). -- Upgraded to discord.py v2.0 master ([internal changes](https://gist.github.com/apple502j/f75b4f24652f04de85c7084ffd73ec58), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). +- Upgraded to discord.py v2.0 ([internal changes](https://discordpy.readthedocs.io/en/latest/migrating.html), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). - Python 3.8 or higher is required. - Asyncio changes ([gist](https://gist.github.com/Rapptz/6706e1c8f23ac27c98cee4dd985c8120)) diff --git a/Pipfile b/Pipfile index 82ec35158d..12de060a72 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ typing-extensions = "==4.2.0" [packages] aiohttp = "==3.8.1" colorama = "~=0.4.5" -"discord.py" = {ref = "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7", git = "https://github.com/Rapptz/discord.py.git"} +"discord.py" = "==2.0.0" emoji = "==1.7.0" isodate = "~=0.6.0" motor = "==2.5.1" diff --git a/Pipfile.lock b/Pipfile.lock index 87a2f247fc..ed19b5883c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "89578b9ae8a9a0b580e0af21767bd2f062388ad43c9bdc6e5d113de91361bea3" + "sha256": "aa752693f18b9d6058209883bdcece4e37a1a7a62a5fd564d64e551d91ea49f4" }, "pipfile-spec": 6, "requires": {}, @@ -110,11 +110,11 @@ }, "attrs": { "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" + "markers": "python_version >= '3.5'", + "version": "==22.1.0" }, "cairocffi": { "hashes": [ @@ -201,11 +201,11 @@ }, "charset-normalizer": { "hashes": [ - "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", - "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" + "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", + "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" ], "markers": "python_version >= '3.6'", - "version": "==2.1.0" + "version": "==2.1.1" }, "colorama": { "hashes": [ @@ -231,13 +231,13 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.7.1" }, - "discord-py": { - "git": "https://github.com/Rapptz/discord.py.git", - "ref": "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7" - }, "discord.py": { - "git": "https://github.com/Rapptz/discord.py.git", - "ref": "9fe19dcc6923e4b6133bdedafb33658bf37c9ab7" + "hashes": [ + "sha256:18b06870bdc85d29e0d55f4a4b2abe9d7cdae2b197e23d49f82886ba27ba1aec", + "sha256:c36f26935938194c3465c2abf8ecfbbf5560c50b189f1b746d6f00d1e78c0d3b" + ], + "index": "pypi", + "version": "==2.0.0" }, "dnspython": { "hashes": [ @@ -256,68 +256,68 @@ }, "frozenlist": { "hashes": [ - "sha256:006d3595e7d4108a12025ddf415ae0f6c9e736e726a5db0183326fd191b14c5e", - "sha256:01a73627448b1f2145bddb6e6c2259988bb8aee0fb361776ff8604b99616cd08", - "sha256:03a7dd1bfce30216a3f51a84e6dd0e4a573d23ca50f0346634916ff105ba6e6b", - "sha256:0437fe763fb5d4adad1756050cbf855bbb2bf0d9385c7bb13d7a10b0dd550486", - "sha256:04cb491c4b1c051734d41ea2552fde292f5f3a9c911363f74f39c23659c4af78", - "sha256:0c36e78b9509e97042ef869c0e1e6ef6429e55817c12d78245eb915e1cca7468", - "sha256:25af28b560e0c76fa41f550eacb389905633e7ac02d6eb3c09017fa1c8cdfde1", - "sha256:2fdc3cd845e5a1f71a0c3518528bfdbfe2efaf9886d6f49eacc5ee4fd9a10953", - "sha256:30530930410855c451bea83f7b272fb1c495ed9d5cc72895ac29e91279401db3", - "sha256:31977f84828b5bb856ca1eb07bf7e3a34f33a5cddce981d880240ba06639b94d", - "sha256:3c62964192a1c0c30b49f403495911298810bada64e4f03249ca35a33ca0417a", - "sha256:3f7c935c7b58b0d78c0beea0c7358e165f95f1fd8a7e98baa40d22a05b4a8141", - "sha256:40dff8962b8eba91fd3848d857203f0bd704b5f1fa2b3fc9af64901a190bba08", - "sha256:40ec383bc194accba825fbb7d0ef3dda5736ceab2375462f1d8672d9f6b68d07", - "sha256:436496321dad302b8b27ca955364a439ed1f0999311c393dccb243e451ff66aa", - "sha256:4406cfabef8f07b3b3af0f50f70938ec06d9f0fc26cbdeaab431cbc3ca3caeaa", - "sha256:45334234ec30fc4ea677f43171b18a27505bfb2dba9aca4398a62692c0ea8868", - "sha256:47be22dc27ed933d55ee55845d34a3e4e9f6fee93039e7f8ebadb0c2f60d403f", - "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b", - "sha256:4eda49bea3602812518765810af732229b4291d2695ed24a0a20e098c45a707b", - "sha256:57f4d3f03a18facacb2a6bcd21bccd011e3b75d463dc49f838fd699d074fabd1", - "sha256:603b9091bd70fae7be28bdb8aa5c9990f4241aa33abb673390a7f7329296695f", - "sha256:65bc6e2fece04e2145ab6e3c47428d1bbc05aede61ae365b2c1bddd94906e478", - "sha256:691ddf6dc50480ce49f68441f1d16a4c3325887453837036e0fb94736eae1e58", - "sha256:6983a31698490825171be44ffbafeaa930ddf590d3f051e397143a5045513b01", - "sha256:6a202458d1298ced3768f5a7d44301e7c86defac162ace0ab7434c2e961166e8", - "sha256:6eb275c6385dd72594758cbe96c07cdb9bd6becf84235f4a594bdf21e3596c9d", - "sha256:754728d65f1acc61e0f4df784456106e35afb7bf39cfe37227ab00436fb38676", - "sha256:768efd082074bb203c934e83a61654ed4931ef02412c2fbdecea0cff7ecd0274", - "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab", - "sha256:871d42623ae15eb0b0e9df65baeee6976b2e161d0ba93155411d58ff27483ad8", - "sha256:88aafd445a233dbbf8a65a62bc3249a0acd0d81ab18f6feb461cc5a938610d24", - "sha256:8c905a5186d77111f02144fab5b849ab524f1e876a1e75205cd1386a9be4b00a", - "sha256:8cf829bd2e2956066dd4de43fd8ec881d87842a06708c035b37ef632930505a2", - "sha256:92e650bd09b5dda929523b9f8e7f99b24deac61240ecc1a32aeba487afcd970f", - "sha256:93641a51f89473837333b2f8100f3f89795295b858cd4c7d4a1f18e299dc0a4f", - "sha256:94c7a8a9fc9383b52c410a2ec952521906d355d18fccc927fca52ab575ee8b93", - "sha256:9f892d6a94ec5c7b785e548e42722e6f3a52f5f32a8461e82ac3e67a3bd073f1", - "sha256:acb267b09a509c1df5a4ca04140da96016f40d2ed183cdc356d237286c971b51", - "sha256:adac9700675cf99e3615eb6a0eb5e9f5a4143c7d42c05cea2e7f71c27a3d0846", - "sha256:aff388be97ef2677ae185e72dc500d19ecaf31b698986800d3fc4f399a5e30a5", - "sha256:b5009062d78a8c6890d50b4e53b0ddda31841b3935c1937e2ed8c1bda1c7fb9d", - "sha256:b684c68077b84522b5c7eafc1dc735bfa5b341fb011d5552ebe0968e22ed641c", - "sha256:b9e3e9e365991f8cc5f5edc1fd65b58b41d0514a6a7ad95ef5c7f34eb49b3d3e", - "sha256:bd89acd1b8bb4f31b47072615d72e7f53a948d302b7c1d1455e42622de180eae", - "sha256:bde99812f237f79eaf3f04ebffd74f6718bbd216101b35ac7955c2d47c17da02", - "sha256:c6c321dd013e8fc20735b92cb4892c115f5cdb82c817b1e5b07f6b95d952b2f0", - "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b", - "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3", - "sha256:d26b650b71fdc88065b7a21f8ace70175bcf3b5bdba5ea22df4bfd893e795a3b", - "sha256:d6d32ff213aef0fd0bcf803bffe15cfa2d4fde237d1d4838e62aec242a8362fa", - "sha256:e1e26ac0a253a2907d654a37e390904426d5ae5483150ce3adedb35c8c06614a", - "sha256:e30b2f9683812eb30cf3f0a8e9f79f8d590a7999f731cf39f9105a7c4a39489d", - "sha256:e84cb61b0ac40a0c3e0e8b79c575161c5300d1d89e13c0e02f76193982f066ed", - "sha256:e982878792c971cbd60ee510c4ee5bf089a8246226dea1f2138aa0bb67aff148", - "sha256:f20baa05eaa2bcd5404c445ec51aed1c268d62600362dc6cfe04fae34a424bd9", - "sha256:f7353ba3367473d1d616ee727945f439e027f0bb16ac1a750219a8344d1d5d3c", - "sha256:f96293d6f982c58ebebb428c50163d010c2f05de0cde99fd681bfdc18d4b2dc2", - "sha256:ff9310f05b9d9c5c4dd472983dc956901ee6cb2c3ec1ab116ecdde25f3ce4951" + "sha256:022178b277cb9277d7d3b3f2762d294f15e85cd2534047e68a118c2bb0058f3e", + "sha256:086ca1ac0a40e722d6833d4ce74f5bf1aba2c77cbfdc0cd83722ffea6da52a04", + "sha256:0bc75692fb3770cf2b5856a6c2c9de967ca744863c5e89595df64e252e4b3944", + "sha256:0dde791b9b97f189874d654c55c24bf7b6782343e14909c84beebd28b7217845", + "sha256:12607804084d2244a7bd4685c9d0dca5df17a6a926d4f1967aa7978b1028f89f", + "sha256:19127f8dcbc157ccb14c30e6f00392f372ddb64a6ffa7106b26ff2196477ee9f", + "sha256:1b51eb355e7f813bcda00276b0114c4172872dc5fb30e3fea059b9367c18fbcb", + "sha256:1e1cf7bc8cbbe6ce3881863671bac258b7d6bfc3706c600008925fb799a256e2", + "sha256:219a9676e2eae91cb5cc695a78b4cb43d8123e4160441d2b6ce8d2c70c60e2f3", + "sha256:2743bb63095ef306041c8f8ea22bd6e4d91adabf41887b1ad7886c4c1eb43d5f", + "sha256:2af6f7a4e93f5d08ee3f9152bce41a6015b5cf87546cb63872cc19b45476e98a", + "sha256:31b44f1feb3630146cffe56344704b730c33e042ffc78d21f2125a6a91168131", + "sha256:31bf9539284f39ff9398deabf5561c2b0da5bb475590b4e13dd8b268d7a3c5c1", + "sha256:35c3d79b81908579beb1fb4e7fcd802b7b4921f1b66055af2578ff7734711cfa", + "sha256:3a735e4211a04ccfa3f4833547acdf5d2f863bfeb01cfd3edaffbc251f15cec8", + "sha256:42719a8bd3792744c9b523674b752091a7962d0d2d117f0b417a3eba97d1164b", + "sha256:49459f193324fbd6413e8e03bd65789e5198a9fa3095e03f3620dee2f2dabff2", + "sha256:4c0c99e31491a1d92cde8648f2e7ccad0e9abb181f6ac3ddb9fc48b63301808e", + "sha256:52137f0aea43e1993264a5180c467a08a3e372ca9d378244c2d86133f948b26b", + "sha256:526d5f20e954d103b1d47232e3839f3453c02077b74203e43407b962ab131e7b", + "sha256:53b2b45052e7149ee8b96067793db8ecc1ae1111f2f96fe1f88ea5ad5fd92d10", + "sha256:572ce381e9fe027ad5e055f143763637dcbac2542cfe27f1d688846baeef5170", + "sha256:58fb94a01414cddcdc6839807db77ae8057d02ddafc94a42faee6004e46c9ba8", + "sha256:5e77a8bd41e54b05e4fb2708dc6ce28ee70325f8c6f50f3df86a44ecb1d7a19b", + "sha256:5f271c93f001748fc26ddea409241312a75e13466b06c94798d1a341cf0e6989", + "sha256:5f63c308f82a7954bf8263a6e6de0adc67c48a8b484fab18ff87f349af356efd", + "sha256:61d7857950a3139bce035ad0b0945f839532987dfb4c06cfe160254f4d19df03", + "sha256:61e8cb51fba9f1f33887e22488bad1e28dd8325b72425f04517a4d285a04c519", + "sha256:625d8472c67f2d96f9a4302a947f92a7adbc1e20bedb6aff8dbc8ff039ca6189", + "sha256:6e19add867cebfb249b4e7beac382d33215d6d54476bb6be46b01f8cafb4878b", + "sha256:717470bfafbb9d9be624da7780c4296aa7935294bd43a075139c3d55659038ca", + "sha256:74140933d45271c1a1283f708c35187f94e1256079b3c43f0c2267f9db5845ff", + "sha256:74e6b2b456f21fc93ce1aff2b9728049f1464428ee2c9752a4b4f61e98c4db96", + "sha256:9494122bf39da6422b0972c4579e248867b6b1b50c9b05df7e04a3f30b9a413d", + "sha256:94e680aeedc7fd3b892b6fa8395b7b7cc4b344046c065ed4e7a1e390084e8cb5", + "sha256:97d9e00f3ac7c18e685320601f91468ec06c58acc185d18bb8e511f196c8d4b2", + "sha256:9c6ef8014b842f01f5d2b55315f1af5cbfde284eb184075c189fd657c2fd8204", + "sha256:a027f8f723d07c3f21963caa7d585dcc9b089335565dabe9c814b5f70c52705a", + "sha256:a718b427ff781c4f4e975525edb092ee2cdef6a9e7bc49e15063b088961806f8", + "sha256:ab386503f53bbbc64d1ad4b6865bf001414930841a870fc97f1546d4d133f141", + "sha256:ab6fa8c7871877810e1b4e9392c187a60611fbf0226a9e0b11b7b92f5ac72792", + "sha256:b47d64cdd973aede3dd71a9364742c542587db214e63b7529fbb487ed67cddd9", + "sha256:b499c6abe62a7a8d023e2c4b2834fce78a6115856ae95522f2f974139814538c", + "sha256:bbb1a71b1784e68870800b1bc9f3313918edc63dbb8f29fbd2e767ce5821696c", + "sha256:c3b31180b82c519b8926e629bf9f19952c743e089c41380ddca5db556817b221", + "sha256:c56c299602c70bc1bb5d1e75f7d8c007ca40c9d7aebaf6e4ba52925d88ef826d", + "sha256:c92deb5d9acce226a501b77307b3b60b264ca21862bd7d3e0c1f3594022f01bc", + "sha256:cc2f3e368ee5242a2cbe28323a866656006382872c40869b49b265add546703f", + "sha256:d82bed73544e91fb081ab93e3725e45dd8515c675c0e9926b4e1f420a93a6ab9", + "sha256:da1cdfa96425cbe51f8afa43e392366ed0b36ce398f08b60de6b97e3ed4affef", + "sha256:da5ba7b59d954f1f214d352308d1d86994d713b13edd4b24a556bcc43d2ddbc3", + "sha256:e0c8c803f2f8db7217898d11657cb6042b9b0553a997c4a0601f48a691480fab", + "sha256:ee4c5120ddf7d4dd1eaf079af3af7102b56d919fa13ad55600a4e0ebe532779b", + "sha256:eee0c5ecb58296580fc495ac99b003f64f82a74f9576a244d04978a7e97166db", + "sha256:f5abc8b4d0c5b556ed8cd41490b606fe99293175a82b98e652c3f2711b452988", + "sha256:f810e764617b0748b49a731ffaa525d9bb36ff38332411704c2400125af859a6", + "sha256:f89139662cc4e65a4813f4babb9ca9544e42bddb823d2ec434e18dad582543bc", + "sha256:fa47319a10e0a076709644a0efbcaab9e91902c8bd8ef74c6adb19d320f69b83", + "sha256:fabb953ab913dadc1ff9dcc3a7a7d3dc6a92efab3a0373989b8063347f8705be" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.3.1" }, "idna": { "hashes": [ @@ -505,7 +505,9 @@ "version": "==2.21" }, "pymongo": { - "extras": [], + "extras": [ + "srv" + ], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -681,81 +683,68 @@ }, "yarl": { "hashes": [ - "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac", - "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8", - "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e", - "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746", - "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98", - "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125", - "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d", - "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d", - "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986", - "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d", - "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec", - "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8", - "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee", - "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3", - "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1", - "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd", - "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b", - "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de", - "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0", - "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8", - "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6", - "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245", - "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23", - "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332", - "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1", - "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c", - "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4", - "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0", - "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8", - "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832", - "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58", - "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6", - "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1", - "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52", - "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92", - "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185", - "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d", - "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d", - "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b", - "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739", - "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05", - "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63", - "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d", - "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa", - "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913", - "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe", - "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b", - "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b", - "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656", - "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1", - "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4", - "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e", - "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63", - "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271", - "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed", - "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d", - "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda", - "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265", - "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f", - "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c", - "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba", - "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c", - "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b", - "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523", - "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a", - "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef", - "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95", - "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72", - "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794", - "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41", - "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576", - "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59" + "sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb", + "sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3", + "sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035", + "sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453", + "sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d", + "sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a", + "sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231", + "sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f", + "sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae", + "sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b", + "sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3", + "sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507", + "sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd", + "sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae", + "sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe", + "sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c", + "sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4", + "sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64", + "sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357", + "sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54", + "sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461", + "sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4", + "sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497", + "sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0", + "sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1", + "sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957", + "sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350", + "sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780", + "sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843", + "sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548", + "sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6", + "sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40", + "sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee", + "sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b", + "sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6", + "sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0", + "sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e", + "sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880", + "sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc", + "sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e", + "sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead", + "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28", + "sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf", + "sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd", + "sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae", + "sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0", + "sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0", + "sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae", + "sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda", + "sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546", + "sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802", + "sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be", + "sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07", + "sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936", + "sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272", + "sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc", + "sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a", + "sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28", + "sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b" ], - "markers": "python_version >= '3.6'", - "version": "==1.7.2" + "markers": "python_version >= '3.7'", + "version": "==1.8.1" } }, "develop": { @@ -910,11 +899,11 @@ }, "pbr": { "hashes": [ - "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a", - "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308" + "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a", + "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf" ], "markers": "python_version >= '2.6'", - "version": "==5.9.0" + "version": "==5.10.0" }, "platformdirs": { "hashes": [ @@ -973,11 +962,11 @@ }, "setuptools": { "hashes": [ - "sha256:16923d366ced322712c71ccb97164d07472abeecd13f3a6c283f6d5d26722793", - "sha256:db3b8e2f922b2a910a29804776c643ea609badb6a32c4bcc226fd4fd902cce65" + "sha256:7f4bc85450898a09f76ebf28b72fa25bc7111f6c7d665d514a60bba9c75ef2a9", + "sha256:a3ca5857c89f82f5c9410e8508cb32f4872a3bafd4aa7ae122a24ca33bccc750" ], "markers": "python_version >= '3.7'", - "version": "==63.1.0" + "version": "==65.2.0" }, "smmap": { "hashes": [ @@ -989,11 +978,11 @@ }, "stevedore": { "hashes": [ - "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c", - "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335" + "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8", + "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786" ], - "markers": "python_version >= '3.6'", - "version": "==3.5.0" + "markers": "python_version >= '3.8'", + "version": "==4.0.0" }, "toml": { "hashes": [ diff --git a/bot.py b/bot.py index f3d7198428..fb373f9e76 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev16" +__version__ = "4.0.0-dev17" import asyncio @@ -1769,9 +1769,9 @@ def main(): sys.exit(0) # check discord version - if discord.__version__ != "2.0.0a": + if discord.__version__ != "2.0.0": logger.error( - "Dependencies are not updated, run pipenv install. discord.py version expected 2.0.0a, received %s", + "Dependencies are not updated, run pipenv install. discord.py version expected 2.0.0, received %s", discord.__version__, ) sys.exit(0) diff --git a/pyproject.toml b/pyproject.toml index 7c1dc0e952..b3dea8293f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev16' +version = '4.0.0-dev17' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 57eca05d471fd5e68b8e25c889e33dcb6522bcef Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Aug 2022 22:21:20 +0800 Subject: [PATCH 565/705] Skip loading of already-loaded cog #3172 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0070eecf0a..44097a7527 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Old data causing `?blocked` to fail. ([GH #3131](https://github.com/kyb3r/modmail/issues/3131)) - Delete channel auto close functionality now works. - Improved error handling for autoupdate. ([PR #3161](https://github.com/kyb3r/modmail/pull/3161)) +- Skip loading of already-loaded cog. ([PR #3172](https://github.com/kyb3r/modmail/pull/3172)) ### Internal From 48ad5c4ee6f92b86d32737568ae94d8637f70219 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Mon, 22 Aug 2022 22:22:47 +0800 Subject: [PATCH 566/705] snippet make create aliases, resolve #3172, close #3174 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44097a7527..27165ebda8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Select menus for certain paginators. - `Title` field in `?logs`. ([GH #3142](https://github.com/kyb3r/modmail/issues/3142)) - Snippets can be used in aliases. ([GH #3108](https://github.com/kyb3r/modmail/issues/3108), [PR #3124](https://github.com/kyb3r/modmail/pull/3124)) +- `?snippet make/create` as aliases to `?snippet add`. ([GH #3172](https://github.com/kyb3r/modmail/issues/3173), [PR #3174](https://github.com/kyb3r/modmail/pull/3174)) ### Improved From f68d8a20861eb851f2713b796f639b44ba6b16c0 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <hidzrie@gmail.com> Date: Wed, 24 Aug 2022 14:10:48 +0000 Subject: [PATCH 567/705] Add `unhandled_by_cog` parameter to `ModmailBot.on_command_error`: - Resolve #3170 --- bot.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 5b71c9bc71..6ea42499cb 100644 --- a/bot.py +++ b/bot.py @@ -1511,7 +1511,17 @@ async def on_error(self, event_method, *args, **kwargs): logger.error("Ignoring exception in %s.", event_method) logger.error("Unexpected exception:", exc_info=sys.exc_info()) - async def on_command_error(self, context, exception): + async def on_command_error( + self, context: commands.Context, exception: Exception, *, unhandled_by_cog: bool = False + ) -> None: + if not unhandled_by_cog: + command = context.command + if command and command.has_error_handler(): + return + cog = context.cog + if cog and cog.has_error_handler(): + return + if isinstance(exception, (commands.BadArgument, commands.BadUnionArgument)): await context.typing() await context.send(embed=discord.Embed(color=self.error_color, description=str(exception))) From fa3ad60af794c5fe766697f6c070a43d21840cfe Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 6 Sep 2022 22:36:26 +0800 Subject: [PATCH 568/705] Update to discord.py 2.0.1 and fix time module --- Pipfile | 2 +- Pipfile.lock | 27 +-- bot.py | 15 +- cogs/modmail.py | 10 +- core/config.py | 7 +- core/time.py | 436 ++++++++++++++++++++++++++++++----------------- core/utils.py | 17 +- pyproject.toml | 2 +- requirements.txt | 2 +- 9 files changed, 333 insertions(+), 185 deletions(-) diff --git a/Pipfile b/Pipfile index 12de060a72..573f06cb76 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ typing-extensions = "==4.2.0" [packages] aiohttp = "==3.8.1" colorama = "~=0.4.5" -"discord.py" = "==2.0.0" +"discord.py" = "==2.0.1" emoji = "==1.7.0" isodate = "~=0.6.0" motor = "==2.5.1" diff --git a/Pipfile.lock b/Pipfile.lock index ed19b5883c..9657e2b273 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "aa752693f18b9d6058209883bdcece4e37a1a7a62a5fd564d64e551d91ea49f4" + "sha256": "c074bd9564d93aac78141ccfec1138ffeb561dfa0956f60ee5b10322d156d20f" }, "pipfile-spec": 6, "requires": {}, @@ -233,11 +233,11 @@ }, "discord.py": { "hashes": [ - "sha256:18b06870bdc85d29e0d55f4a4b2abe9d7cdae2b197e23d49f82886ba27ba1aec", - "sha256:c36f26935938194c3465c2abf8ecfbbf5560c50b189f1b746d6f00d1e78c0d3b" + "sha256:309146476e986cb8faf038cd5d604d4b3834ef15c2d34df697ce5064bf5cd779", + "sha256:aeb186348bf011708b085b2715cf92bbb72c692eb4f59c4c0b488130cc4c4b7e" ], "index": "pypi", - "version": "==2.0.0" + "version": "==2.0.1" }, "dnspython": { "hashes": [ @@ -450,6 +450,7 @@ "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", + "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437", "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", @@ -478,6 +479,7 @@ "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", + "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc", "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", @@ -505,9 +507,7 @@ "version": "==2.21" }, "pymongo": { - "extras": [ - "srv" - ], + "extras": [], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -892,10 +892,11 @@ }, "pathspec": { "hashes": [ - "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", - "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1" + "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93", + "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d" ], - "version": "==0.9.0" + "markers": "python_version >= '3.7'", + "version": "==0.10.1" }, "pbr": { "hashes": [ @@ -962,11 +963,11 @@ }, "setuptools": { "hashes": [ - "sha256:7f4bc85450898a09f76ebf28b72fa25bc7111f6c7d665d514a60bba9c75ef2a9", - "sha256:a3ca5857c89f82f5c9410e8508cb32f4872a3bafd4aa7ae122a24ca33bccc750" + "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82", + "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57" ], "markers": "python_version >= '3.7'", - "version": "==65.2.0" + "version": "==65.3.0" }, "smmap": { "hashes": [ diff --git a/bot.py b/bot.py index 5b71c9bc71..ffc2c01dc6 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev17" +__version__ = "4.0.0-dev18" import asyncio @@ -18,6 +18,7 @@ import discord import isodate from aiohttp import ClientSession, ClientResponseError +from discord.utils import MISSING from discord.ext import commands, tasks from discord.ext.commands.view import StringView from emoji import UNICODE_EMOJI @@ -247,10 +248,10 @@ async def runner(): except Exception: logger.critical("Fatal exception", exc_info=True) finally: - if not self.is_closed(): - await self.close() if self.session: await self.session.close() + if not self.is_closed(): + await self.close() async def _cancel_tasks(): async with self: @@ -282,7 +283,7 @@ async def _cancel_tasks(): pass try: - asyncio.run(runner()) + asyncio.run(runner(), debug=bool(os.getenv("DEBUG_ASYNCIO"))) except (KeyboardInterrupt, SystemExit): logger.info("Received signal to terminate bot and event loop.") finally: @@ -1771,9 +1772,11 @@ def main(): sys.exit(0) # check discord version - if discord.__version__ != "2.0.0": + discord_version = "2.0.1" + if discord.__version__ != discord_version: logger.error( - "Dependencies are not updated, run pipenv install. discord.py version expected 2.0.0, received %s", + "Dependencies are not updated, run pipenv install. discord.py version expected %s, received %s", + discord_version, discord.__version__, ) sys.exit(0) diff --git a/cogs/modmail.py b/cogs/modmail.py index 7fc9e5b975..a623ed3cdd 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -2,6 +2,7 @@ import re from datetime import datetime, timezone from itertools import zip_longest +import time from typing import Optional, Union, List, Tuple from types import SimpleNamespace @@ -1848,14 +1849,17 @@ async def block( return await ctx.send(embed=embed) reason = f"by {escape_markdown(ctx.author.name)}#{ctx.author.discriminator}" + now = discord.utils.utcnow() if after is not None: if "%" in reason: raise commands.BadArgument('The reason contains illegal character "%".') + unixtime = int(after.dt.replace(tzinfo=timezone.utc).timestamp()) + if after.arg: - reason += f" for `{after.arg}`" - if after.dt > after.now: - reason += f" until {after.dt.isoformat()}" + reason += f" until: <t:{unixtime}:R>" + if after.dt > now: + reason += f" until <t:{unixtime}:f>" reason += "." diff --git a/core/config.py b/core/config.py index 6cff7f0bd7..dd76776092 100644 --- a/core/config.py +++ b/core/config.py @@ -13,7 +13,7 @@ from core._color_data import ALL_COLORS from core.models import DMDisabled, InvalidConfigError, Default, getLogger -from core.time import UserFriendlyTimeSync +from core.time import UserFriendlyTime from core.utils import strtobool logger = getLogger(__name__) @@ -400,7 +400,7 @@ def set(self, key: str, item: typing.Any, convert=True) -> None: isodate.parse_duration(item) except isodate.ISO8601Error: try: - converter = UserFriendlyTimeSync() + converter = UserFriendlyTime() time = converter.convert(None, item) if time.arg: raise ValueError @@ -412,7 +412,8 @@ def set(self, key: str, item: typing.Any, convert=True) -> None: "Unrecognized time, please use ISO-8601 duration format " 'string or a simpler "human readable" time.' ) - item = isodate.duration_isoformat(time.dt - converter.now) + now = discord.utils.utcnow() + item = isodate.duration_isoformat(time.dt - now) return self.__setitem__(key, item) if key in self.booleans: diff --git a/core/time.py b/core/time.py index 26b41b9043..b66f84757f 100644 --- a/core/time.py +++ b/core/time.py @@ -3,223 +3,353 @@ Source: https://github.com/Rapptz/RoboDanny/blob/rewrite/cogs/utils/time.py """ -import re -from datetime import datetime - -import discord -from discord.ext.commands import BadArgument, Converter +from __future__ import annotations +import datetime +from typing import TYPE_CHECKING, Any, Optional, Union import parsedatetime as pdt from dateutil.relativedelta import relativedelta +from .utils import human_join +from discord.ext import commands +from discord import app_commands +import re + +# Monkey patch mins and secs into the units +units = pdt.pdtLocales["en_US"].units +units["minutes"].append("mins") +units["seconds"].append("secs") -from core.models import getLogger +if TYPE_CHECKING: + from typing_extensions import Self + from cogs.utils.context import Context -logger = getLogger(__name__) +class plural: + """https://github.com/Rapptz/RoboDanny/blob/bf7d4226350dff26df4981dd53134eeb2aceeb87/cogs/utils/formats.py#L8-L18""" + + def __init__(self, value: int): + self.value: int = value + + def __format__(self, format_spec: str) -> str: + v = self.value + singular, sep, plural = format_spec.partition("|") + plural = plural or f"{singular}s" + if abs(v) != 1: + return f"{v} {plural}" + return f"{v} {singular}" + + +def format_dt(dt: datetime.datetime, style: Optional[str] = None) -> str: + """https://github.com/Rapptz/RoboDanny/blob/bf7d4226350dff26df4981dd53134eeb2aceeb87/cogs/utils/formats.py#L89-L95""" + if dt.tzinfo is None: + dt = dt.replace(tzinfo=datetime.timezone.utc) + + if style is None: + return f"<t:{int(dt.timestamp())}>" + return f"<t:{int(dt.timestamp())}:{style}>" class ShortTime: compiled = re.compile( - r""" - (?:(?P<years>[0-9])(?:years?|y))? # e.g. 2y - (?:(?P<months>[0-9]{1,2})(?:months?|mo))? # e.g. 9mo - (?:(?P<weeks>[0-9]{1,4})(?:weeks?|w))? # e.g. 10w - (?:(?P<days>[0-9]{1,5})(?:days?|d))? # e.g. 14d - (?:(?P<hours>[0-9]{1,5})(?:hours?|h))? # e.g. 12h - (?:(?P<minutes>[0-9]{1,5})(?:min(?:ute)?s?|m))? # e.g. 10m - (?:(?P<seconds>[0-9]{1,5})(?:sec(?:ond)?s?|s))? # e.g. 15s - """, + """ + (?:(?P<years>[0-9])(?:years?|y))? # e.g. 2y + (?:(?P<months>[0-9]{1,2})(?:months?|mo))? # e.g. 2months + (?:(?P<weeks>[0-9]{1,4})(?:weeks?|w))? # e.g. 10w + (?:(?P<days>[0-9]{1,5})(?:days?|d))? # e.g. 14d + (?:(?P<hours>[0-9]{1,5})(?:hours?|h))? # e.g. 12h + (?:(?P<minutes>[0-9]{1,5})(?:minutes?|m))? # e.g. 10m + (?:(?P<seconds>[0-9]{1,5})(?:seconds?|s))? # e.g. 15s + """, re.VERBOSE, ) - def __init__(self, argument): + discord_fmt = re.compile(r"<t:(?P<ts>[0-9]+)(?:\:?[RFfDdTt])?>") + + dt: datetime.datetime + + def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): match = self.compiled.fullmatch(argument) if match is None or not match.group(0): - raise BadArgument("Invalid time provided.") + match = self.discord_fmt.fullmatch(argument) + if match is not None: + self.dt = datetime.datetime.fromtimestamp(int(match.group("ts")), tz=datetime.timezone.utc) + return + else: + raise commands.BadArgument("invalid time provided") - data = {k: int(v) for k, v in match.groupdict(default="0").items()} - now = discord.utils.utcnow() + data = {k: int(v) for k, v in match.groupdict(default=0).items()} + now = now or datetime.datetime.now(datetime.timezone.utc) self.dt = now + relativedelta(**data) - -# Monkey patch mins and secs into the units -units = pdt.pdtLocales["en_US"].units -units["minutes"].append("mins") -units["seconds"].append("secs") + @classmethod + async def convert(cls, ctx: Context, argument: str) -> Self: + return cls(argument, now=ctx.message.created_at) class HumanTime: calendar = pdt.Calendar(version=pdt.VERSION_CONTEXT_STYLE) - def __init__(self, argument): - now = discord.utils.utcnow() + def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): + now = now or datetime.datetime.utcnow() dt, status = self.calendar.parseDT(argument, sourceTime=now) if not status.hasDateOrTime: - raise BadArgument('Invalid time provided, try e.g. "tomorrow" or "3 days".') + raise commands.BadArgument('invalid time provided, try e.g. "tomorrow" or "3 days"') if not status.hasTime: # replace it with the current time dt = dt.replace(hour=now.hour, minute=now.minute, second=now.second, microsecond=now.microsecond) - self.dt = dt - self._past = dt < now + self.dt: datetime.datetime = dt + self._past: bool = dt < now + + @classmethod + async def convert(cls, ctx: Context, argument: str) -> Self: + return cls(argument, now=ctx.message.created_at) class Time(HumanTime): - def __init__(self, argument): + def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): try: - short_time = ShortTime(argument) - except Exception: + o = ShortTime(argument, now=now) + except Exception as e: super().__init__(argument) else: - self.dt = short_time.dt + self.dt = o.dt self._past = False class FutureTime(Time): - def __init__(self, argument): - super().__init__(argument) + def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): + super().__init__(argument, now=now) if self._past: - raise BadArgument("The time is in the past.") + raise commands.BadArgument("this time is in the past") -class UserFriendlyTimeSync(Converter): - """That way quotes aren't absolutely necessary.""" +class BadTimeTransform(app_commands.AppCommandError): + pass + + +class TimeTransformer(app_commands.Transformer): + async def transform(self, interaction, value: str) -> datetime.datetime: + now = interaction.created_at + try: + short = ShortTime(value, now=now) + except commands.BadArgument: + try: + human = FutureTime(value, now=now) + except commands.BadArgument as e: + raise BadTimeTransform(str(e)) from None + else: + return human.dt + else: + return short.dt + + +class FriendlyTimeResult: + dt: datetime.datetime + arg: str - def __init__(self): - self.raw: str = None - self.dt: datetime = None - self.arg = None - self.now: datetime = None + __slots__ = ("dt", "arg") - def check_constraints(self, now, remaining): + def __init__(self, dt: datetime.datetime): + self.dt = dt + self.arg = "" + + async def ensure_constraints( + self, ctx: Context, uft: UserFriendlyTime, now: datetime.datetime, remaining: str + ) -> None: if self.dt < now: - raise BadArgument("This time is in the past.") + raise commands.BadArgument("This time is in the past.") - self.arg = remaining - return self + # if not remaining: + # if uft.default is None: + # raise commands.BadArgument("Missing argument after the time.") + # remaining = uft.default - def convert(self, ctx, argument): - self.raw = argument - remaining = "" - try: - calendar = HumanTime.calendar - regex = ShortTime.compiled - self.dt = self.now = discord.utils.utcnow() + if uft.converter is not None: + self.arg = await uft.converter.convert(ctx, remaining) + else: + self.arg = remaining - match = regex.match(argument) - if match is not None and match.group(0): - data = {k: int(v) for k, v in match.groupdict(default="0").items()} - remaining = argument[match.end() :].strip() - self.dt = self.now + relativedelta(**data) - return self.check_constraints(self.now, remaining) - - # apparently nlp does not like "from now" - # it likes "from x" in other cases though - # so let me handle the 'now' case - if argument.endswith(" from now"): - argument = argument[:-9].strip() - # handles "in xxx hours" - if argument.startswith("in "): - argument = argument[3:].strip() - - elements = calendar.nlp(argument, sourceTime=self.now) - if elements is None or not elements: - return self.check_constraints(self.now, argument) - - # handle the following cases: - # "date time" foo - # date time foo - # foo date time - - # first the first two cases: - dt, status, begin, end, _ = elements[0] - - if not status.hasDateOrTime: - return self.check_constraints(self.now, argument) - - if begin not in (0, 1) and end != len(argument): - raise BadArgument( - "Time is either in an inappropriate location, which must " - "be either at the end or beginning of your input, or I " - "just flat out did not understand what you meant. Sorry." - ) - if not status.hasTime: - # replace it with the current time - dt = dt.replace( - hour=self.now.hour, - minute=self.now.minute, - second=self.now.second, - microsecond=self.now.microsecond, - ) +class UserFriendlyTime(commands.Converter): + """That way quotes aren't absolutely necessary.""" - # if midnight is provided, just default to next day - if status.accuracy == pdt.pdtContext.ACU_HALFDAY: - dt = dt.replace(day=self.now.day + 1) + def __init__( + self, + converter: Optional[Union[type[commands.Converter], commands.Converter]] = None, + *, + default: Any = None, + ): + if isinstance(converter, type) and issubclass(converter, commands.Converter): + converter = converter() + + if converter is not None and not isinstance(converter, commands.Converter): + raise TypeError("commands.Converter subclass necessary.") + + self.converter: commands.Converter = converter # type: ignore # It doesn't understand this narrowing + self.default: Any = default + + async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult: + calendar = HumanTime.calendar + regex = ShortTime.compiled + now = ctx.message.created_at + + match = regex.match(argument) + if match is not None and match.group(0): + data = {k: int(v) for k, v in match.groupdict(default=0).items()} + remaining = argument[match.end() :].strip() + result = FriendlyTimeResult(now + relativedelta(**data)) + await result.ensure_constraints(ctx, self, now, remaining) + return result - self.dt = dt + if match is None or not match.group(0): + match = ShortTime.discord_fmt.match(argument) + if match is not None: + result = FriendlyTimeResult( + datetime.datetime.fromtimestamp(int(match.group("ts")), tz=datetime.timezone.utc) + ) + remaining = argument[match.end() :].strip() + await result.ensure_constraints(ctx, self, now, remaining) + return result - if begin in (0, 1): - if begin == 1: - # check if it's quoted: - if argument[0] != '"': - raise BadArgument("Expected quote before time input...") + # apparently nlp does not like "from now" + # it likes "from x" in other cases though so let me handle the 'now' case + if argument.endswith("from now"): + argument = argument[:-8].strip() - if not (end < len(argument) and argument[end] == '"'): - raise BadArgument("If the time is quoted, you must unquote it.") + if argument[0:2] == "me": + # starts with "me to", "me in", or "me at " + if argument[0:6] in ("me to ", "me in ", "me at "): + argument = argument[6:] - remaining = argument[end + 1 :].lstrip(" ,.!") - else: - remaining = argument[end:].lstrip(" ,.!") - elif len(argument) == end: - remaining = argument[:begin].strip() + elements = calendar.nlp(argument, sourceTime=now) + if elements is None or len(elements) == 0: + raise commands.BadArgument('Invalid time provided, try e.g. "tomorrow" or "3 days".') - return self.check_constraints(self.now, remaining) - except Exception: - logger.exception("Something went wrong while parsing the time.") - raise + # handle the following cases: + # "date time" foo + # date time foo + # foo date time + # first the first two cases: + dt, status, begin, end, dt_string = elements[0] -class UserFriendlyTime(UserFriendlyTimeSync): - async def convert(self, ctx, argument): - return super().convert(ctx, argument) + if not status.hasDateOrTime: + raise commands.BadArgument('Invalid time provided, try e.g. "tomorrow" or "3 days".') + if begin not in (0, 1) and end != len(argument): + raise commands.BadArgument( + "Time is either in an inappropriate location, which " + "must be either at the end or beginning of your input, " + "or I just flat out did not understand what you meant. Sorry." + ) -def human_timedelta(dt, *, spec="R"): - if spec == "manual": - now = discord.utils.utcnow() - if dt > now: - delta = relativedelta(dt, now) - suffix = "" - else: - delta = relativedelta(now, dt) - suffix = " ago" + if not status.hasTime: + # replace it with the current time + dt = dt.replace(hour=now.hour, minute=now.minute, second=now.second, microsecond=now.microsecond) + + # if midnight is provided, just default to next day + if status.accuracy == pdt.pdtContext.ACU_HALFDAY: + dt = dt.replace(day=now.day + 1) - if delta.microseconds and delta.seconds: - delta = delta + relativedelta(seconds=+1) + result = FriendlyTimeResult(dt.replace(tzinfo=datetime.timezone.utc)) + remaining = "" - attrs = ["years", "months", "days", "hours", "minutes", "seconds"] + if begin in (0, 1): + if begin == 1: + # check if it's quoted: + if argument[0] != '"': + raise commands.BadArgument("Expected quote before time input...") - output = [] - for attr in attrs: - elem = getattr(delta, attr) - if not elem: - continue + if not (end < len(argument) and argument[end] == '"'): + raise commands.BadArgument("If the time is quoted, you must unquote it.") - if elem > 1: - output.append(f"{elem} {attr}") + remaining = argument[end + 1 :].lstrip(" ,.!") else: - output.append(f"{elem} {attr[:-1]}") - - if not output: - return "now" - if len(output) == 1: - return output[0] + suffix - if len(output) == 2: - return f"{output[0]} and {output[1]}{suffix}" - return f"{output[0]}, {output[1]} and {output[2]}{suffix}" + remaining = argument[end:].lstrip(" ,.!") + elif len(argument) == end: + remaining = argument[:begin].strip() + + await result.ensure_constraints(ctx, self, now, remaining) + return result + + +def human_timedelta( + dt: datetime.datetime, + *, + source: Optional[datetime.datetime] = None, + accuracy: Optional[int] = 3, + brief: bool = False, + suffix: bool = True, +) -> str: + now = source or datetime.datetime.now(datetime.timezone.utc) + if dt.tzinfo is None: + dt = dt.replace(tzinfo=datetime.timezone.utc) + + if now.tzinfo is None: + now = now.replace(tzinfo=datetime.timezone.utc) + + # Microsecond free zone + now = now.replace(microsecond=0) + dt = dt.replace(microsecond=0) + + # This implementation uses relativedelta instead of the much more obvious + # divmod approach with seconds because the seconds approach is not entirely + # accurate once you go over 1 week in terms of accuracy since you have to + # hardcode a month as 30 or 31 days. + # A query like "11 months" can be interpreted as "!1 months and 6 days" + if dt > now: + delta = relativedelta(dt, now) + output_suffix = "" else: - unixtime = int(dt.timestamp()) - return f"<t:{unixtime}:{spec}>" + delta = relativedelta(now, dt) + output_suffix = " ago" if suffix else "" + + attrs = [ + ("year", "y"), + ("month", "mo"), + ("day", "d"), + ("hour", "h"), + ("minute", "m"), + ("second", "s"), + ] + + output = [] + for attr, brief_attr in attrs: + elem = getattr(delta, attr + "s") + if not elem: + continue + + if attr == "day": + weeks = delta.weeks + if weeks: + elem -= weeks * 7 + if not brief: + output.append(format(plural(weeks), "week")) + else: + output.append(f"{weeks}w") + + if elem <= 0: + continue + + if brief: + output.append(f"{elem}{brief_attr}") + else: + output.append(format(plural(elem), attr)) + + if accuracy is not None: + output = output[:accuracy] + + if len(output) == 0: + return "now" + else: + if not brief: + return human_join(output, final="and") + output_suffix + else: + return " ".join(output) + output_suffix + + +def format_relative(dt: datetime.datetime) -> str: + return format_dt(dt, "R") diff --git a/core/utils.py b/core/utils.py index 30efb05e75..ce28f243c1 100644 --- a/core/utils.py +++ b/core/utils.py @@ -172,10 +172,19 @@ def parse_image_url(url: str, *, convert_size=True) -> str: return "" -def human_join(strings): - if len(strings) <= 2: - return " or ".join(strings) - return ", ".join(strings[: len(strings) - 1]) + " or " + strings[-1] +def human_join(seq: typing.Sequence[str], delim: str = ", ", final: str = "or") -> str: + """https://github.com/Rapptz/RoboDanny/blob/bf7d4226350dff26df4981dd53134eeb2aceeb87/cogs/utils/formats.py#L21-L32""" + size = len(seq) + if size == 0: + return "" + + if size == 1: + return seq[0] + + if size == 2: + return f"{seq[0]} {final} {seq[1]}" + + return delim.join(seq[:-1]) + f" {final} {seq[-1]}" def days(day: typing.Union[str, int]) -> str: diff --git a/pyproject.toml b/pyproject.toml index b3dea8293f..b1826a921d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev17' +version = '4.0.0-dev18' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ diff --git a/requirements.txt b/requirements.txt index edc784029b..313426315e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,7 @@ defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' emoji==1.7.0 frozenlist==1.3.0; python_version >= '3.7' -git+https://github.com/Rapptz/discord.py.git@e9c7c09ebfe780d8f9de1e9e4d3c2dddf85eccfd#egg=discord.py +discord.py==2.0.1 idna==3.3; python_version >= '3.5' isodate==0.6.1 lottie[pdf]==0.6.11 From 3ea3cf2f8cbc67e39e9a85beb7bfb88934aca22d Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 6 Sep 2022 22:40:54 +0800 Subject: [PATCH 569/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27165ebda8..0d32c078b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Delete channel auto close functionality now works. - Improved error handling for autoupdate. ([PR #3161](https://github.com/kyb3r/modmail/pull/3161)) - Skip loading of already-loaded cog. ([PR #3172](https://github.com/kyb3r/modmail/pull/3172)) +- Respect plugin's `cog_command_error`. ([GH #3170](https://github.com/kyb3r/modmail/issues/3170), [PR #3178](https://github.com/kyb3r/modmail/pull/3178)) ### Internal From ecffec2604e8e52b9248f1971751996dc383c461 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 6 Sep 2022 23:01:09 +0800 Subject: [PATCH 570/705] use silent as typing literal, resolve #3179 --- CHANGELOG.md | 1 + cogs/modmail.py | 26 ++++++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d32c078b1..8789209eb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Improved error handling for autoupdate. ([PR #3161](https://github.com/kyb3r/modmail/pull/3161)) - Skip loading of already-loaded cog. ([PR #3172](https://github.com/kyb3r/modmail/pull/3172)) - Respect plugin's `cog_command_error`. ([GH #3170](https://github.com/kyb3r/modmail/issues/3170), [PR #3178](https://github.com/kyb3r/modmail/pull/3178)) +- Use silent as a typing literal for contacting. ([GH #3179](https://github.com/kyb3r/modmail/issues/3179)) ### Internal diff --git a/cogs/modmail.py b/cogs/modmail.py index a623ed3cdd..68c4c4715d 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -3,7 +3,7 @@ from datetime import datetime, timezone from itertools import zip_longest import time -from typing import Optional, Union, List, Tuple +from typing import Optional, Union, List, Tuple, Literal from types import SimpleNamespace import discord @@ -1500,9 +1500,9 @@ async def selfcontact(self, ctx): async def contact( self, ctx, - users: commands.Greedy[Union[discord.Member, discord.User, discord.Role]], + users: commands.Greedy[Union[Literal["silent", "silently"], discord.Member, discord.User, discord.Role]], *, - category: Union[SimilarCategoryConverter, str] = None, + category: SimilarCategoryConverter = None, manual_trigger=True, ): """ @@ -1516,16 +1516,22 @@ async def contact( A maximum of 5 users are allowed. `options` can be `silent` or `silently`. """ - silent = False + silent = any(x in users for x in ("silent", "silently")) + if silent: + try: + users.remove("silent") + except ValueError: + pass + + try: + users.remove("silently") + except ValueError: + pass + + print(users, silent) if isinstance(category, str): category = category.split() - # just check the last element in the list - if category[-1].lower() in ("silent", "silently"): - silent = True - # remove the last element as we no longer need it - category.pop() - category = " ".join(category) if category: try: From 7b0c360dd249f9dd6cc75b8f0c1cfc2f76ddc91e Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 6 Sep 2022 23:01:19 +0800 Subject: [PATCH 571/705] fix formatting --- cogs/modmail.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 68c4c4715d..a21dc205b4 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1500,7 +1500,9 @@ async def selfcontact(self, ctx): async def contact( self, ctx, - users: commands.Greedy[Union[Literal["silent", "silently"], discord.Member, discord.User, discord.Role]], + users: commands.Greedy[ + Union[Literal["silent", "silently"], discord.Member, discord.User, discord.Role] + ], *, category: SimilarCategoryConverter = None, manual_trigger=True, From 60e8444a46c7f94ab923e0cd0c2ca8351172985a Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 6 Sep 2022 23:01:50 +0800 Subject: [PATCH 572/705] bump ver --- bot.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index 846eccd3ac..b05d1435c8 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev18" +__version__ = "4.0.0-dev19" import asyncio diff --git a/pyproject.toml b/pyproject.toml index b1826a921d..9a22625dba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev18' +version = '4.0.0-dev19' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From ec399c3e579ff31492ad7223a9242809b4f9bb7d Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 6 Sep 2022 23:07:24 +0800 Subject: [PATCH 573/705] Autoupdate now automatically updates pipenv dependencies if possible --- CHANGELOG.md | 1 + bot.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8789209eb1..e584286230 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Use discord relative timedeltas. ([GH #3046](https://github.com/kyb3r/modmail/issues/3046)) - Use discord native buttons for all paginator sessions. - `?help` and `?blocked` paginator sessions now have better multi-page UI. +- Autoupdate now automatically updates pipenv dependencies if possible. ### Fixed diff --git a/bot.py b/bot.py index b05d1435c8..418916b528 100644 --- a/bot.py +++ b/bot.py @@ -1674,17 +1674,28 @@ async def autoupdate(self): return elif res != "Already up to date.": + if os.getenv("PIPENV_ACTIVE"): + # Update pipenv if possible + await asyncio.create_subprocess_shell( + "pipenv sync", + stderr=PIPE, + stdout=PIPE, + ) + message = "" + else: + message = "\n\nDo manually update dependencies if your bot has crashed." + logger.info("Bot has been updated.") channel = self.update_channel if self.hosting_method in (HostingMethod.PM2, HostingMethod.SYSTEMD): embed = discord.Embed(title="Bot has been updated", color=self.main_color) - embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version} {message}") if self.config["update_notifications"]: await channel.send(embed=embed) else: embed = discord.Embed( title="Bot has been updated and is logging out.", - description="If you do not have an auto-restart setup, please manually start the bot.", + description=f"If you do not have an auto-restart setup, please manually start the bot. {message}", color=self.main_color, ) embed.set_footer(text=f"Updating Modmail v{self.version} -> v{latest.version}") From ddc34c0624e5b18c4f24f923813d79ccfd94424f Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 6 Sep 2022 23:07:40 +0800 Subject: [PATCH 574/705] formatting --- bot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 418916b528..a990ac772c 100644 --- a/bot.py +++ b/bot.py @@ -1689,7 +1689,9 @@ async def autoupdate(self): channel = self.update_channel if self.hosting_method in (HostingMethod.PM2, HostingMethod.SYSTEMD): embed = discord.Embed(title="Bot has been updated", color=self.main_color) - embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version} {message}") + embed.set_footer( + text=f"Updating Modmail v{self.version} " f"-> v{latest.version} {message}" + ) if self.config["update_notifications"]: await channel.send(embed=embed) else: From 1d3aac9bec0ea71f8f06720e33d5d04f7ac0b047 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 7 Sep 2022 00:09:51 +0800 Subject: [PATCH 575/705] Fix time args, and use literals for close --- cogs/modmail.py | 19 +++++++------------ core/time.py | 29 +++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index a21dc205b4..279df07dd6 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -464,7 +464,7 @@ async def send_scheduled_close_message(self, ctx, after, silent=False): @commands.command(usage="[after] [close message]") @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() - async def close(self, ctx, *, after: UserFriendlyTime = None): + async def close(self, ctx, option: Optional[Literal["silent", "silently", "cancel"]]='', *, after: UserFriendlyTime = None): """ Close the current thread. @@ -486,15 +486,11 @@ async def close(self, ctx, *, after: UserFriendlyTime = None): thread = ctx.thread - now = discord.utils.utcnow() - - close_after = (after.dt - now).total_seconds() if after else 0 - message = after.arg if after else None - silent = str(message).lower() in {"silent", "silently"} - cancel = str(message).lower() == "cancel" + close_after = (after.dt - after.now).total_seconds() if after else 0 + silent = any(x == option for x in {"silent", "silently"}) + cancel = option == "cancel" if cancel: - if thread.close_task is not None or thread.auto_close_task is not None: await thread.cancel_closure(all=True) embed = discord.Embed( @@ -508,10 +504,11 @@ async def close(self, ctx, *, after: UserFriendlyTime = None): return await ctx.send(embed=embed) + message = after.arg if after else None if self.bot.config["require_close_reason"] and message is None: raise commands.BadArgument("Provide a reason for closing the thread.") - if after and after.dt > now: + if after and after.dt > after.now: await self.send_scheduled_close_message(ctx, after, silent) await thread.close(closer=ctx.author, after=close_after, message=message, silent=silent) @@ -1530,7 +1527,6 @@ async def contact( except ValueError: pass - print(users, silent) if isinstance(category, str): category = category.split() @@ -1857,7 +1853,6 @@ async def block( return await ctx.send(embed=embed) reason = f"by {escape_markdown(ctx.author.name)}#{ctx.author.discriminator}" - now = discord.utils.utcnow() if after is not None: if "%" in reason: @@ -1866,7 +1861,7 @@ async def block( if after.arg: reason += f" until: <t:{unixtime}:R>" - if after.dt > now: + if after.dt > after.now: reason += f" until <t:{unixtime}:f>" reason += "." diff --git a/core/time.py b/core/time.py index b66f84757f..d0698d6381 100644 --- a/core/time.py +++ b/core/time.py @@ -20,8 +20,8 @@ units["seconds"].append("secs") if TYPE_CHECKING: + from discord.ext.commands import Context from typing_extensions import Self - from cogs.utils.context import Context class plural: @@ -82,7 +82,7 @@ def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): self.dt = now + relativedelta(**data) @classmethod - async def convert(cls, ctx: Context, argument: str) -> Self: + async def convert(cls, ctx: Context, argument: str) -> Self: return cls(argument, now=ctx.message.created_at) @@ -146,14 +146,23 @@ async def transform(self, interaction, value: str) -> datetime.datetime: return short.dt +## CHANGE: Added now class FriendlyTimeResult: dt: datetime.datetime + now: datetime.datetime arg: str - __slots__ = ("dt", "arg") + __slots__ = ("dt", "arg", "now") - def __init__(self, dt: datetime.datetime): + def __init__(self, dt: datetime.datetime, now: datetime.datetime=None): self.dt = dt + self.now = now + + if now is None: + self.now = dt + else: + self.now = now + self.arg = "" async def ensure_constraints( @@ -162,6 +171,7 @@ async def ensure_constraints( if self.dt < now: raise commands.BadArgument("This time is in the past.") + # CHANGE # if not remaining: # if uft.default is None: # raise commands.BadArgument("Missing argument after the time.") @@ -200,7 +210,7 @@ async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult: if match is not None and match.group(0): data = {k: int(v) for k, v in match.groupdict(default=0).items()} remaining = argument[match.end() :].strip() - result = FriendlyTimeResult(now + relativedelta(**data)) + result = FriendlyTimeResult(now + relativedelta(**data), now) await result.ensure_constraints(ctx, self, now, remaining) return result @@ -208,7 +218,7 @@ async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult: match = ShortTime.discord_fmt.match(argument) if match is not None: result = FriendlyTimeResult( - datetime.datetime.fromtimestamp(int(match.group("ts")), tz=datetime.timezone.utc) + datetime.datetime.fromtimestamp(int(match.group("ts")), now, tz=datetime.timezone.utc) ) remaining = argument[match.end() :].strip() await result.ensure_constraints(ctx, self, now, remaining) @@ -226,7 +236,10 @@ async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult: elements = calendar.nlp(argument, sourceTime=now) if elements is None or len(elements) == 0: - raise commands.BadArgument('Invalid time provided, try e.g. "tomorrow" or "3 days".') + # CHANGE + result = FriendlyTimeResult(now) + await result.ensure_constraints(ctx, self, now, argument) + return result # handle the following cases: # "date time" foo @@ -254,7 +267,7 @@ async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult: if status.accuracy == pdt.pdtContext.ACU_HALFDAY: dt = dt.replace(day=now.day + 1) - result = FriendlyTimeResult(dt.replace(tzinfo=datetime.timezone.utc)) + result = FriendlyTimeResult(dt.replace(tzinfo=datetime.timezone.utc), now) remaining = "" if begin in (0, 1): From 30430a6c255407729472445961c11dd9c6a4bf06 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 7 Sep 2022 00:10:19 +0800 Subject: [PATCH 576/705] bump ver --- bot.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index a990ac772c..7c9f19f920 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev19" +__version__ = "4.0.0-dev20" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 9a22625dba..f4faae86fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev19' +version = '4.0.0-dev20' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 420d4dc577c1ac5d68360dac81a9f9a023d473b0 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 7 Sep 2022 00:10:56 +0800 Subject: [PATCH 577/705] formatting --- cogs/modmail.py | 8 +++++++- core/time.py | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 279df07dd6..d1528f9b46 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -464,7 +464,13 @@ async def send_scheduled_close_message(self, ctx, after, silent=False): @commands.command(usage="[after] [close message]") @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() - async def close(self, ctx, option: Optional[Literal["silent", "silently", "cancel"]]='', *, after: UserFriendlyTime = None): + async def close( + self, + ctx, + option: Optional[Literal["silent", "silently", "cancel"]] = "", + *, + after: UserFriendlyTime = None, + ): """ Close the current thread. diff --git a/core/time.py b/core/time.py index d0698d6381..90aca9c021 100644 --- a/core/time.py +++ b/core/time.py @@ -82,7 +82,7 @@ def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): self.dt = now + relativedelta(**data) @classmethod - async def convert(cls, ctx: Context, argument: str) -> Self: + async def convert(cls, ctx: Context, argument: str) -> Self: return cls(argument, now=ctx.message.created_at) @@ -154,7 +154,7 @@ class FriendlyTimeResult: __slots__ = ("dt", "arg", "now") - def __init__(self, dt: datetime.datetime, now: datetime.datetime=None): + def __init__(self, dt: datetime.datetime, now: datetime.datetime = None): self.dt = dt self.now = now From 711fb68c4d0378b3f79a83ce18a1778ffc1d2f64 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 7 Sep 2022 00:13:18 +0800 Subject: [PATCH 578/705] formatting --- bot.py | 1 - cogs/modmail.py | 1 - cogs/utility.py | 2 +- core/time.py | 4 ++-- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index 7c9f19f920..5eb3378d45 100644 --- a/bot.py +++ b/bot.py @@ -18,7 +18,6 @@ import discord import isodate from aiohttp import ClientSession, ClientResponseError -from discord.utils import MISSING from discord.ext import commands, tasks from discord.ext.commands.view import StringView from emoji import UNICODE_EMOJI diff --git a/cogs/modmail.py b/cogs/modmail.py index d1528f9b46..ecdf7144e6 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -2,7 +2,6 @@ import re from datetime import datetime, timezone from itertools import zip_longest -import time from typing import Optional, Union, List, Tuple, Literal from types import SimpleNamespace diff --git a/cogs/utility.py b/cogs/utility.py index 7f623141b7..af0e70beec 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -197,7 +197,7 @@ async def send_error_message(self, error): if snippet_aliases: embed.add_field( - name=f"Aliases to this snippet:", value=",".join(snippet_aliases), inline=False + name="Aliases to this snippet:", value=",".join(snippet_aliases), inline=False ) return await self.get_destination().send(embed=embed) diff --git a/core/time.py b/core/time.py index 90aca9c021..99c1ed7713 100644 --- a/core/time.py +++ b/core/time.py @@ -111,7 +111,7 @@ class Time(HumanTime): def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): try: o = ShortTime(argument, now=now) - except Exception as e: + except Exception: super().__init__(argument) else: self.dt = o.dt @@ -146,7 +146,7 @@ async def transform(self, interaction, value: str) -> datetime.datetime: return short.dt -## CHANGE: Added now +# CHANGE: Added now class FriendlyTimeResult: dt: datetime.datetime now: datetime.datetime From 3d7b6261ea5c7e7eb36da0cc9c2962621e475b39 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 7 Sep 2022 00:25:22 +0800 Subject: [PATCH 579/705] add comnts to lint file --- .github/workflows/lints.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index a7418930be..21bf39368e 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -23,6 +23,7 @@ jobs: run: | python -m pip install --upgrade pip pipenv pipenv install --dev --system + # to refresh: bandit -f json -o .bandit_baseline.json -r . # - name: Bandit syntax check # run: bandit -r . -b .bandit_baseline.json - name: Pylint From 039347fb05b38ab39b4ea0acad7be3ee1cab27e1 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:10:47 +0800 Subject: [PATCH 580/705] Use new timestamps for userinfo and fix potential blocked parsing --- bot.py | 2 +- cogs/modmail.py | 48 ++++++++++++++++++++++++++++++++++++++---------- core/thread.py | 9 ++++----- core/time.py | 13 ++----------- pyproject.toml | 2 +- 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/bot.py b/bot.py index a96a58fd6e..23c911b8ea 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0-dev20" +__version__ = "4.0.0" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index ecdf7144e6..85b4af62ac 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1654,21 +1654,48 @@ async def blocked(self, ctx): blocked_users = list(self.bot.blocked_users.items()) for id_, reason in blocked_users: # parse "reason" and check if block is expired - # etc "blah blah blah... until 2019-10-14T21:12:45.559948." - end_time = re.search(r"until ([^`]+?)\.$", reason) - if end_time is None: + # etc "blah blah blah... until <t:XX:f>." + end_time = re.search(r"until <t:(\d+):(?:R|f)>.$", reason) + attempts = [ # backwards compat - end_time = re.search(r"%([^%]+?)%", reason) + re.search(r"until ([^`]+?)\.$", reason), + re.search(r"%([^%]+?)%", reason), + ] + if end_time is None: + for i in attempts: + if i is not None: + end_time = i + break + if end_time is not None: + # found a deprecated version + try: + after = ( + datetime.fromisoformat(end_time.group(1)).replace(tzinfo=timezone.utc) - now + ).total_seconds() + except ValueError: + logger.warning( + r"Broken block message for user %s, block and unblock again with a different message to prevent further issues", + id_, + ) + continue logger.warning( r"Deprecated time message for user %s, block and unblock again to update.", id_, ) + else: + try: + after = ( + datetime.fromtimestamp(int(end_time.group(1))).replace(tzinfo=timezone.utc) - now + ).total_seconds() + except ValueError: + logger.warning( + r"Broken block message for user %s, block and unblock again with a different message to prevent further issues", + id_, + ) + continue if end_time is not None: - after = ( - datetime.fromisoformat(end_time.group(1)).replace(tzinfo=timezone.utc) - now - ).total_seconds() if after <= 0: # No longer blocked self.bot.blocked_users.pop(str(id_)) @@ -1862,12 +1889,13 @@ async def block( if after is not None: if "%" in reason: raise commands.BadArgument('The reason contains illegal character "%".') - unixtime = int(after.dt.replace(tzinfo=timezone.utc).timestamp()) if after.arg: - reason += f" until: <t:{unixtime}:R>" + fmt_dt = discord.utils.format_dt(after.dt, "R") if after.dt > after.now: - reason += f" until <t:{unixtime}:f>" + fmt_dt = discord.utils.format_dt(after.dt, "f") + + reason += f" until {fmt_dt}" reason += "." diff --git a/core/thread.py b/core/thread.py index 606a204b37..99a805fef5 100644 --- a/core/thread.py +++ b/core/thread.py @@ -322,10 +322,10 @@ def _format_info_embed(self, user, log_url, log_count, color): role_names = separator.join(roles) - created = str((time - user.created_at).days) user_info = [] if self.bot.config["thread_show_account_age"]: - user_info.append(f" was created {days(created)}") + created = discord.utils.format_dt(user.created_at, "R") + user_info.append(f" was created {created}") embed = discord.Embed(color=color, description=user.mention, timestamp=time) @@ -337,10 +337,9 @@ def _format_info_embed(self, user, log_url, log_count, color): if member is not None: embed.set_author(name=str(user), icon_url=member.display_avatar.url, url=log_url) - joined = str((time - member.joined_at).days) - # embed.add_field(name='Joined', value=joined + days(joined)) if self.bot.config["thread_show_join_age"]: - user_info.append(f"joined {days(joined)}") + joined = discord.utils.format_dt(member.joined_at, "R") + user_info.append(f"joined {joined}") if member.nick: embed.add_field(name="Nickname", value=member.nick, inline=True) diff --git a/core/time.py b/core/time.py index 99c1ed7713..64dcd88507 100644 --- a/core/time.py +++ b/core/time.py @@ -6,6 +6,7 @@ from __future__ import annotations import datetime +import discord from typing import TYPE_CHECKING, Any, Optional, Union import parsedatetime as pdt from dateutil.relativedelta import relativedelta @@ -39,16 +40,6 @@ def __format__(self, format_spec: str) -> str: return f"{v} {singular}" -def format_dt(dt: datetime.datetime, style: Optional[str] = None) -> str: - """https://github.com/Rapptz/RoboDanny/blob/bf7d4226350dff26df4981dd53134eeb2aceeb87/cogs/utils/formats.py#L89-L95""" - if dt.tzinfo is None: - dt = dt.replace(tzinfo=datetime.timezone.utc) - - if style is None: - return f"<t:{int(dt.timestamp())}>" - return f"<t:{int(dt.timestamp())}:{style}>" - - class ShortTime: compiled = re.compile( """ @@ -365,4 +356,4 @@ def human_timedelta( def format_relative(dt: datetime.datetime) -> str: - return format_dt(dt, "R") + return discord.utils.format_dt(dt, "R") diff --git a/pyproject.toml b/pyproject.toml index f4faae86fd..a19e436399 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0-dev20' +version = '4.0.0' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From ba4d6fb81fe61628fda805d56d5d9a0a2f560cdf Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:11:47 +0800 Subject: [PATCH 581/705] Fix removeprefix issue by @Jerrie-Aries https://github.com/kyb3r/modmail/commit/ecc92e4bbf44d0f44d2df902e16a30734320070e#r83768323 --- bot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 23c911b8ea..52ba65b960 100644 --- a/bot.py +++ b/bot.py @@ -1000,7 +1000,8 @@ async def get_contexts(self, message, *, cls=commands.Context): # This needs to be done before checking for aliases since # snippets can have multiple words. try: - snippet_text = self.snippets[message.content.strip(invoked_prefix)] + # Use removeprefix once PY3.9+ + snippet_text = self.snippets[message.content[len(invoked_prefix) :]] except KeyError: snippet_text = None From c6b4f530de7765839278546ed7351433450d99f9 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:31:04 +0800 Subject: [PATCH 582/705] Fix block logic and rewrite into helper function --- bot.py | 41 +++++++++++------------------------ cogs/modmail.py | 57 +++++++------------------------------------------ core/thread.py | 1 - core/time.py | 4 ++-- core/utils.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 80 deletions(-) diff --git a/bot.py b/bot.py index 52ba65b960..9f13e3e04e 100644 --- a/bot.py +++ b/bot.py @@ -47,7 +47,7 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import normalize_alias, parse_alias, truncate, tryint +from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint logger = getLogger(__name__) @@ -735,21 +735,13 @@ def check_manual_blocked_roles(self, author: discord.Member) -> bool: if str(r.id) in self.blocked_roles: blocked_reason = self.blocked_roles.get(str(r.id)) or "" - now = discord.utils.utcnow() - - # etc "blah blah blah... until 2019-10-14T21:12:45.559948." - end_time = re.search(r"until ([^`]+?)\.$", blocked_reason) - if end_time is None: - # backwards compat - end_time = re.search(r"%([^%]+?)%", blocked_reason) - if end_time is not None: - logger.warning( - r"Deprecated time message for role %s, block and unblock again to update.", - r.name, - ) + + try: + end_time, after = extract_block_timestamp(blocked_reason, author.id) + except ValueError: + return False if end_time is not None: - after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() if after <= 0: # No longer blocked self.blocked_roles.pop(str(r.id)) @@ -765,26 +757,19 @@ def check_manual_blocked(self, author: discord.Member) -> bool: return True blocked_reason = self.blocked_users.get(str(author.id)) or "" - now = discord.utils.utcnow() if blocked_reason.startswith("System Message:"): # Met the limits already, otherwise it would've been caught by the previous checks logger.debug("No longer internally blocked, user %s.", author.name) self.blocked_users.pop(str(author.id)) return True - # etc "blah blah blah... until 2019-10-14T21:12:45.559948." - end_time = re.search(r"until ([^`]+?)\.$", blocked_reason) - if end_time is None: - # backwards compat - end_time = re.search(r"%([^%]+?)%", blocked_reason) - if end_time is not None: - logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", - author.name, - ) + + try: + end_time, after = extract_block_timestamp(blocked_reason, author.id) + except ValueError: + return False if end_time is not None: - after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() if after <= 0: # No longer blocked self.blocked_users.pop(str(author.id)) @@ -891,7 +876,7 @@ async def add_reaction( if reaction != "disable": try: await msg.add_reaction(reaction) - except (discord.HTTPException, discord.InvalidArgument) as e: + except (discord.HTTPException, discord.BadArgument) as e: logger.warning("Failed to add reaction %s: %s.", reaction, e) return False return True @@ -1316,7 +1301,7 @@ async def handle_reaction_events(self, payload): for msg in linked_messages: await msg.remove_reaction(reaction, self.user) await message.remove_reaction(reaction, self.user) - except (discord.HTTPException, discord.InvalidArgument) as e: + except (discord.HTTPException, discord.BadArgument) as e: logger.warning("Failed to remove reaction: %s", e) async def handle_react_to_contact(self, payload): diff --git a/cogs/modmail.py b/cogs/modmail.py index 85b4af62ac..b6ebe81baf 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1654,46 +1654,10 @@ async def blocked(self, ctx): blocked_users = list(self.bot.blocked_users.items()) for id_, reason in blocked_users: # parse "reason" and check if block is expired - # etc "blah blah blah... until <t:XX:f>." - end_time = re.search(r"until <t:(\d+):(?:R|f)>.$", reason) - attempts = [ - # backwards compat - re.search(r"until ([^`]+?)\.$", reason), - re.search(r"%([^%]+?)%", reason), - ] - if end_time is None: - for i in attempts: - if i is not None: - end_time = i - break - - if end_time is not None: - # found a deprecated version - try: - after = ( - datetime.fromisoformat(end_time.group(1)).replace(tzinfo=timezone.utc) - now - ).total_seconds() - except ValueError: - logger.warning( - r"Broken block message for user %s, block and unblock again with a different message to prevent further issues", - id_, - ) - continue - logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", - id_, - ) - else: - try: - after = ( - datetime.fromtimestamp(int(end_time.group(1))).replace(tzinfo=timezone.utc) - now - ).total_seconds() - except ValueError: - logger.warning( - r"Broken block message for user %s, block and unblock again with a different message to prevent further issues", - id_, - ) - continue + try: + end_time, after = extract_block_timestamp(reason, id_) + except ValueError: + continue if end_time is not None: if after <= 0: @@ -1713,15 +1677,10 @@ async def blocked(self, ctx): for id_, reason in blocked_roles: # parse "reason" and check if block is expired # etc "blah blah blah... until 2019-10-14T21:12:45.559948." - end_time = re.search(r"until ([^`]+?)\.$", reason) - if end_time is None: - # backwards compat - end_time = re.search(r"%([^%]+?)%", reason) - if end_time is not None: - logger.warning( - r"Deprecated time message for role %s, block and unblock again to update.", - id_, - ) + try: + end_time, after = extract_block_timestamp(reason, id_) + except ValueError: + continue if end_time is not None: after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() diff --git a/core/thread.py b/core/thread.py index 99a805fef5..c9d8ae5bcb 100644 --- a/core/thread.py +++ b/core/thread.py @@ -22,7 +22,6 @@ from core.time import human_timedelta from core.utils import ( is_image_url, - days, parse_channel_topic, match_title, match_user_id, diff --git a/core/time.py b/core/time.py index 64dcd88507..963eac5a6e 100644 --- a/core/time.py +++ b/core/time.py @@ -63,7 +63,7 @@ def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): if match is None or not match.group(0): match = self.discord_fmt.fullmatch(argument) if match is not None: - self.dt = datetime.datetime.fromtimestamp(int(match.group("ts")), tz=datetime.timezone.utc) + self.dt = datetime.datetime.utcfromtimestamp(int(match.group("ts")), tz=datetime.timezone.utc) return else: raise commands.BadArgument("invalid time provided") @@ -209,7 +209,7 @@ async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult: match = ShortTime.discord_fmt.match(argument) if match is not None: result = FriendlyTimeResult( - datetime.datetime.fromtimestamp(int(match.group("ts")), now, tz=datetime.timezone.utc) + datetime.datetime.utcfromtimestamp(int(match.group("ts")), now, tz=datetime.timezone.utc) ) remaining = argument[match.end() :].strip() await result.ensure_constraints(ctx, self, now, remaining) diff --git a/core/utils.py b/core/utils.py index ce28f243c1..30130eb740 100644 --- a/core/utils.py +++ b/core/utils.py @@ -2,6 +2,7 @@ import functools import re import typing +from datetime import datetime, timezone from difflib import get_close_matches from distutils.util import strtobool as _stb # pylint: disable=import-error from itertools import takewhile, zip_longest @@ -10,6 +11,9 @@ import discord from discord.ext import commands +from core.models import getLogger + + __all__ = [ "strtobool", "User", @@ -34,9 +38,13 @@ "tryint", "get_top_role", "get_joint_id", + "extract_block_timestamp", ] +logger = getLogger(__name__) + + def strtobool(val): if isinstance(val, bool): return val @@ -504,3 +512,50 @@ def get_joint_id(message: discord.Message) -> typing.Optional[int]: except ValueError: pass return None + + +def extract_block_timestamp(reason, id_): + # etc "blah blah blah... until <t:XX:f>." + now = discord.utils.utcnow() + end_time = re.search(r"until <t:(\d+):(?:R|f)>.$", reason) + attempts = [ + # backwards compat + re.search(r"until ([^`]+?)\.$", reason), + re.search(r"%([^%]+?)%", reason), + ] + after = None + if end_time is None: + for i in attempts: + if i is not None: + end_time = i + break + + if end_time is not None: + # found a deprecated version + try: + after = ( + datetime.fromisoformat(end_time.group(1)).replace(tzinfo=timezone.utc) - now + ).total_seconds() + except ValueError: + logger.warning( + r"Broken block message for user %s, block and unblock again with a different message to prevent further issues", + id_, + ) + raise + logger.warning( + r"Deprecated time message for user %s, block and unblock again to update.", + id_, + ) + else: + try: + after = ( + datetime.utcfromtimestamp(int(end_time.group(1))).replace(tzinfo=timezone.utc) - now + ).total_seconds() + except ValueError: + logger.warning( + r"Broken block message for user %s, block and unblock again with a different message to prevent further issues", + id_, + ) + raise + + return end_time, after From ebfd37baccfacf3aa9f34100ae1a3b91e6e7ec7f Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:33:23 +0800 Subject: [PATCH 583/705] Purge Registry --- plugins/registry.json | 260 +----------------------------------------- 1 file changed, 1 insertion(+), 259 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index ad8dbebaf9..9e26dfeeb6 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1,259 +1 @@ -{ - "close_message": { - "repository": "python-discord/modmail-plugins", - "branch": "main", - "description": "Add a ?closemessage command that will close the thread after 15 minutes with a default message.", - "bot_version": "2.20.1", - "title": "Close message", - "icon_url": "https://i.imgur.com/ev7BFMz.png", - "thumbnail_url": "https://i.imgur.com/ev7BFMz.png" - }, - "mdlink": { - "repository": "python-discord/modmail-plugins", - "branch": "main", - "description": "Generate a ready to paste link to the thread logs.", - "bot_version": "2.20.1", - "title": "MDLink", - "icon_url": "https://i.imgur.com/JA2E63R.png", - "thumbnail_url": "https://i.imgur.com/JA2E63R.png" - }, - "reply_cooldown": { - "repository": "python-discord/modmail-plugins", - "branch": "main", - "description": "Forbid you from sending the same message twice in ten seconds.", - "bot_version": "2.20.1", - "title": "Reply cooldown", - "icon_url": "https://i.imgur.com/FtRQveT.png", - "thumbnail_url": "https://i.imgur.com/FtRQveT.png" - }, - "dragory-migrate": { - "repository": "kyb3r/modmail-plugins", - "branch": "master", - "description": "Migrate your logs from Dragory's modmail bot to this one with a simple command. Added at the request of users.", - "bot_version": "2.20.1", - "title": "Dragory Logs Migration", - "icon_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png", - "thumbnail_url": "https://cdn1.iconfinder.com/data/icons/web-hosting-2-4/52/200-512.png" - }, - "music": { - "repository": "Taaku18/modmail-plugins", - "branch": "master", - "description": "Play wonderfull jams through your modmail!", - "bot_version": "2.20.1", - "title": "music", - "icon_url": "https://i.imgur.com/JmJPX5W.gif", - "thumbnail_url": "https://i.imgur.com/jrYL7F8.gif" - }, - "media-only": { - "repository": "lorenzo132/modmail-plugins", - "branch": "master", - "description": "Make a channel mediaonly, only the following mediatypes will be accepted `.png` / `.gif` / `.jpg` / `.mp4`/ `.jpeg`", - "bot_version": "2.20.1", - "title": "Media-only", - "icon_url": "https://i.imgur.com/ussAoIi.png", - "thumbnail_url": "https://i.imgur.com/ussAoIi.png" - }, - "anti-steal-close": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Don't let anyone steal ya close.", - "title": "Anti Steal Close", - "icon_url": "https://i.imgur.com/LovxyV3.png", - "thumbnail_url": "https://i.imgur.com/LovxyV3.png" - }, - "announcement": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Easily make announcements in your server!", - "bot_version": "2.20.1", - "title": "Announcement Plugin", - "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", - "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" - }, - "dm-on-join": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "DM New Users when they join", - "bot_version": "2.20.1", - "title": "DM-on-join Plugin", - "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", - "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" - }, - "giveaway": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Host giveaways on your server", - "bot_version": "2.20.1", - "title": "\uD83C\uDF89 Giveaway Plugin \uD83C\uDF89", - "icon_url": "https://i.imgur.com/qk85xdi.png", - "thumbnail_url": "https://i.imgur.com/gUHB91v.png" - }, - "hastebin": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Easily Upload Text To hastebin!", - "bot_version": "2.20.1", - "title": "Hastebin Plugin", - "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", - "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" - }, - "leave-server": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Don't want your bot in a server? Did someone invite it without your permission? If so, this plugin is useful for you!", - "bot_version": "2.20.1", - "title": "Leave-server Plugin", - "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", - "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" - }, - "welcomer": { - "repository": "fourjr/modmail-plugins", - "branch": "master", - "description": "Add messages to welcome new members! Allows for embedded messages as well. [Read more](https://github.com/fourjr/modmail-plugins/blob/master/welcomer/README.md)", - "bot_version": "2.20.1", - "title": "New member messages plugin", - "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", - "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" - }, - "tags": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Tag Management For Your Server", - "bot_version": "2.20.1", - "title": "Tags Plugin", - "icon_url": "https://images.ionadev.ml/b/ZIDUUsl.png", - "thumbnail_url": "https://images.ionadev.ml/b/ZIDUUsl.png" - }, - "backupdb": { - "repository": "officialpiyush/modmail-plugins", - "branch": "master", - "description": "Backup you're current Modmail DB with a single command!\n\n**Requires `BACKUP_MONGO_URI` in either config.json or environment variables**", - "bot_version": "2.20.1", - "title": "Backup Database (backupdb)", - "icon_url": "https://images.ionadev.ml/b/nKAlOC4.jpg", - "thumbnail_url": "https://images.ionadev.ml/b/nKAlOC4.jpg" - }, - "colors": { - "repository": "Taaku18/modmail-plugins", - "branch": "master", - "description": "Conversions between hex, RGB, and color names.", - "bot_version": "2.20.1", - "title": "Colors!!", - "icon_url": "https://cdn1.iconfinder.com/data/icons/weather-19/32/rainbow-512.png", - "thumbnail_url": "https://i.imgur.com/fSxnc9W.jpg" - }, - "fun": { - "repository": "TheKinG2149/modmail-plugins", - "branch": "master", - "description": "Some fun commands like 8ball, dadjokes", - "bot_version": "2.24.1", - "title": "Fun", - "icon_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png", - "thumbnail_url": "https://cdn.discordapp.com/attachments/584692239893135362/591588754142265354/43880032.png" - }, - "stats": { - "repository": "KarateWumpus/modmail-plugins", - "branch": "master", - "description": "Get useful stats directly in an embed about either the Modmail bot, a user or the server.", - "bot_version": "2.24.1", - "title": "Get Stats", - "icon_url": "https://image.flaticon.com/icons/png/512/117/117761.png", - "thumbnail_url": "http://www.pngmart.com/files/7/Statistics-PNG-Clipart.png" - }, - "moderation": { - "repository": "Vincysuper07/modmail-plugins", - "branch": "main", - "description": "Moderate your server with Modmail, bring the Mod to Modmail!", - "bot_version": "3.6.2", - "title": "Moderate your server", - "icon_url": "https://cdn.discordapp.com/attachments/759829573654544454/773535811143598110/ad2e4d6e7b90ca6005a5038e22b099cc.png", - "thumbnail_url": "https://cdn.discordapp.com/attachments/759829573654544454/773535811143598110/ad2e4d6e7b90ca6005a5038e22b099cc.png" - }, - "serverstats": { - "repository": "dazvise/modmail-plugins", - "branch": "master", - "description": "Voice channels containing interesting and accurate statistics about your server such as Member Count.", - "bot_version": "2.20.1", - "title": "Server Stats", - "icon_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png", - "thumbnail_url": "https://i.gyazo.com/fadb70740e83f2448b23ffe192a1f32d.png" - }, - "suggest": { - "repository": "realcyguy/modmail-plugins", - "branch": "master", - "description": "Send suggestions to a selected server! It has accepting, denying, and moderation-ing.", - "bot_version": "3.4.1", - "title": "Suggest stuff.", - "icon_url": "https://i.imgur.com/qtE7AH8.png", - "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" - }, - "githubstats": { - "repository": "mischievousdev/modmail-plugins", - "branch": "master", - "description": "Github statistics in discord", - "bot_version": "2.20.1", - "title": "Github Stats", - "icon_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg", - "thumbnail_url": "https://raw.githubusercontent.com/mischievousdev/modmail-plugins/master/download%20(9).jpeg" - }, - "slowmode": { - "repository": "teen1/modmail-plugins", - "branch": "master", - "description": "Configure slow mode for your channels with Modmail!", - "bot_version": "2.20.1", - "title": "Slow Mode", - "icon_url": "https://cdn.discordapp.com/attachments/717029057635549274/717033838966210601/Slow_mode_-_icon.png", - "thumbnail_url": "https://cdn.discordapp.com/attachments/717029057635549274/717029110907666482/Slow_mode_plugin_-_thumbnail.png" - }, - "translate": { - "repository": "WebKide/modmail-plugins", - "branch": "master", - "description": "(∩`-´)⊃━☆゚.*・。゚ translate text from one language to another (defaults to English)\n\nGet full list of available languages at: https://github.com/WebKide/modmail-plugins/blob/master/translate/langs.json\n\nThis command conflicts with Translator-plugin", - "bot_version": "3.5.0", - "title": "Translate", - "icon_url": "https://i.imgur.com/yeHFKgl.png", - "thumbnail_url": "https://i.imgur.com/yeHFKgl.png" - }, - "countdowns": { - "repository": "fourjr/modmail-plugins", - "branch": "master", - "description": "Setup a countdown voice channel in your server!", - "bot_version": "3.6.2", - "title": "Countdowns", - "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", - "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" - }, - "action": { - "repository": "6days9weeks/modmail-plugins", - "branch": "master", - "description": "Have fun with others by hugging them or giving them pats~!!", - "title": "Action", - "icon_url": "https://media.discordapp.net/attachments/720733784970100776/820933433579798528/689105042212388965.png", - "thumbnail_url": "https://data.whicdn.com/images/58526601/original.gif" - }, - "menu": { - "repository": "fourjr/modmail-plugins", - "branch": "master", - "description": "Adds reaction-based menus into thread creates. Check out `?configmenu`", - "title": "Menus", - "bot_version": "3.9.0", - "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", - "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" - }, - "claim": { - "repository": "fourjr/modmail-plugins", - "branch": "master", - "description": "Allows supporters to claim thread by sending ?claim in the thread channel", - "title": "Claim Thread", - "icon_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png", - "thumbnail_url": "https://cdn.discordapp.com/avatars/180314310298304512/7552e0089004079304cc9912d13ac81d.png" - }, - "phishchecker": { - "repository": "TheDiscordHistorian/historian-cogs", - "branch": "main", - "description": "Deletes scam links from your server and optionally kick / ban the user.", - "title": "Scam Link Detector", - "icon_url": "https://cdn.discordapp.com/attachments/576521645540245505/895661244743299102/antifish.png", - "thumbnail_url": "https://cdn.discordapp.com/attachments/576521645540245505/895661244743299102/antifish.png" - } -} +{} \ No newline at end of file From 7c2875c9e1db45f4120da17cb5dff85c7134f043 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:34:00 +0800 Subject: [PATCH 584/705] Lock registry version --- cogs/plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index 4cdd0aba3f..dc4c89aa6b 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -131,7 +131,7 @@ def __init__(self, bot): logger.info("Plugins not loaded since ENABLE_PLUGINS=false.") async def populate_registry(self): - url = "https://raw.githubusercontent.com/kyb3r/modmail/master/plugins/registry.json" + url = "https://raw.githubusercontent.com/kyb3r/modmail/be14cca89742cd691f6b91f0d0931a074ad81e3b/plugins/registry.json" async with self.bot.session.get(url) as resp: self.registry = json.loads(await resp.text()) From b7e25a0d5eed17808911a8532338c6bd3ba061f2 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:35:11 +0800 Subject: [PATCH 585/705] Upgrade version to 3.10.5 with locked registry --- CHANGELOG.md | 3 +++ bot.py | 2 +- pyproject.toml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f9b461169..268ee82a1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.10.5 +Locked plugin registry version impending v4 release. + # v3.10.3 This is a hotfix for contact command. diff --git a/bot.py b/bot.py index 0ee38be340..5113f367f8 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.10.3" +__version__ = "3.10.5" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 341e506413..cad728fd2a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '3.10.3' +version = '3.10.5' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 1f9f633ae1111b04701c137da192dc1d3d63a493 Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:36:58 +0800 Subject: [PATCH 586/705] Add suggest plugin #3189 --- plugins/registry.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 9e26dfeeb6..494feebee4 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1 +1,11 @@ -{} \ No newline at end of file +{ + "suggest": { + "repository": "realcyguy/modmail-plugins", + "branch": "v4", + "description": "Send suggestions to a selected server! It has accepting, denying, and moderation-ing.", + "bot_version": "4.0.0", + "title": "Suggest stuff.", + "icon_url": "https://i.imgur.com/qtE7AH8.png", + "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" + } +} \ No newline at end of file From cc4b4ff0aa345fc93dafa9556eacb4ec56d3a15f Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:37:54 +0800 Subject: [PATCH 587/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e90aeb637..4c1c3327ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Upgraded to discord.py v2.0 ([internal changes](https://discordpy.readthedocs.io/en/latest/migrating.html), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). - Python 3.8 or higher is required. - Asyncio changes ([gist](https://gist.github.com/Rapptz/6706e1c8f23ac27c98cee4dd985c8120)) +- Plugin registry is purged and all developers have to re-apply due to breaking changes. ### Added From b04ac7836abae923794cc6ca69e80a434c855fbb Mon Sep 17 00:00:00 2001 From: Yee Jia Rong <28086837+fourjr@users.noreply.github.com> Date: Wed, 21 Sep 2022 00:12:09 +0800 Subject: [PATCH 588/705] Hotfix v4.0.1 for thread cooldown --- CHANGELOG.md | 13 +++++++ Pipfile | 1 + Pipfile.lock | 98 ++++++++++++++++++++++++++++++++++++------------- README.md | 2 +- bot.py | 20 +++++++--- cogs/modmail.py | 1 - cogs/utility.py | 2 +- core/config.py | 4 +- core/thread.py | 2 +- core/time.py | 5 ++- core/utils.py | 2 +- pyproject.toml | 2 +- 12 files changed, 111 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20403c41a2..c46714146c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.0.1 + +This is a hotfix release. + +### Improved + +- Error Messages + +### Fixed + +- Thread cooldown + + # v4.0.0 ### Breaking diff --git a/Pipfile b/Pipfile index 573f06cb76..e61e3b9288 100644 --- a/Pipfile +++ b/Pipfile @@ -23,6 +23,7 @@ python-dateutil = "~=2.8.1" python-dotenv = "==0.20.0" uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} lottie = {version = "==0.6.11", extras = ["pdf"]} +requests = "==2.28.1" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 9657e2b273..e1c531856e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c074bd9564d93aac78141ccfec1138ffeb561dfa0956f60ee5b10322d156d20f" + "sha256": "9d1171901e036b1f78a2e89855d564e9f559736ca076128fa27eb14ee8f917a4" }, "pipfile-spec": 6, "requires": {}, @@ -130,6 +130,14 @@ ], "version": "==2.5.2" }, + "certifi": { + "hashes": [ + "sha256:36973885b9542e6bd01dea287b2b4b3b21236307c56324fcc3f1160f2d655ed5", + "sha256:e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.9.14" + }, "cffi": { "hashes": [ "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", @@ -217,11 +225,11 @@ }, "cssselect2": { "hashes": [ - "sha256:3a83b2a68370c69c9cd3fcb88bbfaebe9d22edeef2c22d1ff3e1ed9c7fa45ed8", - "sha256:5b5d6dea81a5eb0c9ca39f116c8578dd413778060c94c1f51196371618909325" + "sha256:1ccd984dab89fc68955043aca4e1b03e0cf29cad9880f6e28e3ba7a74b14aa5a", + "sha256:fd23a65bfd444595913f02fc71f6b286c29261e354c41d722ca7a261a49b5969" ], "markers": "python_version >= '3.7'", - "version": "==0.6.0" + "version": "==0.7.0" }, "defusedxml": { "hashes": [ @@ -321,11 +329,11 @@ }, "idna": { "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" ], "markers": "python_version >= '3.5'", - "version": "==3.3" + "version": "==3.4" }, "isodate": { "hashes": [ @@ -507,7 +515,9 @@ "version": "==2.21" }, "pymongo": { - "extras": [], + "extras": [ + "srv" + ], "hashes": [ "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", @@ -570,6 +580,7 @@ "sha256:81a3ebc33b1367f301d1c8eda57eec4868e951504986d5d3fe437479dcdac5b2", "sha256:8455176fd1b86de97d859fed4ae0ef867bf998581f584c7a1a591246dfec330f", "sha256:845b178bd127bb074835d2eac635b980c58ec5e700ebadc8355062df708d5a71", + "sha256:858af7c2ab98f21ed06b642578b769ecfcabe4754648b033168a91536f7beef9", "sha256:87e18f29bac4a6be76a30e74de9c9005475e27100acf0830679420ce1fd9a6fd", "sha256:89d7baa847383b9814de640c6f1a8553d125ec65e2761ad146ea2e75a7ad197c", "sha256:8c7ad5cab282f53b9d78d51504330d1c88c83fbe187e472c07e6908a0293142e", @@ -636,6 +647,14 @@ "index": "pypi", "version": "==0.20.0" }, + "requests": { + "hashes": [ + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + ], + "index": "pypi", + "version": "==2.28.1" + }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -652,27 +671,49 @@ "markers": "python_version >= '3.6'", "version": "==1.1.1" }, + "urllib3": { + "hashes": [ + "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", + "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", + "version": "==1.26.12" + }, "uvloop": { "hashes": [ - "sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450", - "sha256:089b4834fd299d82d83a25e3335372f12117a7d38525217c2258e9b9f4578897", - "sha256:1e5f2e2ff51aefe6c19ee98af12b4ae61f5be456cd24396953244a30880ad861", - "sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c", - "sha256:3a19828c4f15687675ea912cc28bbcb48e9bb907c801873bd1519b96b04fb805", - "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d", - "sha256:647e481940379eebd314c00440314c81ea547aa636056f554d491e40503c8464", - "sha256:6ccd57ae8db17d677e9e06192e9c9ec4bd2066b77790f9aa7dede2cc4008ee8f", - "sha256:772206116b9b57cd625c8a88f2413df2fcfd0b496eb188b82a43bed7af2c2ec9", - "sha256:8e0d26fa5875d43ddbb0d9d79a447d2ace4180d9e3239788208527c4784f7cab", - "sha256:98d117332cc9e5ea8dfdc2b28b0a23f60370d02e1395f88f40d1effd2cb86c4f", - "sha256:b572256409f194521a9895aef274cea88731d14732343da3ecdb175228881638", - "sha256:bd53f7f5db562f37cd64a3af5012df8cac2c464c97e732ed556800129505bd64", - "sha256:bd8f42ea1ea8f4e84d265769089964ddda95eb2bb38b5cbe26712b0616c3edee", - "sha256:e814ac2c6f9daf4c36eb8e85266859f42174a4ff0d71b99405ed559257750382", - "sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228" + "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d", + "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1", + "sha256:1436c8673c1563422213ac6907789ecb2b070f5939b9cbff9ef7113f2b531595", + "sha256:23609ca361a7fc587031429fa25ad2ed7242941adec948f9d10c045bfecab06b", + "sha256:2a6149e1defac0faf505406259561bc14b034cdf1d4711a3ddcdfbaa8d825a05", + "sha256:2deae0b0fb00a6af41fe60a675cec079615b01d68beb4cc7b722424406b126a8", + "sha256:307958f9fc5c8bb01fad752d1345168c0abc5d62c1b72a4a8c6c06f042b45b20", + "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded", + "sha256:3378eb62c63bf336ae2070599e49089005771cc651c8769aaad72d1bd9385a7c", + "sha256:3d97672dc709fa4447ab83276f344a165075fd9f366a97b712bdd3fee05efae8", + "sha256:3db8de10ed684995a7f34a001f15b374c230f7655ae840964d51496e2f8a8474", + "sha256:3ebeeec6a6641d0adb2ea71dcfb76017602ee2bfd8213e3fcc18d8f699c5104f", + "sha256:45cea33b208971e87a31c17622e4b440cac231766ec11e5d22c76fab3bf9df62", + "sha256:6708f30db9117f115eadc4f125c2a10c1a50d711461699a0cbfaa45b9a78e376", + "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c", + "sha256:6aafa5a78b9e62493539456f8b646f85abc7093dd997f4976bb105537cf2635e", + "sha256:7d37dccc7ae63e61f7b96ee2e19c40f153ba6ce730d8ba4d3b4e9738c1dccc1b", + "sha256:864e1197139d651a76c81757db5eb199db8866e13acb0dfe96e6fc5d1cf45fc4", + "sha256:8887d675a64cfc59f4ecd34382e5b4f0ef4ae1da37ed665adba0c2badf0d6578", + "sha256:8efcadc5a0003d3a6e887ccc1fb44dec25594f117a94e3127954c05cf144d811", + "sha256:9b09e0f0ac29eee0451d71798878eae5a4e6a91aa275e114037b27f7db72702d", + "sha256:a4aee22ece20958888eedbad20e4dbb03c37533e010fb824161b4f05e641f738", + "sha256:a5abddb3558d3f0a78949c750644a67be31e47936042d4f6c888dd6f3c95f4aa", + "sha256:c092a2c1e736086d59ac8e41f9c98f26bbf9b9222a76f21af9dfe949b99b2eb9", + "sha256:c686a47d57ca910a2572fddfe9912819880b8765e2f01dc0dd12a9bf8573e539", + "sha256:cbbe908fda687e39afd6ea2a2f14c2c3e43f2ca88e3a11964b297822358d0e6c", + "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718", + "sha256:dbbaf9da2ee98ee2531e0c780455f2841e4675ff580ecf93fe5c48fe733b5667", + "sha256:f1e507c9ee39c61bfddd79714e4f85900656db1aec4d40c6de55648e85c2799c", + "sha256:ff3d00b70ce95adce264462c930fbaecb29718ba6563db354608f37e49e09024" ], "markers": "sys_platform != 'win32'", - "version": "==0.16.0" + "version": "==0.17.0" }, "webencodings": { "hashes": [ @@ -924,6 +965,7 @@ }, "pyyaml": { "hashes": [ + "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", @@ -935,26 +977,32 @@ "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" ], diff --git a/README.md b/README.md index ace61fb903..559d49ba65 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.0.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.0.1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index 9f13e3e04e..1f62bfcac7 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.0" +__version__ = "4.0.1" import asyncio @@ -10,6 +10,7 @@ import string import struct import sys +import platform import typing from datetime import datetime, timezone from subprocess import PIPE @@ -857,10 +858,12 @@ async def get_thread_cooldown(self, author: discord.Member): return try: - cooldown = datetime.fromisoformat(last_log_closed_at) + thread_cooldown + cooldown = datetime.fromisoformat(last_log_closed_at).astimezone(timezone.utc) + thread_cooldown except ValueError: logger.warning("Error with 'thread_cooldown'.", exc_info=True) - cooldown = datetime.fromisoformat(last_log_closed_at) + self.config.remove("thread_cooldown") + cooldown = datetime.fromisoformat(last_log_closed_at).astimezone( + timezone.utc + ) + self.config.remove("thread_cooldown") if cooldown > now: # User messaged before thread cooldown ended @@ -1774,9 +1777,14 @@ def main(): "Unable to import cairosvg, install GTK Installer for Windows and restart your system (https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/latest)" ) else: - logger.error( - "Unable to import cairosvg, report on our support server with your OS details: https://discord.gg/etJNHCQ" - ) + if "ubuntu" in platform.version().lower() or "debian" in platform.version().lower(): + logger.error( + "Unable to import cairosvg, try running `sudo apt-get install libpangocairo-1.0-0` or report on our support server with your OS details: https://discord.gg/etJNHCQ" + ) + else: + logger.error( + "Unable to import cairosvg, report on our support server with your OS details: https://discord.gg/etJNHCQ" + ) sys.exit(0) # check discord version diff --git a/cogs/modmail.py b/cogs/modmail.py index b6ebe81baf..75130fdb6e 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1683,7 +1683,6 @@ async def blocked(self, ctx): continue if end_time is not None: - after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() if after <= 0: # No longer blocked self.bot.blocked_roles.pop(str(id_)) diff --git a/cogs/utility.py b/cogs/utility.py index af0e70beec..16c84af29d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -810,7 +810,7 @@ async def config_set(self, ctx, key: str.lower, *, value: str): if key in keys: try: - self.bot.config.set(key, value) + await self.bot.config.set(key, value) await self.bot.config.update() embed = discord.Embed( title="Success", diff --git a/core/config.py b/core/config.py index dd76776092..c25eef3921 100644 --- a/core/config.py +++ b/core/config.py @@ -366,7 +366,7 @@ def get(self, key: str, convert=True) -> typing.Any: return value - def set(self, key: str, item: typing.Any, convert=True) -> None: + async def set(self, key: str, item: typing.Any, convert=True) -> None: if not convert: return self.__setitem__(key, item) @@ -401,7 +401,7 @@ def set(self, key: str, item: typing.Any, convert=True) -> None: except isodate.ISO8601Error: try: converter = UserFriendlyTime() - time = converter.convert(None, item) + time = await converter.convert(None, item, now=discord.utils.utcnow()) if time.arg: raise ValueError except BadArgument as exc: diff --git a/core/thread.py b/core/thread.py index c9d8ae5bcb..30f0542c6d 100644 --- a/core/thread.py +++ b/core/thread.py @@ -568,7 +568,7 @@ async def _restart_close_timer(self): seconds = timeout.total_seconds() # seconds = 20 # Uncomment to debug with just 20 seconds reset_time = discord.utils.utcnow() + timedelta(seconds=seconds) - human_time = human_timedelta(dt=reset_time, spec="manual") + human_time = discord.utils.format_dt(reset_time) if self.bot.config.get("thread_auto_close_silently"): return await self.close(closer=self.bot.user, silent=True, after=int(seconds), auto_close=True) diff --git a/core/time.py b/core/time.py index 963eac5a6e..c56c7264e2 100644 --- a/core/time.py +++ b/core/time.py @@ -192,10 +192,11 @@ def __init__( self.converter: commands.Converter = converter # type: ignore # It doesn't understand this narrowing self.default: Any = default - async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult: + async def convert(self, ctx: Context, argument: str, *, now=None) -> FriendlyTimeResult: calendar = HumanTime.calendar regex = ShortTime.compiled - now = ctx.message.created_at + if now is None: + now = ctx.message.created_at match = regex.match(argument) if match is not None and match.group(0): diff --git a/core/utils.py b/core/utils.py index 30130eb740..d8046ade5f 100644 --- a/core/utils.py +++ b/core/utils.py @@ -469,7 +469,7 @@ async def create_thread_channel(bot, recipient, category, overwrites, *, name=No if not fallback: fallback = await category.clone(name="Fallback Modmail") - bot.config.set("fallback_category_id", str(fallback.id)) + await bot.config.set("fallback_category_id", str(fallback.id)) await bot.config.update() return await create_thread_channel( diff --git a/pyproject.toml b/pyproject.toml index a19e436399..79a3e74f0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.0' +version = '4.0.1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From d63575281f23286a103ed340968aa50b880ecb1d Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Wed, 21 Sep 2022 12:52:32 +0200 Subject: [PATCH 589/705] Fixed runtime.txt to use a valid python version --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 30e81e3130..119ff10234 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.10.3 +python-3.10.7 From ec52cc2001f487ab74f5b649f2a085828e9b8b22 Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Thu, 22 Sep 2022 17:39:18 +0530 Subject: [PATCH 590/705] Update modmail.py --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 75130fdb6e..57d4e4e844 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -749,7 +749,7 @@ def format_log_embeds(self, logs, avatar_url): if entry["recipient"]["id"] != entry["creator"]["id"]: embed.add_field(name="Created by", value=f"<@{entry['creator']['id']}>") - if entry["title"]: + if entry.get("title"): embed.add_field(name="Title", value=entry["title"], inline=False) embed.add_field(name="Preview", value=format_preview(entry["messages"]), inline=False) From 7960761ea740d2e5ed7f43ab03b0c11f6215afb6 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <hidzrie@gmail.com> Date: Fri, 23 Sep 2022 11:42:44 +0000 Subject: [PATCH 591/705] Fix RuntimeError when presence intent disabled. --- bot.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index 1f62bfcac7..06841e90b9 100644 --- a/bot.py +++ b/bot.py @@ -225,7 +225,6 @@ async def runner(): except discord.PrivilegedIntentsRequired: retry_intents = True if retry_intents: - await self.http.close() if self.ws is not None and self.ws.open: await self.ws.close(code=1000) self._ready.clear() @@ -236,9 +235,9 @@ async def runner(): # Try again with members intent self._connection._intents = intents logger.warning( - "Attempting to login with only the server members and message content privileged intent. Some plugins might not work correctly." + "Attempting to reconnect with only the server members and message content privileged intent. Some plugins might not work correctly." ) - await self.start(self.token) + await self.connect(reconnect=True) except discord.PrivilegedIntentsRequired: logger.critical( "Privileged intents are not explicitly granted in the discord developers dashboard." From ea0c5fce3241ef12aa8753c269b12c6498e0413b Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:53:19 +0200 Subject: [PATCH 592/705] Added advanced menu to registry --- plugins/registry.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 494feebee4..325ee2fac0 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1,4 +1,13 @@ { + "advanced-menu": { + "repository": "sebkuip/mm-plugins", + "branch": "master", + "description": "Advanced menu plugin using dropdown selectors. Supports submenus (and sub-submenus infinitely).", + "bot_version": "v4.0.0", + "title": "Advanced menu", + "icon_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png", + "thumbnail_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png" + }, "suggest": { "repository": "realcyguy/modmail-plugins", "branch": "v4", @@ -8,4 +17,4 @@ "icon_url": "https://i.imgur.com/qtE7AH8.png", "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" } -} \ No newline at end of file +} From 9e86f224fcf4f18a5c73fe3592098640964e0920 Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sat, 1 Oct 2022 09:37:10 +0800 Subject: [PATCH 593/705] Add giveaway plugin to registry. (#3208) * Add giveaway plugin to registry. * Update `thumbnail_url` for giveaway plugin. --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 325ee2fac0..27f304c983 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -8,6 +8,15 @@ "icon_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png", "thumbnail_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png" }, + "giveaway": { + "repository": "Jerrie-Aries/modmail-plugins", + "branch": "master", + "description": "Host giveaways on your server with this plugin.", + "bot_version": "4.0.0", + "title": "Giveaway", + "icon_url": "https://github.com/Jerrie-Aries.png", + "thumbnail_url": "https://raw.githubusercontent.com/Jerrie-Aries/modmail-plugins/master/.static/giveaway.jpg" + }, "suggest": { "repository": "realcyguy/modmail-plugins", "branch": "v4", From a5156621a85da28938b078c73153bb840d3e7a06 Mon Sep 17 00:00:00 2001 From: Ralph <blackbirdralph@aol.com> Date: Fri, 30 Sep 2022 23:03:19 -0400 Subject: [PATCH 594/705] Re-add/Expand FourJR Plugins --- plugins/registry.json | 74 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 27f304c983..7f09fbe2cc 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -25,5 +25,79 @@ "title": "Suggest stuff.", "icon_url": "https://i.imgur.com/qtE7AH8.png", "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" + }, + "welcomer": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Add messages to welcome new members! Allows for embedded messages as well. [Read more](https://github.com/fourjr/modmail-plugins/blob/master/welcomer/README.md)", + "bot_version": "2.20.1", + "title": "New member messages plugin", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "countdowns": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Setup a countdown voice channel in your server!", + "bot_version": "3.6.2", + "title": "Countdowns", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "claim": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Allows supporters to claim thread by sending ?claim in the thread channel", + "title": "Claim Thread", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "emote-manager": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Allows managing server emotes via ?emoji", + "title": "Emote Manager", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "claim": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Allows supporters to claim thread by sending ?claim in the thread channel", + "title": "Claim Thread", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "gen-log": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Outputs a text log of a thread in a specified channel", + "title": "Log Generator", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "media-logger": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Re-posts detected media from all visible channels into a specified logging channel", + "title": "Media Logger", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "report": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Specify an emoji to react with on messages. Generates a "report" in specified logging channel upon react.", + "title": "Report", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "top-supporters": { + "repository": "fourjr/modmail-plugins", + "branch": "master", + "description": "Gathers and prints the top supporters of handling threads.", + "title": "Top Supporters", + "icon_url": "https://i.imgur.com/Mo60CdK.png", + "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" } } From e978457f2ae61c5c9ee6c58fb64742376a62c1d5 Mon Sep 17 00:00:00 2001 From: Ralph <blackbirdralph@aol.com> Date: Fri, 30 Sep 2022 23:04:47 -0400 Subject: [PATCH 595/705] remove extra quotes --- plugins/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/registry.json b/plugins/registry.json index 7f09fbe2cc..23feb063f9 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -87,7 +87,7 @@ "report": { "repository": "fourjr/modmail-plugins", "branch": "master", - "description": "Specify an emoji to react with on messages. Generates a "report" in specified logging channel upon react.", + "description": "Specify an emoji to react with on messages. Generates a 'report' in specified logging channel upon react.", "title": "Report", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" From 964c809dd880f4aebba3a458c16f116757d29b93 Mon Sep 17 00:00:00 2001 From: Ralph <blackbirdralph@aol.com> Date: Sat, 1 Oct 2022 03:05:34 -0400 Subject: [PATCH 596/705] Update plugins/registry.json Co-authored-by: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> --- plugins/registry.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 23feb063f9..57d735198d 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -59,14 +59,6 @@ "title": "Emote Manager", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" - }, - "claim": { - "repository": "fourjr/modmail-plugins", - "branch": "master", - "description": "Allows supporters to claim thread by sending ?claim in the thread channel", - "title": "Claim Thread", - "icon_url": "https://i.imgur.com/Mo60CdK.png", - "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "gen-log": { "repository": "fourjr/modmail-plugins", From a139de8432b0abe7acb6018aff80e7ee4def84f6 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <hidzrie@gmail.com> Date: Sat, 1 Oct 2022 07:55:02 +0000 Subject: [PATCH 597/705] Add `announcement` plugin to registry. --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index 27f304c983..141ff174c2 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -8,6 +8,15 @@ "icon_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png", "thumbnail_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png" }, + "announcement": { + "repository": "Jerrie-Aries/modmail-plugins", + "branch": "master", + "description": "Create and post announcements. Supports both plain and embed. Also customisable using buttons and dropdown menus.", + "bot_version": "4.0.0", + "title": "Announcement", + "icon_url": "https://github.com/Jerrie-Aries.png", + "thumbnail_url": "https://raw.githubusercontent.com/Jerrie-Aries/modmail-plugins/master/.static/announcement.jpg" + }, "giveaway": { "repository": "Jerrie-Aries/modmail-plugins", "branch": "master", From 766bbbbd0e494c17dc2cffefb5c906216a7fcb2d Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 2 Oct 2022 22:49:22 -0700 Subject: [PATCH 598/705] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c46714146c..3f19259a9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. + +# [Unreleased] + +### Fixed + +- Bots without presence intent encountering RuntimeError on start. + + # v4.0.1 This is a hotfix release. From 4aadf63590175213ca918e748893311913fd4814 Mon Sep 17 00:00:00 2001 From: Ralph <blackbirdralph@aol.com> Date: Mon, 3 Oct 2022 10:08:39 -0400 Subject: [PATCH 599/705] Update Branch and Bot_Version --- plugins/registry.json | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 57d735198d..558d725814 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -28,66 +28,72 @@ }, "welcomer": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Add messages to welcome new members! Allows for embedded messages as well. [Read more](https://github.com/fourjr/modmail-plugins/blob/master/welcomer/README.md)", - "bot_version": "2.20.1", + "bot_version": "4.0.0", "title": "New member messages plugin", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "countdowns": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Setup a countdown voice channel in your server!", - "bot_version": "3.6.2", + "bot_version": "4.0.0", "title": "Countdowns", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "claim": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Allows supporters to claim thread by sending ?claim in the thread channel", + "bot_version": "4.0.0", "title": "Claim Thread", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "emote-manager": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Allows managing server emotes via ?emoji", + "bot_version": "4.0.0", "title": "Emote Manager", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "gen-log": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Outputs a text log of a thread in a specified channel", + "bot_version": "4.0.0", "title": "Log Generator", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "media-logger": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Re-posts detected media from all visible channels into a specified logging channel", + "bot_version": "4.0.0", "title": "Media Logger", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "report": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Specify an emoji to react with on messages. Generates a 'report' in specified logging channel upon react.", + "bot_version": "4.0.0", "title": "Report", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, "top-supporters": { "repository": "fourjr/modmail-plugins", - "branch": "master", + "branch": "v4", "description": "Gathers and prints the top supporters of handling threads.", + "bot_version": "4.0.0", "title": "Top Supporters", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" From df63dec4b02d449c39cc79616dfff0ef00ce37a8 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 15 Oct 2022 04:34:33 -0700 Subject: [PATCH 600/705] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c46714146c..db997890ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# Unreleased + +### Fixed + +- Resolved an issue where `?logs` doesn't work when the thread has no title. ([PR #3201](https://github.com/kyb3r/modmail/pull/3201)) + # v4.0.1 This is a hotfix release. From 03558f742bc0df5aff38eb67fa6e0370bba8f8c9 Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sun, 4 Dec 2022 11:47:32 +0530 Subject: [PATCH 601/705] Remove hard coded "( )" from plain messages --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 30f0542c6d..4d883ae687 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1150,7 +1150,7 @@ def lottie_to_png(data): additional_images = [] if embed.footer.text: - plain_message = f"**({embed.footer.text}) " + plain_message = f"**{embed.footer.text} " else: plain_message = "**" plain_message += f"{embed.author.name}:** {embed.description}" From cde98e90b4119fca97bd80880d3e33cc044cc9ef Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sun, 4 Dec 2022 13:35:03 +0530 Subject: [PATCH 602/705] Fix guild icon not set issue --- bot.py | 16 +++++++++++++--- cogs/modmail.py | 14 +++++++------- cogs/utility.py | 8 +++++--- core/thread.py | 6 +++--- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/bot.py b/bot.py index 1f62bfcac7..01d8a52c11 100644 --- a/bot.py +++ b/bot.py @@ -87,6 +87,13 @@ def __init__(self): self.plugin_db = PluginDatabaseClient(self) # Deprecated self.startup() + def get_guild_icon(self, guild: typing.Optional[discord.Guild]) -> str: + if guild is None: + guild = self.guild + if guild.icon is None: + return self.user.display_avatar.url + return guild.icon_url + def _resolve_snippet(self, name: str) -> typing.Optional[str]: """ Get actual snippet names from direct aliases to snippets. @@ -913,7 +920,10 @@ async def process_dm_modmail(self, message: discord.Message) -> None: color=self.error_color, description=self.config["disabled_new_thread_response"], ) - embed.set_footer(text=self.config["disabled_new_thread_footer"], icon_url=self.guild.icon.url) + embed.set_footer( + text=self.config["disabled_new_thread_footer"], + icon_url=self.get_guild_icon(guild=message.guild), + ) logger.info("A new thread was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) @@ -928,7 +938,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: ) embed.set_footer( text=self.config["disabled_current_thread_footer"], - icon_url=self.guild.icon.url, + icon_url=self.get_guild_icon(guild=message.guild), ) logger.info("A message was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -1335,7 +1345,7 @@ async def handle_react_to_contact(self, payload): ) embed.set_footer( text=self.config["disabled_new_thread_footer"], - icon_url=self.guild.icon.url, + icon_url=self.get_guild_icon(guild=channel.guild), ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", diff --git a/cogs/modmail.py b/cogs/modmail.py index 75130fdb6e..1e4e00a8d0 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -160,7 +160,7 @@ async def snippet(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any snippets at the moment." ) embed.set_footer(text=f'Check "{self.bot.prefix}help snippet add" to add a snippet.') - embed.set_author(name="Snippets", icon_url=ctx.guild.icon.url) + embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) return await ctx.send(embed=embed) embeds = [] @@ -168,7 +168,7 @@ async def snippet(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): description = format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Snippets", icon_url=ctx.guild.icon.url) + embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1031,7 +1031,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.guild.icon.url + avatar_url = self.bot.get_guild_icon(guild=ctx.guild) em.set_footer(text=name, icon_url=avatar_url) for u in users: @@ -1120,7 +1120,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.guild.icon.url + avatar_url = self.bot.get_guild_icon(guild=ctx.guild) em.set_footer(text=name, icon_url=avatar_url) for u in users: @@ -1200,7 +1200,7 @@ async def logs_closed_by(self, ctx, *, user: User = None): user = user if user is not None else ctx.author entries = await self.bot.api.search_closed_by(user.id) - embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon.url) + embeds = self.format_log_embeds(entries, avatar_url=self.bot.get_guild_icon(guild=ctx.guild)) if not embeds: embed = discord.Embed( @@ -1250,7 +1250,7 @@ async def logs_responded(self, ctx, *, user: User = None): entries = await self.bot.api.get_responded_logs(user.id) - embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon.url) + embeds = self.format_log_embeds(entries, avatar_url=self.bot.get_guild_icon(guild=ctx.guild)) if not embeds: embed = discord.Embed( @@ -1275,7 +1275,7 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): entries = await self.bot.api.search_by_text(query, limit) - embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon.url) + embeds = self.format_log_embeds(entries, avatar_url=self.bot.get_guild_icon(guild=ctx.guild)) if not embeds: embed = discord.Embed( diff --git a/cogs/utility.py b/cogs/utility.py index 16c84af29d..5c0ea09eb3 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1020,7 +1020,7 @@ async def alias(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any aliases at the moment." ) embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') - embed.set_author(name="Aliases", icon_url=ctx.guild.icon.url) + embed.set_author(name="Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) return await ctx.send(embed=embed) embeds = [] @@ -1028,7 +1028,7 @@ async def alias(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.aliases)),) * 15)): description = utils.format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Command Aliases", icon_url=ctx.guild.icon.url) + embed.set_author(name="Command Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1611,7 +1611,9 @@ async def permissions_get( for name, level in takewhile(lambda x: x is not None, items) ) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Permission Overrides", icon_url=ctx.guild.icon.url) + embed.set_author( + name="Permission Overrides", icon_url=self.bot.get_guild_icon(guild=ctx.guild) + ) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) diff --git a/core/thread.py b/core/thread.py index 30f0542c6d..07f3108914 100644 --- a/core/thread.py +++ b/core/thread.py @@ -228,7 +228,7 @@ async def send_recipient_genesis_message(): else: footer = self.bot.config["thread_creation_footer"] - embed.set_footer(text=footer, icon_url=self.bot.guild.icon.url) + embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.modmail_guild)) embed.title = self.bot.config["thread_creation_title"] if creator is None or creator == recipient: @@ -521,7 +521,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, embed.description = message footer = self.bot.config["thread_close_footer"] - embed.set_footer(text=footer, icon_url=self.bot.guild.icon.url) + embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.guild)) if not silent: for user in self.recipients: @@ -957,7 +957,7 @@ async def send( name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.guild.icon.url + avatar_url = self.bot.get_guild_icon(guild=self.bot.guild) embed.set_author( name=name, icon_url=avatar_url, From ccc53ea5795ce3affcee9526d4f80a9f17b87c81 Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Mon, 5 Dec 2022 16:11:49 +0530 Subject: [PATCH 603/705] Update bot.py Co-authored-by: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 01d8a52c11..f060c5e246 100644 --- a/bot.py +++ b/bot.py @@ -92,7 +92,7 @@ def get_guild_icon(self, guild: typing.Optional[discord.Guild]) -> str: guild = self.guild if guild.icon is None: return self.user.display_avatar.url - return guild.icon_url + return guild.icon.url def _resolve_snippet(self, name: str) -> typing.Optional[str]: """ From f0e313c4917d6627e1e0001441a7ec38669fa016 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Dec 2022 14:24:59 -0800 Subject: [PATCH 604/705] Update changelog, and use default user icon instead of user avatar, so to not leak the user in anon commands --- CHANGELOG.md | 6 ++++++ bot.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cfeec9f8e..74d4ed5115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,14 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed +- Not having a guild icon no longer raises an exception. ([PR #3235](https://github.com/kyb3r/modmail/pull/3235)) + - When no icon is set, use the default user icon. - Resolved an issue where `?logs` doesn't work when the thread has no title. ([PR #3201](https://github.com/kyb3r/modmail/pull/3201)) +### Changed + +- Plain messages no longer forces `()` around the respondent text. ([PR #3234](https://github.com/kyb3r/modmail/pull/3234)) + # v4.0.1 This is a hotfix release. diff --git a/bot.py b/bot.py index 3602d37468..77aeb4142b 100644 --- a/bot.py +++ b/bot.py @@ -94,7 +94,7 @@ def get_guild_icon(self, guild: typing.Optional[discord.Guild]) -> str: if guild is None: guild = self.guild if guild.icon is None: - return self.user.display_avatar.url + return "https://cdn.discordapp.com/embed/avatars/0.png" return guild.icon.url def _resolve_snippet(self, name: str) -> typing.Optional[str]: From bb41861cf1e96c6bf8c4d50de99b23493cfc0d06 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 8 Dec 2022 14:42:08 -0800 Subject: [PATCH 605/705] Replaced discord.BadArgument with TypeError --- CHANGELOG.md | 1 + bot.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74d4ed5115..5bbc6910b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Not having a guild icon no longer raises an exception. ([PR #3235](https://github.com/kyb3r/modmail/pull/3235)) - When no icon is set, use the default user icon. - Resolved an issue where `?logs` doesn't work when the thread has no title. ([PR #3201](https://github.com/kyb3r/modmail/pull/3201)) +- AttributeError raised when failing to forward a reaction. ([GH #3218](https://github.com/kyb3r/modmail/issues/3218)) ### Changed diff --git a/bot.py b/bot.py index 77aeb4142b..2c8b8da73c 100644 --- a/bot.py +++ b/bot.py @@ -876,7 +876,7 @@ async def add_reaction( if reaction != "disable": try: await msg.add_reaction(reaction) - except (discord.HTTPException, discord.BadArgument) as e: + except (discord.HTTPException, TypeError) as e: logger.warning("Failed to add reaction %s: %s.", reaction, e) return False return True @@ -1304,7 +1304,7 @@ async def handle_reaction_events(self, payload): for msg in linked_messages: await msg.remove_reaction(reaction, self.user) await message.remove_reaction(reaction, self.user) - except (discord.HTTPException, discord.BadArgument) as e: + except (discord.HTTPException, TypeError) as e: logger.warning("Failed to remove reaction: %s", e) async def handle_react_to_contact(self, payload): From aed97d5b717e44698d4eb628f791c76dd59e7f1e Mon Sep 17 00:00:00 2001 From: Sattelite <90934664+Satellite-Galaxy@users.noreply.github.com> Date: Mon, 19 Dec 2022 05:15:52 -0500 Subject: [PATCH 606/705] Build and Push docker image to Githubs container registry (#3228) --- .github/workflows/docker-image.yml | 42 ++++++++++++++++++++++++++++++ Dockerfile | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000000..6af8630b38 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,42 @@ + +name: Create and publish a Docker image + +on: + push: + branches: ['master'] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v3 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index 2906f4508f..3c88a0e7ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9 as py +FROM python:3.10 as py FROM py as build From 88676e585af54a58e382e86543b5afed6093f3b2 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 19 Dec 2022 03:42:12 -0800 Subject: [PATCH 607/705] Update docker compose, changelog, and installation guide --- CHANGELOG.md | 2 + README.md | 131 ++++++++++++++++++++++++--------------------- docker-compose.yml | 4 +- 3 files changed, 74 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bbc6910b8..83cc9dd697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Changed - Plain messages no longer forces `()` around the respondent text. ([PR #3234](https://github.com/kyb3r/modmail/pull/3234)) +- Added workflow to automatically build Docker image ([PR #3232](https://github.com/kyb3r/modmail/pull/3228)) +- Updated installation guide to reflect new preferred hosting methods # v4.0.1 diff --git a/README.md b/README.md index 559d49ba65..a6ded0badd 100644 --- a/README.md +++ b/README.md @@ -84,80 +84,89 @@ This list is ever-growing thanks to active development and our exceptional contr ## Installation -Where can I find the Modmail bot invite link? +Q: Where can I find the Modmail bot invite link? + +A: Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time). + +There are a few options for hosting your very own dedicated Modmail bot. + +1. Patreon hosting +2. Local hosting (VPS, Dedicated Server, RPi, your computer, etc.) +3. PaaS (we provide a guide for Heroku) + +### Patreon Hosting + +If you don't want the trouble of renting and configuring your server to host Modmail, we got a solution for you! We offer hosting and maintenance of your own, private Modmail bot (including a Logviewer) through [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! + +### Local hosting (General Guide) + +Modmail can be hosted on any modern hardware, including your PC. For stability and reliability, we suggest purchasing a cloud server (VPS) for under $10/mo. If you need recommendations on choosing a VPS, join our [Discord server](https://discord.gg/j5e9p8w), and we'll send you a list of non-affiliated hosting providers. Alternatively, we can host Modmail for you when you're subscribed to our [Patreon](https://patreon.com/kyber). + +This guide assumes you've downloaded [`Python 3.10`](https://www.python.org/downloads/release/python-376/) and added python and pip to PATH. + +1. Clone this repo + ```console + $ git clone https://github.com/kyb3r/modmail + $ cd modmail + ``` +2. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/kyb3r/modmail/wiki/Installation#2-discord-bot-account)) +3. Create a free MongoDB database ([guide](https://github.com/kyb3r/modmail/wiki/Installation-(cont.)#3-create-a-database), follow it carefully!) +4. Rename the file `.env.example` to `.env` and fill it with appropriate values + - If you can't find `.env.example` because it's hidden, create a new text file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/kyb3r/modmail/master/.env.example) and replace the placeholders with their values + - If you're on Windows and cannot save the file as `.env`, save it as `.env.` instead (this only applies to Windows!) + - If you do not have a Logviewer yet, leave the `LOG_URL` field as-is +5. Update pip, install pipenv, and install dependencies using pipenv + ```console + $ pip install -U pip + $ pip install pipenv + $ pipenv install + ``` +6. Start the bot + ```console + $ pipenv run bot + ``` +7. Set up the Logviewer, see the [Logviewer installation guide](https://github.com/kyb3r/logviewer) + +### Local Hosting (Docker) + +We provide support for Docker to simplify the deployment of Modmail and Logviewer. +We assume you already have Docker and Docker Compose Plugin installed, if not, see [here](https://docs.docker.com/get-docker/). + +1. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/kyb3r/modmail/wiki/Installation#2-discord-bot-account)) +2. Create a file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/kyb3r/modmail/master/.env.example) and replace the placeholders with their values +3. Create a file named `docker-compose.yml`, then copy the contents of [this file](https://raw.githubusercontent.com/kyb3r/modmail/master/docker-compose.yml), do not change anything! +4. Start the bot + ```console + $ docker compose up -d + ``` + - For older Docker versions, you may need to run `docker-compose up -d` instead +5. View the status of your bot, using `docker ps` and `docker logs [container-id]` + +Our Docker images are hosted on [GitHub Container Registry](ghcr.io), you can build your own image if you wish: +```console +$ docker build --tag=modmail:master . +``` + +Then simply remove `ghcr.io/kyb3r/` from the `docker-compose.yml` file. -Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time). +### Local Hosting (OS-Specific) -### Heroku +This guide is a WIP. Join our [Discord server](https://discord.gg/j5e9p8w) for more info. -You can host this bot on Heroku. +### Platform as a Service (PaaS) + +You can host this bot on Heroku (no longer free). Installation via Heroku is possible with your web browser alone. The [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) (which includes a video tutorial!) will guide you through the entire installation process. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. -To configure automatic updates: +When using Heroku, you can configure automatic updates: - Login to [GitHub](https://github.com/) and verify your account. - [Fork the repo](https://github.com/kyb3r/modmail/fork). - Install the [Pull app](https://github.com/apps/pull) for your fork. - Then go to the Deploy tab in your [Heroku account](https://dashboard.heroku.com/apps) of your bot app, select GitHub and connect your fork (usually by typing "Modmail"). - Turn on auto-deploy for the `master` branch. -### Hosting for Patreons - -If you don't want to go through the trouble of setting up your very own Modmail bot or wish to support this project, we got a solution for you! We offer the complete installation, hosting, and maintenance of your Modmail with [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! - -### Locally - -Local hosting of Modmail is also possible. First, you will need at least [`Python 3.8`](https://www.python.org/downloads/release/python-376/). - -Follow the [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) and disregard deploying the Heroku bot application. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. - -Clone the repo: - -```console -$ git clone https://github.com/kyb3r/modmail -$ cd modmail -``` - -Install dependencies: - -```console -$ pipenv install -``` - -Rename the `.env.example` to `.env` and fill out the fields. If `.env.example` is nonexistent (hidden), create a text file named `.env` and copy the contents of [`.env.example`](https://raw.githubusercontent.com/kyb3r/modmail/master/.env.example) then modify the values. - -Finally, start Modmail. - -```console -$ pipenv run bot -``` - -#### Docker - -This repo supplies a Dockerfile for simplified deployment. - -You can build your own Docker image: - -```console -$ docker build . --tag=modmail -``` - -Or run directly from a pre-built version from https://hub.docker.com/. - -- Kyber's: - -```console -$ docker pull kyb3rr/modmail -``` - -And to run your docker image: - -```console -$ docker run --env-file .env kyb3rr/modmail -``` -- `.env` should be the path to your env file; you can also supply a path: `/path/to/.env`. - ## Sponsors Special thanks to our sponsors for supporting the project. diff --git a/docker-compose.yml b/docker-compose.yml index d3745c9b4c..0bdd3808bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.7" services: bot: - image: kyb3rr/modmail + image: ghcr.io/kyb3r/modmail:master restart: always env_file: - .env @@ -10,7 +10,7 @@ services: depends_on: - mongo logviewer: - image: kyb3rr/logviewer + image: ghcr.io/kyb3r/logviewer:master restart: always depends_on: - mongo From 6c690fe73403becbd0c388ebfbc19dfd77b244d9 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 19 Dec 2022 03:45:14 -0800 Subject: [PATCH 608/705] Fix black formatting --- bot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index 2c8b8da73c..a79981df5e 100644 --- a/bot.py +++ b/bot.py @@ -70,7 +70,7 @@ def __init__(self): self.config.populate_cache() intents = discord.Intents.all() - if not self.config['enable_presence_intent']: + if not self.config["enable_presence_intent"]: intents.presences = False super().__init__(command_prefix=None, intents=intents) # implemented in `get_prefix` @@ -229,7 +229,7 @@ async def runner(): self._connected = asyncio.Event() self.session = ClientSession(loop=self.loop) - if self.config['enable_presence_intent']: + if self.config["enable_presence_intent"]: logger.info("Starting bot with presence intent.") else: logger.info("Starting bot without presence intent.") From b693b27828437e771ec8496558b8992e7bdb6ee0 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 19 Dec 2022 03:47:39 -0800 Subject: [PATCH 609/705] Bump version to v4.0.2 --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83cc9dd697..87d32b7f60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2. however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# [Unreleased] +# v4.0.2 ### Breaking diff --git a/README.md b/README.md index a6ded0badd..0a71061fd0 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.0.1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.0.2-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index a79981df5e..b23b2449b2 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.1" +__version__ = "4.0.2" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 79a3e74f0b..468dc29112 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.1' +version = '4.0.2' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 11eef8b8e25d3b0600b3bdef06a6ad8a98cb85bd Mon Sep 17 00:00:00 2001 From: Stephen <48072084+StephenDaDev@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:14:45 -0500 Subject: [PATCH 610/705] Add alias make/create as an alias to alias add & add to changelog (#3195) --- CHANGELOG.md | 4 ++++ cogs/utility.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87d32b7f60..0450b47c9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# [UNRELEASED] + +### Fixed +- `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. # v4.0.2 diff --git a/cogs/utility.py b/cogs/utility.py index 5c0ea09eb3..ac642d9eb3 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1115,7 +1115,7 @@ async def make_alias(self, name, value, action): await self.bot.config.update() return embed - @alias.command(name="add") + @alias.command(name="add", aliases=["create", "make"]) @checks.has_permissions(PermissionLevel.MODERATOR) async def alias_add(self, ctx, name: str.lower, *, value): """ From c8b2522173b9923e8bfb009b7972ca7c40f72f43 Mon Sep 17 00:00:00 2001 From: Antonis Tatmichalis <44528553+lidistat67@users.noreply.github.com> Date: Tue, 20 Dec 2022 01:20:09 +0200 Subject: [PATCH 611/705] Fix silently order in help embed (#3215) --- cogs/modmail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 376f954cbe..5094e81890 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -483,7 +483,7 @@ async def close( Silently close a thread (no message) - `{prefix}close silently` - - `{prefix}close in 10m silently` + - `{prefix}close silently in 10m` Stop a thread from closing: - `{prefix}close cancel` From 485ab5ab936cb98748ad1f9d8825437dd15fc895 Mon Sep 17 00:00:00 2001 From: khakers <22665282+khakers@users.noreply.github.com> Date: Fri, 20 Jan 2023 16:30:30 -0800 Subject: [PATCH 612/705] Remove user fetching from blocked command (#3242) We already have all the information we need to mention a user (their id) and fetching the information from discord will lead to rate limiting and extremely poor performance on large block lists for no gain. --- cogs/modmail.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 5094e81890..484eb7aac8 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1665,13 +1665,7 @@ async def blocked(self, ctx): self.bot.blocked_users.pop(str(id_)) logger.debug("No longer blocked, user %s.", id_) continue - - try: - user = await self.bot.get_or_fetch_user(int(id_)) - except discord.NotFound: - users.append((id_, reason)) - else: - users.append((user.mention, reason)) + users.append((f"<@{id_}>", reason)) blocked_roles = list(self.bot.blocked_roles.items()) for id_, reason in blocked_roles: From d6eba12937d4e0024e1c9208d0ac22b365829397 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Fri, 20 Jan 2023 16:34:17 -0800 Subject: [PATCH 613/705] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0450b47c9a..dfb6e3f27d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s # [UNRELEASED] ### Fixed -- `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. +- `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) +- Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) # v4.0.2 From 8d41c1d4b25cdede91f2f18954e15ced9cbf7bb9 Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Wed, 8 Mar 2023 23:45:11 +0100 Subject: [PATCH 614/705] Added the option for registry_plugins_only (#3247) * Added the option for secure_plugins_only * Change config name * Forgot to update app.json * Forgot a period. Thanks taku :( --- app.json | 4 ++++ cogs/plugins.py | 8 ++++++++ core/config.py | 2 ++ 3 files changed, 14 insertions(+) diff --git a/app.json b/app.json index 66b5c77752..1cf5d107e4 100644 --- a/app.json +++ b/app.json @@ -34,6 +34,10 @@ "GITHUB_TOKEN": { "description": "A github personal access token with the repo scope.", "required": false + }, + "REGISTRY_PLUGINS_ONLY": { + "description": "If set to true, only plugins that are in the registry can be loaded.", + "required": false } } } \ No newline at end of file diff --git a/cogs/plugins.py b/cogs/plugins.py index 2bfac509af..c99f74ef40 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -302,6 +302,14 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): plugin = Plugin(user, repo, plugin_name, branch) else: + if not self.bot.config.get("registry_plugins_only", False): + embed = discord.Embed( + description="This plugin is not in the registry. " + "To install it, you must set `REGISTRY_PLUGINS_ONLY=false` in your .env file or config settings.", + color=self.bot.error_color, + ) + await ctx.send(embed=embed) + return try: plugin = Plugin.from_string(plugin_name) except InvalidPluginError: diff --git a/core/config.py b/core/config.py index 56db40c7b0..9a033167b7 100644 --- a/core/config.py +++ b/core/config.py @@ -167,6 +167,7 @@ class ConfigManager: "connection_uri": None, # replace mongo uri in the future "owners": None, "enable_presence_intent": False, + "registry_plugins_only": False, # bot "token": None, "enable_plugins": True, @@ -223,6 +224,7 @@ class ConfigManager: "thread_show_join_age", "use_hoisted_top_role", "enable_presence_intent", + "registry_plugins_only", } enums = { From 1f3bd0e9fcecb0be1feb217f174b47bb1d5e2251 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 12 Mar 2023 19:17:37 -0700 Subject: [PATCH 615/705] Update changelog and updated all the links to new repo (#3251) --- .github/CONTRIBUTING.md | 6 +- .github/pull.yml | 4 +- CHANGELOG.md | 236 +++++++++++++++++++++------------------- README.md | 48 ++++---- app.json | 2 +- cogs/modmail.py | 2 +- cogs/plugins.py | 4 +- cogs/utility.py | 6 +- core/changelog.py | 4 +- core/clients.py | 4 +- docker-compose.yml | 4 +- pyproject.toml | 4 +- 12 files changed, 166 insertions(+), 158 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b1309b6402..6c6694b809 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -30,11 +30,11 @@ Pull requests are the best way to propose changes to the codebase. We actively w ## Any contributions you make will be under the GNU Affero General Public License v3.0 In short, when you submit code changes, your submissions are understood to be under the same [GNU Affero General Public License v3.0](https://www.gnu.org/licenses/agpl-3.0.en.html) that covers the project. Feel free to contact the maintainers if that's a concern. -## Report bugs using [Github Issues](https://github.com/kyb3r/modmail/issues) -We use GitHub issues to track public bugs. Report a bug by [opening a new Issue](https://github.com/kyb3r/modmail/issues/new); it's that easy! +## Report bugs using [Github Issues](https://github.com/modmail-dev/modmail/issues) +We use GitHub issues to track public bugs. Report a bug by [opening a new Issue](https://github.com/modmail-dev/modmail/issues/new); it's that easy! ## Find pre-existing issues to tackle -Check out our [unstaged issue tracker](https://github.com/kyb3r/modmail/issues?q=is%3Aissue+is%3Aopen+-label%3Astaged) and start helping out! +Check out our [unstaged issue tracker](https://github.com/modmail-dev/modmail/issues?q=is%3Aissue+is%3Aopen+-label%3Astaged) and start helping out! Ways to help out: - Help out new members diff --git a/.github/pull.yml b/.github/pull.yml index 2fec8bbda0..8a0898a6b7 100644 --- a/.github/pull.yml +++ b/.github/pull.yml @@ -1,8 +1,8 @@ version: "1" rules: - base: master - upstream: kyb3r:master + upstream: modmail-dev:master mergeMethod: hardreset - base: development - upstream: kyb3r:development + upstream: modmail-dev:development mergeMethod: hardreset \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 87d32b7f60..46cf14177c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); -however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# [UNRELEASED] + +### Added +- New .env config option: `REGISTRY_PLUGINS_ONLY`, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) + +### Changed +- Repo moved to https://github.com/modmail-dev/modmail. + # v4.0.2 ### Breaking @@ -15,15 +23,15 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed -- Not having a guild icon no longer raises an exception. ([PR #3235](https://github.com/kyb3r/modmail/pull/3235)) +- Not having a guild icon no longer raises an exception. ([PR #3235](https://github.com/modmail-dev/modmail/pull/3235)) - When no icon is set, use the default user icon. -- Resolved an issue where `?logs` doesn't work when the thread has no title. ([PR #3201](https://github.com/kyb3r/modmail/pull/3201)) -- AttributeError raised when failing to forward a reaction. ([GH #3218](https://github.com/kyb3r/modmail/issues/3218)) +- Resolved an issue where `?logs` doesn't work when the thread has no title. ([PR #3201](https://github.com/modmail-dev/modmail/pull/3201)) +- AttributeError raised when failing to forward a reaction. ([GH #3218](https://github.com/modmail-dev/modmail/issues/3218)) ### Changed -- Plain messages no longer forces `()` around the respondent text. ([PR #3234](https://github.com/kyb3r/modmail/pull/3234)) -- Added workflow to automatically build Docker image ([PR #3232](https://github.com/kyb3r/modmail/pull/3228)) +- Plain messages no longer forces `()` around the respondent text. ([PR #3234](https://github.com/modmail-dev/modmail/pull/3234)) +- Added workflow to automatically build Docker image ([PR #3232](https://github.com/modmail-dev/modmail/pull/3228)) - Updated installation guide to reflect new preferred hosting methods # v4.0.1 @@ -43,59 +51,59 @@ This is a hotfix release. ### Breaking - Modmail now requires [`Message Content` privileged intent](https://support-dev.discord.com/hc/en-us/articles/4404772028055-Message-Content-Privileged-Intent-for-Verified-Bots). -- Upgraded to discord.py v2.0 ([internal changes](https://discordpy.readthedocs.io/en/latest/migrating.html), [GH #2990](https://github.com/kyb3r/modmail/issues/2990)). +- Upgraded to discord.py v2.0 ([internal changes](https://discordpy.readthedocs.io/en/latest/migrating.html), [GH #2990](https://github.com/modmail-dev/modmail/issues/2990)). - Python 3.8 or higher is required. - Asyncio changes ([gist](https://gist.github.com/Rapptz/6706e1c8f23ac27c98cee4dd985c8120)) - Plugin registry is purged and all developers have to re-apply due to breaking changes. ### Added -- `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/kyb3r/modmail/pull/3093)) -- `require_close_reason` config to require a reason to close a thread. ([GH #3107](https://github.com/kyb3r/modmail/issues/3107)) -- `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/kyb3r/modmail/issues/3083)) +- `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/modmail-dev/modmail/pull/3093)) +- `require_close_reason` config to require a reason to close a thread. ([GH #3107](https://github.com/modmail-dev/modmail/issues/3107)) +- `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/modmail-dev/modmail/issues/3083)) - `?fpareply` and `?fpreply` to reply to messages with variables plainly. -- `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/kyb3r/modmail/issues/3112)) -- `use_random_channel_name` config to use random nicknames vaguely tied to user ID. It is unable to be computed in reverse. ([GH #3143](https://github.com/kyb3r/modmail/issues/3143)) -- `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/kyb3r/modmail/issues/3122)) +- `use_nickname_channel_name` config to use nicknames instead of usernames for channel names. ([GH #3112](https://github.com/modmail-dev/modmail/issues/3112)) +- `use_random_channel_name` config to use random nicknames vaguely tied to user ID. It is unable to be computed in reverse. ([GH #3143](https://github.com/modmail-dev/modmail/issues/3143)) +- `show_log_url_button` config to show Log URL button. ([GH #3122](https://github.com/modmail-dev/modmail/issues/3122)) - Select menus for certain paginators. -- `Title` field in `?logs`. ([GH #3142](https://github.com/kyb3r/modmail/issues/3142)) -- Snippets can be used in aliases. ([GH #3108](https://github.com/kyb3r/modmail/issues/3108), [PR #3124](https://github.com/kyb3r/modmail/pull/3124)) -- `?snippet make/create` as aliases to `?snippet add`. ([GH #3172](https://github.com/kyb3r/modmail/issues/3173), [PR #3174](https://github.com/kyb3r/modmail/pull/3174)) +- `Title` field in `?logs`. ([GH #3142](https://github.com/modmail-dev/modmail/issues/3142)) +- Snippets can be used in aliases. ([GH #3108](https://github.com/modmail-dev/modmail/issues/3108), [PR #3124](https://github.com/modmail-dev/modmail/pull/3124)) +- `?snippet make/create` as aliases to `?snippet add`. ([GH #3172](https://github.com/modmail-dev/modmail/issues/3173), [PR #3174](https://github.com/modmail-dev/modmail/pull/3174)) ### Improved -- Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/kyb3r/modmail/issues/3048)) -- Use discord relative timedeltas. ([GH #3046](https://github.com/kyb3r/modmail/issues/3046)) +- Modmail now uses per-server avatars if applicable. ([GH #3048](https://github.com/modmail-dev/modmail/issues/3048)) +- Use discord relative timedeltas. ([GH #3046](https://github.com/modmail-dev/modmail/issues/3046)) - Use discord native buttons for all paginator sessions. - `?help` and `?blocked` paginator sessions now have better multi-page UI. - Autoupdate now automatically updates pipenv dependencies if possible. ### Fixed -- Several minor typos. ([PR #3095](https://github.com/kyb3r/modmail/pull/3095), [PR #3116](https://github.com/kyb3r/modmail/pull/3116)) -- Certain cases where fallback categories were not working as intended. ([PR #3109](https://github.com/kyb3r/modmail/pull/3109)) -- `?contact` would create in a random category in silent mode. ([GH #3091](https://github.com/kyb3r/modmail/issues/3091), [PR #3092](https://github.com/kyb3r/modmail/pull/3092)) -- Certain cases where `?close` would fail if closer isn't in cache. ([GH #3104](https://github.com/kyb3r/modmail/issues/3104), [PR #3105](https://github.com/kyb3r/modmail/pull/3105)) +- Several minor typos. ([PR #3095](https://github.com/modmail-dev/modmail/pull/3095), [PR #3116](https://github.com/modmail-dev/modmail/pull/3116)) +- Certain cases where fallback categories were not working as intended. ([PR #3109](https://github.com/modmail-dev/modmail/pull/3109)) +- `?contact` would create in a random category in silent mode. ([GH #3091](https://github.com/modmail-dev/modmail/issues/3091), [PR #3092](https://github.com/modmail-dev/modmail/pull/3092)) +- Certain cases where `?close` would fail if closer isn't in cache. ([GH #3104](https://github.com/modmail-dev/modmail/issues/3104), [PR #3105](https://github.com/modmail-dev/modmail/pull/3105)) - Stickers now work in Modmail. -- Large server sizes results in Guild.name == None. ([GH #3088](https://github.com/kyb3r/modmail/issues/3088)) -- Attachments now work on plain replies. ([GH #3102](https://github.com/kyb3r/modmail/issues/3102)) -- Support LOTTIE stickers. ([GH #3119](https://github.com/kyb3r/modmail/issues/3119)) -- Editing notes now work. ([GH #3094](https://github.com/kyb3r/modmail/issues/3094)) +- Large server sizes results in Guild.name == None. ([GH #3088](https://github.com/modmail-dev/modmail/issues/3088)) +- Attachments now work on plain replies. ([GH #3102](https://github.com/modmail-dev/modmail/issues/3102)) +- Support LOTTIE stickers. ([GH #3119](https://github.com/modmail-dev/modmail/issues/3119)) +- Editing notes now work. ([GH #3094](https://github.com/modmail-dev/modmail/issues/3094)) - Commands now work in threads. - Audit log searching now properly works. -- Old data causing `?blocked` to fail. ([GH #3131](https://github.com/kyb3r/modmail/issues/3131)) +- Old data causing `?blocked` to fail. ([GH #3131](https://github.com/modmail-dev/modmail/issues/3131)) - Delete channel auto close functionality now works. -- Improved error handling for autoupdate. ([PR #3161](https://github.com/kyb3r/modmail/pull/3161)) -- Skip loading of already-loaded cog. ([PR #3172](https://github.com/kyb3r/modmail/pull/3172)) -- Respect plugin's `cog_command_error`. ([GH #3170](https://github.com/kyb3r/modmail/issues/3170), [PR #3178](https://github.com/kyb3r/modmail/pull/3178)) -- Use silent as a typing literal for contacting. ([GH #3179](https://github.com/kyb3r/modmail/issues/3179)) +- Improved error handling for autoupdate. ([PR #3161](https://github.com/modmail-dev/modmail/pull/3161)) +- Skip loading of already-loaded cog. ([PR #3172](https://github.com/modmail-dev/modmail/pull/3172)) +- Respect plugin's `cog_command_error`. ([GH #3170](https://github.com/modmail-dev/modmail/issues/3170), [PR #3178](https://github.com/modmail-dev/modmail/pull/3178)) +- Use silent as a typing literal for contacting. ([GH #3179](https://github.com/modmail-dev/modmail/issues/3179)) ### Internal -- Improve regex parsing of channel topics. ([GH #3114](https://github.com/kyb3r/modmail/issues/3114), [PR #3111](https://github.com/kyb3r/modmail/pull/3111)) +- Improve regex parsing of channel topics. ([GH #3114](https://github.com/modmail-dev/modmail/issues/3114), [PR #3111](https://github.com/modmail-dev/modmail/pull/3111)) - Add warning if deploying on a developmental version. - Extensions are now loaded `on_connect`. -- MongoDB v5.0 clients are now supported. ([GH #3126](https://github.com/kyb3r/modmail/issues/3126)) +- MongoDB v5.0 clients are now supported. ([GH #3126](https://github.com/modmail-dev/modmail/issues/3126)) - Bump python-dotenv to v0.20.0, support for python 3.10 - Bump emoji to v1.7.0 - Bump aiohttp to v3.8.1 @@ -155,37 +163,37 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is ### Added -- Ability to have group conversations with up to 5 users. ([GH #143](https://github.com/kyb3r/modmail/issues/143)) -- Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080)) -- Default tags now use top hoisted role. ([GH #3014](https://github.com/kyb3r/modmail/issues/3014)) -- New thread-related config - `thread_show_roles`, `thread_show_account_age`, `thread_show_join_age`, `thread_cancelled`, `thread_creation_contact_title`, `thread_creation_self_contact_response`, `thread_creation_contact_response`. ([GH #3072](https://github.com/kyb3r/modmail/issues/3072)) +- Ability to have group conversations with up to 5 users. ([GH #143](https://github.com/modmail-dev/modmail/issues/143)) +- Snippets are invoked case insensitively. ([GH #3077](https://github.com/modmail-dev/modmail/issues/3077), [PR #3080](https://github.com/modmail-dev/modmail/pull/3080)) +- Default tags now use top hoisted role. ([GH #3014](https://github.com/modmail-dev/modmail/issues/3014)) +- New thread-related config - `thread_show_roles`, `thread_show_account_age`, `thread_show_join_age`, `thread_cancelled`, `thread_creation_contact_title`, `thread_creation_self_contact_response`, `thread_creation_contact_response`. ([GH #3072](https://github.com/modmail-dev/modmail/issues/3072)) - `use_timestamp_channel_name` config to create thread channels by timestamp. ### Improved -- `?contact` now accepts a role or multiple users (creates a group conversation). ([GH #3082](https://github.com/kyb3r/modmail/issues/3082)) -- Aliases are now supported in autotrigger. ([GH #3081](https://github.com/kyb3r/modmail/pull/3081)) +- `?contact` now accepts a role or multiple users (creates a group conversation). ([GH #3082](https://github.com/modmail-dev/modmail/issues/3082)) +- Aliases are now supported in autotrigger. ([GH #3081](https://github.com/modmail-dev/modmail/pull/3081)) ### Fixed -- Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/kyb3r/modmail/issues/3022), [PR #3028](https://github.com/kyb3r/modmail/pull/3028)) -- Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/kyb3r/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/kyb3r/modmail/pull/3027)) -- UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/kyb3r/modmail/pull/3043)) -- Notifications are no longer duplicated when using both `?notify` and `subscribe`. ([PR #3015](https://github.com/kyb3r/modmail/pull/3015)) -- `?contact` now works properly with both category and silent. ([GH #3076](https://github.com/kyb3r/modmail/issues/3076)) -- `close_on_leave_reason` now works properly when `close_on_leave` is enabled. ([GH #3075](https://github.com/kyb3r/modmail/issues/3075)) +- Certain situations where the internal thread cache breaks and spams new channels. ([GH #3022](https://github.com/modmail-dev/modmail/issues/3022), [PR #3028](https://github.com/modmail-dev/modmail/pull/3028)) +- Blocked users are now no longer allowed to use `?contact` and react to contact. ([COMMENT #819004157](https://github.com/modmail-dev/modmail/issues/2969#issuecomment-819004157), [PR #3027](https://github.com/modmail-dev/modmail/pull/3027)) +- UnicodeEncodeError will no longer be raised on Windows. ([PR #3043](https://github.com/modmail-dev/modmail/pull/3043)) +- Notifications are no longer duplicated when using both `?notify` and `subscribe`. ([PR #3015](https://github.com/modmail-dev/modmail/pull/3015)) +- `?contact` now works properly with both category and silent. ([GH #3076](https://github.com/modmail-dev/modmail/issues/3076)) +- `close_on_leave_reason` now works properly when `close_on_leave` is enabled. ([GH #3075](https://github.com/modmail-dev/modmail/issues/3075)) - Invalid arguments are now properly catched and a proper error message is sent. -- Update database after resetting/purging all plugins. ([GH #3011](https://github.com/kyb3r/modmail/pull/3011)) -- `thread_auto_close` timer now only resets on non-note and replies from mods. ([GH #3030](https://github.com/kyb3r/modmail/issues/3030)) -- Deleted messages are now deleted on both ends. ([GH #3041](https://github.com/kyb3r/modmail/issues/3041), [@JerrieAries](https://github.com/kyb3r/modmail/commit/20b31f8e8b5497943513997fef788d72ae668438)) -- Persistent notes are now properly deleted from the database. ([GH #3013](https://github.com/kyb3r/modmail/issues/3013)) +- Update database after resetting/purging all plugins. ([GH #3011](https://github.com/modmail-dev/modmail/pull/3011)) +- `thread_auto_close` timer now only resets on non-note and replies from mods. ([GH #3030](https://github.com/modmail-dev/modmail/issues/3030)) +- Deleted messages are now deleted on both ends. ([GH #3041](https://github.com/modmail-dev/modmail/issues/3041), [@JerrieAries](https://github.com/modmail-dev/modmail/commit/20b31f8e8b5497943513997fef788d72ae668438)) +- Persistent notes are now properly deleted from the database. ([GH #3013](https://github.com/modmail-dev/modmail/issues/3013)) - Modmail Bot is now recognized to have `OWNER` permission level. This affects what can be run in autotriggers. ### Internal -- Fix return types, type hints and unresolved references ([PR #3009](https://github.com/kyb3r/modmail/pull/3009)) -- Reload thread cache only when it's the first on_ready trigger. ([GH #3037](https://github.com/kyb3r/modmail/issues/3037)) -- `format_channel_name` is now extendable to plugins. Modify `Bot.format_channel_name(bot, author, exclude_channel=None, force_null=False):`. ([GH #2982](https://github.com/kyb3r/modmail/issues/2982)) +- Fix return types, type hints and unresolved references ([PR #3009](https://github.com/modmail-dev/modmail/pull/3009)) +- Reload thread cache only when it's the first on_ready trigger. ([GH #3037](https://github.com/modmail-dev/modmail/issues/3037)) +- `format_channel_name` is now extendable to plugins. Modify `Bot.format_channel_name(bot, author, exclude_channel=None, force_null=False):`. ([GH #2982](https://github.com/modmail-dev/modmail/issues/2982)) # v3.9.5 @@ -199,17 +207,17 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is ### Fixed -- Certain cases where fallback categories were not working as intended. ([GH #3002](https://github.com/kyb3r/modmail/issues/3002), [PR #3003](https://github.com/kyb3r/modmail/pull/3003)) +- Certain cases where fallback categories were not working as intended. ([GH #3002](https://github.com/modmail-dev/modmail/issues/3002), [PR #3003](https://github.com/modmail-dev/modmail/pull/3003)) - There is now a proper message when trying to contact a bot. ### Improved -- `?mention` can now be disabled with `?mention disable`. ([PR #2993](https://github.com/kyb3r/modmail/pull/2993/files)) -- `?mention` now allows vague entries such as `everyone` or `all`. ([PR #2993](https://github.com/kyb3r/modmail/pull/2993/files)) +- `?mention` can now be disabled with `?mention disable`. ([PR #2993](https://github.com/modmail-dev/modmail/pull/2993/files)) +- `?mention` now allows vague entries such as `everyone` or `all`. ([PR #2993](https://github.com/modmail-dev/modmail/pull/2993/files)) ### Internal -- Change heroku python version to 3.9.4 ([PR #3001](https://github.com/kyb3r/modmail/pull/3001)) +- Change heroku python version to 3.9.4 ([PR #3001](https://github.com/modmail-dev/modmail/pull/3001)) # v3.9.3 @@ -228,7 +236,7 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is ### Improved -- Additional HostingMethods (i.e. DOCKER, PM2, SCREEN). Autoupdates are now disabled on all docker instances. ([GH #2977](https://github.com/kyb3r/modmail/issues/2977), [PR #2988](https://github.com/kyb3r/modmail/pull/2988)) +- Additional HostingMethods (i.e. DOCKER, PM2, SCREEN). Autoupdates are now disabled on all docker instances. ([GH #2977](https://github.com/modmail-dev/modmail/issues/2977), [PR #2988](https://github.com/modmail-dev/modmail/pull/2988)) ### Fixed @@ -249,8 +257,8 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is ### Fixed -- `confirm_thread_creation` now properly works when a user opens a thread using react to contact. ([GH #2930](https://github.com/kyb3r/modmail/issues/2930), [PR #2971](https://github.com/kyb3r/modmail/pull/2971)) -- `?disable all/new` now disables react to contact threads. ([GH #2969](https://github.com/kyb3r/modmail/issues/2969), [PR #2971](https://github.com/kyb3r/modmail/pull/2971)) +- `confirm_thread_creation` now properly works when a user opens a thread using react to contact. ([GH #2930](https://github.com/modmail-dev/modmail/issues/2930), [PR #2971](https://github.com/modmail-dev/modmail/pull/2971)) +- `?disable all/new` now disables react to contact threads. ([GH #2969](https://github.com/modmail-dev/modmail/issues/2969), [PR #2971](https://github.com/modmail-dev/modmail/pull/2971)) - Ghost errors are no longer raised when threads are created using non-organic methods. ### Internal @@ -269,13 +277,13 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is ### Added -- `?msglink <message id>`, allows you to obtain channel + message ID for T&S reports. ([GH #2963](https://github.com/kyb3r/modmail/issues/2963), [PR #2964](https://github.com/kyb3r/modmail/pull/2964)) -- `?mention disable/reset`, disables or resets mention on thread creation. ([PR #2951](https://github.com/kyb3r/modmail/pull/2951)) +- `?msglink <message id>`, allows you to obtain channel + message ID for T&S reports. ([GH #2963](https://github.com/modmail-dev/modmail/issues/2963), [PR #2964](https://github.com/modmail-dev/modmail/pull/2964)) +- `?mention disable/reset`, disables or resets mention on thread creation. ([PR #2951](https://github.com/modmail-dev/modmail/pull/2951)) ### Fixed - Non-master/development branch deployments no longer cause errors to be raised. -- Autotriggers now can search for roles/channels in guild context. ([GH #2961](https://github.com/kyb3r/modmail/issues/2961)) +- Autotriggers now can search for roles/channels in guild context. ([GH #2961](https://github.com/modmail-dev/modmail/issues/2961)) # v3.8.4 @@ -289,28 +297,28 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Fixed -- Retry with `null-discrim` if channel could not be created. ([GH #2934](https://github.com/kyb3r/modmail/issues/2934)) +- Retry with `null-discrim` if channel could not be created. ([GH #2934](https://github.com/modmail-dev/modmail/issues/2934)) - Fix update notifications. -- Retrieve user from Discord API if user has left the server, resolving issues in `?block`. ([GH #2935](https://github.com/kyb3r/modmail/issues/2935), [PR #2936](https://github.com/kyb3r/modmail/pull/2936)) +- Retrieve user from Discord API if user has left the server, resolving issues in `?block`. ([GH #2935](https://github.com/modmail-dev/modmail/issues/2935), [PR #2936](https://github.com/modmail-dev/modmail/pull/2936)) - IDs in `<member>` commands work now. # v3.8.1 ### Fixed -- Additional image uploads now render properly. ([PR #2933](https://github.com/kyb3r/modmail/pull/2933)) -- `confirm_thread_creation` no longer raises unnecessary errors. ([GH #2931](https://github.com/kyb3r/modmail/issues/2931), [PR #2933](https://github.com/kyb3r/modmail/pull/2933)) -- Autotriggers no longer sends attachments back. ([GH #2932](https://github.com/kyb3r/modmail/issues/2932)) +- Additional image uploads now render properly. ([PR #2933](https://github.com/modmail-dev/modmail/pull/2933)) +- `confirm_thread_creation` no longer raises unnecessary errors. ([GH #2931](https://github.com/modmail-dev/modmail/issues/2931), [PR #2933](https://github.com/modmail-dev/modmail/pull/2933)) +- Autotriggers no longer sends attachments back. ([GH #2932](https://github.com/modmail-dev/modmail/issues/2932)) # v3.8.0 ### Added -- `update_notifications` configuration option to toggle bot autoupdate notifications. ([GH #2896](https://github.com/kyb3r/modmail/issues/2896)) +- `update_notifications` configuration option to toggle bot autoupdate notifications. ([GH #2896](https://github.com/modmail-dev/modmail/issues/2896)) - `?fareply`, anonymously reply with variables. -- `anonymous_snippets` config variable to toggle if snippets should be anonymous. ([GH #2905](https://github.com/kyb3r/modmail/issues/2905)) +- `anonymous_snippets` config variable to toggle if snippets should be anonymous. ([GH #2905](https://github.com/modmail-dev/modmail/issues/2905)) - `disable_updates` config variable to control if the update command should be disabled or not. -- `silent_alert_on_mention` to alert mods silently. ([GH #2907](https://github.com/kyb3r/modmail/issues/2907)) +- `silent_alert_on_mention` to alert mods silently. ([GH #2907](https://github.com/modmail-dev/modmail/issues/2907)) - Support for only the "Server Members" intent. ### Improved @@ -321,17 +329,17 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Fixed -- Mentioned `competing` as an activity type. ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) +- Mentioned `competing` as an activity type. ([PR #2902](https://github.com/modmail-dev/modmail/pull/2902)) - Level permissions were not checked if command permissions were set. - Regex autotriggers were not working if term was in the middle of strings. - `?blocked` now no longers show blocks that have expired. - Blocked roles will no longer trigger an error during unblock. -- Custom emojis are now supported in `confirm_thread_creation_deny`. ([GH #2916](https://github.com/kyb3r/modmail/issues/2916)) -- Finding linked messages in replies work now. ([GH #2920](https://github.com/kyb3r/modmail/issues/2920), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2920#issuecomment-751530495)) -- Sending files in threads (non-images) now work. ([GH #2926](https://github.com/kyb3r/modmail/issues/2926)) -- Deleting messages no longer shows a false error. ([GH #2910](https://github.com/kyb3r/modmail/issues/2910), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2910#issuecomment-753557313)) +- Custom emojis are now supported in `confirm_thread_creation_deny`. ([GH #2916](https://github.com/modmail-dev/modmail/issues/2916)) +- Finding linked messages in replies work now. ([GH #2920](https://github.com/modmail-dev/modmail/issues/2920), [Jerrie-Aries](https://github.com/modmail-dev/modmail/issues/2920#issuecomment-751530495)) +- Sending files in threads (non-images) now work. ([GH #2926](https://github.com/modmail-dev/modmail/issues/2926)) +- Deleting messages no longer shows a false error. ([GH #2910](https://github.com/modmail-dev/modmail/issues/2910), [Jerrie-Aries](https://github.com/modmail-dev/modmail/issues/2910#issuecomment-753557313)) - Display an error on [Lottie](https://airbnb.io/lottie/#/) stickers, instead of failing the send. -- `?perms get` now shows role/user names. ([PR #2927](https://github.com/kyb3r/modmail/pull/2927)) +- `?perms get` now shows role/user names. ([PR #2927](https://github.com/modmail-dev/modmail/pull/2927)) ### Internal @@ -370,13 +378,13 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Added - Added `update_channel_id` to specify which channel autoupdate notifications were being sent to. -- Added `show_timestamp` to specify if timestamps should be displayed in message embeds. ([GH #2885](https://github.com/kyb3r/modmail/issues/2885)) +- Added `show_timestamp` to specify if timestamps should be displayed in message embeds. ([GH #2885](https://github.com/modmail-dev/modmail/issues/2885)) # v3.7.9 ### Fixed -- `perms add/remove` with permission levels should now work again. ([GH #2892](https://github.com/kyb3r/modmail/issues/2892), [PR #2893](https://github.com/kyb3r/modmail/pull/2893)) +- `perms add/remove` with permission levels should now work again. ([GH #2892](https://github.com/modmail-dev/modmail/issues/2892), [PR #2893](https://github.com/modmail-dev/modmail/pull/2893)) ### Improved @@ -386,7 +394,7 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Added -- Added `thread_contact_silently` to allow opening threads silently by default. ([PR #2887](https://github.com/kyb3r/modmail/pull/2887)) +- Added `thread_contact_silently` to allow opening threads silently by default. ([PR #2887](https://github.com/modmail-dev/modmail/pull/2887)) ### Fixed - Permission levels were not respected. @@ -412,7 +420,7 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Fixed - Autoupdate persists despite errors. -- Mention when normal thread created was not working. ([GH #2883](https://github.com/kyb3r/modmail/issues/2883)) +- Mention when normal thread created was not working. ([GH #2883](https://github.com/modmail-dev/modmail/issues/2883)) # v3.7.5 @@ -424,13 +432,13 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Fixed -- React to contact threads were treated like normal contact threads. ([GH #2881](https://github.com/kyb3r/modmail/issues/2881)) +- React to contact threads were treated like normal contact threads. ([GH #2881](https://github.com/modmail-dev/modmail/issues/2881)) # v3.7.2 ### Added -- Added `mention_channel_id` to specify which channel `alert_on_mention` was being sent to. ([GH #2880](https://github.com/kyb3r/modmail/issues/2880)) +- Added `mention_channel_id` to specify which channel `alert_on_mention` was being sent to. ([GH #2880](https://github.com/modmail-dev/modmail/issues/2880)) ### Fixed @@ -447,31 +455,31 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Added -- Plain replies functionality. Added commands `preply`, `pareply` and config `plain_reply_without_command`. ([GH #2872](https://github.com/kyb3r/modmail/issues/2872)) +- Plain replies functionality. Added commands `preply`, `pareply` and config `plain_reply_without_command`. ([GH #2872](https://github.com/modmail-dev/modmail/issues/2872)) - Added `react_to_contact_message`, `react_to_contact_emoji` to allow users to create threads by reacting to a message. -- Added `thread_move_notify_mods` to mention all mods again after moving thread. ([GH #215](https://github.com/kyb3r/modmail/issues/215)) -- Added `transfer_reactions` to link reactions between mods and users. ([GH #2763](https://github.com/kyb3r/modmail/issues/2763)) -- Added `close_on_leave`, `close_on_leave_reason` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/kyb3r/modmail/issues/2757)) -- Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/kyb3r/modmail/issues/2833)) -- Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/kyb3r/modmail/issues/2773)) -- Support Gyazo image links in message embeds. ([GH #282](https://github.com/kyb3r/modmail/issues/282)) +- Added `thread_move_notify_mods` to mention all mods again after moving thread. ([GH #215](https://github.com/modmail-dev/modmail/issues/215)) +- Added `transfer_reactions` to link reactions between mods and users. ([GH #2763](https://github.com/modmail-dev/modmail/issues/2763)) +- Added `close_on_leave`, `close_on_leave_reason` to automatically close threads upon recipient leaving the server. ([GH #2757](https://github.com/modmail-dev/modmail/issues/2757)) +- Added `alert_on_mention` to mention mods upon a bot mention. ([GH #2833](https://github.com/modmail-dev/modmail/issues/2833)) +- Added `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny` to allow users to confirm that they indeed want to create a new thread. ([GH #2773](https://github.com/modmail-dev/modmail/issues/2773)) +- Support Gyazo image links in message embeds. ([GH #282](https://github.com/modmail-dev/modmail/issues/282)) - Added `silent` argument to `?contact` to restore old behaviour. -- Added new functionality: If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/kyb3r/modmail/issues/2847)) -- Added a way to block roles. ([GH #2753](https://github.com/kyb3r/modmail/issues/2753)) -- Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865)) -- Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/kyb3r/modmail/issues/2762)) +- Added new functionality: If `?help` is sent, bot does checks on every command, `?help all` restores old behaviour. ([GH #2847](https://github.com/modmail-dev/modmail/issues/2847)) +- Added a way to block roles. ([GH #2753](https://github.com/modmail-dev/modmail/issues/2753)) +- Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/modmail-dev/modmail/issues/2865)) +- Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/modmail-dev/modmail/issues/2762)) - Support stickers and reject non-messages. (i.e. pin_add) -- Added support for thread titles, `?title`. ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) +- Added support for thread titles, `?title`. ([GH #2838](https://github.com/modmail-dev/modmail/issues/2838)) - Added `data_collection` to specify if bot metadata should be collected by Modmail developers. -- Added `?autotrigger`, `use_regex_autotrigger` config to specify keywords to trigger commands. ([GH #130](https://github.com/kyb3r/modmail/issues/130), [GH #649](https://github.com/kyb3r/modmail/issues/649)) -- Added `?note persistent` that creates notes that are persistent for a user. ([GH #2842](https://github.com/kyb3r/modmail/issues/2842), [PR #2878](https://github.com/kyb3r/modmail/pull/2878)) +- Added `?autotrigger`, `use_regex_autotrigger` config to specify keywords to trigger commands. ([GH #130](https://github.com/modmail-dev/modmail/issues/130), [GH #649](https://github.com/modmail-dev/modmail/issues/649)) +- Added `?note persistent` that creates notes that are persistent for a user. ([GH #2842](https://github.com/modmail-dev/modmail/issues/2842), [PR #2878](https://github.com/modmail-dev/modmail/pull/2878)) - Autoupdates and `?update` which was removed in v3.0.0 ### Fixed - `?contact` now sends members a DM. -- `level_permissions` and `command_permissions` would sometimes be reset. ([GH #2856](https://github.com/kyb3r/modmail/issues/2856)) -- Command truncated after && in alias. ([GH #2870](https://github.com/kyb3r/modmail/issues/2870)) +- `level_permissions` and `command_permissions` would sometimes be reset. ([GH #2856](https://github.com/modmail-dev/modmail/issues/2856)) +- Command truncated after && in alias. ([GH #2870](https://github.com/modmail-dev/modmail/issues/2870)) - `on_plugins_ready` event for plugins works now. ### Improved @@ -480,7 +488,7 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh - `?move` now does not require exact category names, accepts case-insensitive and startswith names. ### Internal -- Use enums in config. ([GH #2821](https://github.com/kyb3r/modmail/issues/2821)) +- Use enums in config. ([GH #2821](https://github.com/modmail-dev/modmail/issues/2821)) - `on_thread_close` event for plugins. - `on_thread_reply` event for plugins. @@ -503,14 +511,14 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh ### Added - Added `thread_move_title` to specify title of thread moved embed. -- Mark NSFW logs in log message. ([GH #2792](https://github.com/kyb3r/modmail/issues/2792)) -- Icon for moderator that closed the thread in log message. ([GH #2828](https://github.com/kyb3r/modmail/issues/2828)) -- Ability to set mentions via user/role ID. ([GH #2796](https://github.com/kyb3r/modmail/issues/2796)) +- Mark NSFW logs in log message. ([GH #2792](https://github.com/modmail-dev/modmail/issues/2792)) +- Icon for moderator that closed the thread in log message. ([GH #2828](https://github.com/modmail-dev/modmail/issues/2828)) +- Ability to set mentions via user/role ID. ([GH #2796](https://github.com/modmail-dev/modmail/issues/2796)) ### Changed - `?move` now consumes rest in category name, which means `?move Long Category Name` works without quotes! -- `?help` shows "No command description" if no description provided. ([PR #2845](https://github.com/kyb3r/modmail/pull/2845)) +- `?help` shows "No command description" if no description provided. ([PR #2845](https://github.com/modmail-dev/modmail/pull/2845)) ### Fixed - Unicode errors raised during windows selfhosting @@ -519,7 +527,7 @@ This update is a quick hotfix for a weird behaviour experienced on 1 Feb 2021 wh - Bump discord.py version to 1.5.1 - Explicitly state intents used for connection -- Use `--diff` for black CI instead of `--check` ([GH #2816](https://github.com/kyb3r/modmail/issues/2816)) +- Use `--diff` for black CI instead of `--check` ([GH #2816](https://github.com/modmail-dev/modmail/issues/2816)) # v3.5.0 @@ -529,7 +537,7 @@ Fixed discord.py issue. ### Added - A confirmation when you manually delete a thread message embed. -- Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. ([GH #2803](https://github.com/kyb3r/modmail/issues/2803)) +- Config var `enable_eval` defaults true, set `enable_eval=no` to disable the eval command. ([GH #2803](https://github.com/modmail-dev/modmail/issues/2803)) - Added `?plugins reset` command to completely reset everything related to plugins. This will fix some problems caused by broken plugins in the file system. - Support private GitHub repos for plugins (thanks to @officialpiyush pr#2767) @@ -838,7 +846,7 @@ Security update! - Removed auto-update functionality and the `?update` command in favor of the [Pull app](https://github.com/apps/pull). -Read more about updating your bot [here](https://github.com/kyb3r/modmail/wiki/updating) +Read more about updating your bot [here](https://github.com/modmail-dev/modmail/wiki/updating) ### Changed - Channel names now can contain Unicode characters. @@ -883,7 +891,7 @@ Added a 🛑 reaction to the paginators to delete the embed. ### Fixed -`?blocked` is now paginated using reactions. This fixes [#249](https://github.com/kyb3r/modmail/issues/249) +`?blocked` is now paginated using reactions. This fixes [#249](https://github.com/modmail-dev/modmail/issues/249) # v2.21.0 @@ -922,7 +930,7 @@ This update contains mostly internal changes. ### What's new? -New `?oauth whitelist` command, which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app, check the logviewer [repo](https://github.com/kyb3r/logviewer). +New `?oauth whitelist` command, which allows you to whitelist users so they can log in via discord to view logs. To set up oauth login for your logviewer app, check the logviewer [repo](https://github.com/modmail-dev/logviewer). # v2.19.1 @@ -1207,7 +1215,7 @@ Added image link in title in case discord fails to embed an image. ### What's new? - Plugins: - Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it. Add a welcome message to Modmail, or moderation commands? It's all up to your imagination! Have a niche feature request that you think only your server would benefit? Plugins are your go-to! - - [Creating Plugins Documentation](https://github.com/kyb3r/modmail/wiki/Plugins). + - [Creating Plugins Documentation](https://github.com/modmail-dev/modmail/wiki/Plugins). # v2.12.5 @@ -1218,7 +1226,7 @@ Added image link in title in case discord fails to embed an image. # v2.12.4 ### What's new? -- Named colors are now supported! Over 900 different common color names are recognized. A list of color names can be found in [core/_color_data.py](https://github.com/kyb3r/modmail/blob/master/core/_color_data.py). +- Named colors are now supported! Over 900 different common color names are recognized. A list of color names can be found in [core/_color_data.py](https://github.com/modmail-dev/modmail/blob/master/core/_color_data.py). - Named colors can be set the same way as hex. But this can only be done through `config set`, which means database modifications will not work. - For example: `config set main_color yellowish green`. - New config var `main_color` allows you to customize the main Modmail color (as requested by many). Defaults to Discord `blurple`. @@ -1412,7 +1420,7 @@ Thread channels will now default to being private (`@everyone`'s read message pe ### Background - Bots hosted by Heroku restart at least once every 27 hours. - During this period, local caches will be deleted, which results in the inability to set the scheduled close time to longer than 24 hours. This update resolves this issue. -- [PR #135](https://github.com/kyb3r/modmail/pull/135) +- [PR #135](https://github.com/modmail-dev/modmail/pull/135) ### Changed - Created a new internal config var: `closures`. @@ -1450,7 +1458,7 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o ### What's new? - Added the `?activity` command for setting the activity -- [PR #131](https://github.com/kyb3r/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening`, and `streaming`). +- [PR #131](https://github.com/modmail-dev/modmail/pull/131#issue-244686818) this supports multiple activity types (`playing`, `watching`, `listening`, and `streaming`). ### Removed - Removed the deprecated `status` command. @@ -1583,9 +1591,9 @@ Fixed a bug in the `?activity` command where it would fail to set the activity o # v2.0.0 -This release introduces the use of our centralized [API service](https://github.com/kyb3r/webserver) to enable dynamic configuration, auto-updates, and thread logs. +This release introduces the use of our centralized [API service](https://github.com/modmail-dev/webserver) to enable dynamic configuration, auto-updates, and thread logs. To use this release, you must acquire an API token from https://modmail.tk. -Read the updated installation guide [here](https://github.com/kyb3r/modmail/wiki/installation). +Read the updated installation guide [here](https://github.com/modmail-dev/modmail/wiki/installation). ### Changed - Stability improvements through synchronization primitives. diff --git a/README.md b/README.md index 0a71061fd0..062bf6d8a4 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,16 @@ <br> - <a href="https://heroku.com/deploy?template=https://github.com/kyb3r/modmail"> + <a href="https://heroku.com/deploy?template=https://github.com/modmail-dev/modmail"> <img src="https://img.shields.io/badge/deploy_to-heroku-997FBC.svg?style=for-the-badge&logo=Heroku"> </a> - <a href="https://github.com/kyb3r/modmail/"> + <a href="https://github.com/modmail-dev/modmail/"> <img src="https://api.modmail.dev/badges/instances.svg" alt="Bot instances"> </a> - <a href="https://discord.gg/j5e9p8w"> - <img src="https://img.shields.io/discord/515071617815019520.svg?label=Discord&logo=Discord&colorB=7289da&style=for-the-badge" alt="Support"> + <a href="https://discord.gg/cnUpwrnpYb"> + <img src="https://img.shields.io/discord/1079074933008781362.svg?label=Discord&logo=Discord&colorB=7289da&style=for-the-badge" alt="Support"> </a> <a href="https://patreon.com/kyber"> @@ -35,7 +35,7 @@ <img src="https://img.shields.io/badge/Code%20Style-Black-black?style=for-the-badge"> </a> - <a href="https://github.com/kyb3r/modmail/blob/master/LICENSE"> + <a href="https://github.com/modmail-dev/modmail/blob/master/LICENSE"> <img src="https://img.shields.io/badge/license-agpl-e74c3c.svg?style=for-the-badge" alt="MIT License"> </a> @@ -96,23 +96,23 @@ There are a few options for hosting your very own dedicated Modmail bot. ### Patreon Hosting -If you don't want the trouble of renting and configuring your server to host Modmail, we got a solution for you! We offer hosting and maintenance of your own, private Modmail bot (including a Logviewer) through [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for more info! +If you don't want the trouble of renting and configuring your server to host Modmail, we got a solution for you! We offer hosting and maintenance of your own, private Modmail bot (including a Logviewer) through [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/cnUpwrnpYb) for more info! ### Local hosting (General Guide) -Modmail can be hosted on any modern hardware, including your PC. For stability and reliability, we suggest purchasing a cloud server (VPS) for under $10/mo. If you need recommendations on choosing a VPS, join our [Discord server](https://discord.gg/j5e9p8w), and we'll send you a list of non-affiliated hosting providers. Alternatively, we can host Modmail for you when you're subscribed to our [Patreon](https://patreon.com/kyber). +Modmail can be hosted on any modern hardware, including your PC. For stability and reliability, we suggest purchasing a cloud server (VPS) for under $10/mo. If you need recommendations on choosing a VPS, join our [Discord server](https://discord.gg/cnUpwrnpYb), and we'll send you a list of non-affiliated hosting providers. Alternatively, we can host Modmail for you when you're subscribed to our [Patreon](https://patreon.com/kyber). This guide assumes you've downloaded [`Python 3.10`](https://www.python.org/downloads/release/python-376/) and added python and pip to PATH. 1. Clone this repo ```console - $ git clone https://github.com/kyb3r/modmail + $ git clone https://github.com/modmail-dev/modmail $ cd modmail ``` -2. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/kyb3r/modmail/wiki/Installation#2-discord-bot-account)) -3. Create a free MongoDB database ([guide](https://github.com/kyb3r/modmail/wiki/Installation-(cont.)#3-create-a-database), follow it carefully!) +2. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/modmail-dev/modmail/wiki/Installation#2-discord-bot-account)) +3. Create a free MongoDB database ([guide](https://github.com/modmail-dev/modmail/wiki/Installation-(cont.)#3-create-a-database), follow it carefully!) 4. Rename the file `.env.example` to `.env` and fill it with appropriate values - - If you can't find `.env.example` because it's hidden, create a new text file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/kyb3r/modmail/master/.env.example) and replace the placeholders with their values + - If you can't find `.env.example` because it's hidden, create a new text file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/modmail-dev/modmail/master/.env.example) and replace the placeholders with their values - If you're on Windows and cannot save the file as `.env`, save it as `.env.` instead (this only applies to Windows!) - If you do not have a Logviewer yet, leave the `LOG_URL` field as-is 5. Update pip, install pipenv, and install dependencies using pipenv @@ -125,16 +125,16 @@ This guide assumes you've downloaded [`Python 3.10`](https://www.python.org/down ```console $ pipenv run bot ``` -7. Set up the Logviewer, see the [Logviewer installation guide](https://github.com/kyb3r/logviewer) +7. Set up the Logviewer, see the [Logviewer installation guide](https://github.com/modmail-dev/logviewer) ### Local Hosting (Docker) We provide support for Docker to simplify the deployment of Modmail and Logviewer. We assume you already have Docker and Docker Compose Plugin installed, if not, see [here](https://docs.docker.com/get-docker/). -1. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/kyb3r/modmail/wiki/Installation#2-discord-bot-account)) -2. Create a file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/kyb3r/modmail/master/.env.example) and replace the placeholders with their values -3. Create a file named `docker-compose.yml`, then copy the contents of [this file](https://raw.githubusercontent.com/kyb3r/modmail/master/docker-compose.yml), do not change anything! +1. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/modmail-dev/modmail/wiki/Installation#2-discord-bot-account)) +2. Create a file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/modmail-dev/modmail/master/.env.example) and replace the placeholders with their values +3. Create a file named `docker-compose.yml`, then copy the contents of [this file](https://raw.githubusercontent.com/modmail-dev/modmail/master/docker-compose.yml), do not change anything! 4. Start the bot ```console $ docker compose up -d @@ -147,22 +147,22 @@ Our Docker images are hosted on [GitHub Container Registry](ghcr.io), you can bu $ docker build --tag=modmail:master . ``` -Then simply remove `ghcr.io/kyb3r/` from the `docker-compose.yml` file. +Then simply remove `ghcr.io/modmail-dev/` from the `docker-compose.yml` file. ### Local Hosting (OS-Specific) -This guide is a WIP. Join our [Discord server](https://discord.gg/j5e9p8w) for more info. +This guide is a WIP. Join our [Discord server](https://discord.gg/cnUpwrnpYb) for more info. ### Platform as a Service (PaaS) You can host this bot on Heroku (no longer free). Installation via Heroku is possible with your web browser alone. -The [**installation guide**](https://github.com/kyb3r/modmail/wiki/Installation) (which includes a video tutorial!) will guide you through the entire installation process. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/etJNHCQ) for help and support. +The [**installation guide**](https://github.com/modmail-dev/modmail/wiki/Installation) (which includes a video tutorial!) will guide you through the entire installation process. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/cnUpwrnpYb) for help and support. When using Heroku, you can configure automatic updates: - Login to [GitHub](https://github.com/) and verify your account. - - [Fork the repo](https://github.com/kyb3r/modmail/fork). + - [Fork the repo](https://github.com/modmail-dev/modmail/fork). - Install the [Pull app](https://github.com/apps/pull) for your fork. - Then go to the Deploy tab in your [Heroku account](https://dashboard.heroku.com/apps) of your bot app, select GitHub and connect your fork (usually by typing "Modmail"). - Turn on auto-deploy for the `master` branch. @@ -213,20 +213,20 @@ Become a sponsor on [Patreon](https://patreon.com/kyber). Modmail supports the use of third-party plugins to extend or add functionalities to the bot. Plugins allow niche features as well as anything else outside of the scope of the core functionality of Modmail. -You can find a list of third-party plugins using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/kyb3r/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. +You can find a list of third-party plugins using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/modmail-dev/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. -To develop your own, check out the [plugins documentation](https://github.com/kyb3r/modmail/wiki/Plugins). +To develop your own, check out the [plugins documentation](https://github.com/modmail-dev/modmail/wiki/Plugins). -Plugins requests and support are available in our [Modmail Support Server](https://discord.gg/j5e9p8w). +Plugins requests and support are available in our [Modmail Support Server](https://discord.gg/cnUpwrnpYb). ## Contributing -Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/kyb3r/modmail/blob/master/.github/CONTRIBUTING.md) before you get started. +Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/modmail-dev/modmail/blob/master/.github/CONTRIBUTING.md) before you get started. If you like this project and would like to show your appreciation, support us on **[Patreon](https://www.patreon.com/kyber)**! ## Beta Testing -Our [development](https://github.com/kyb3r/modmail/tree/development) branch is where most of our features are tested before public release. Be warned that there could be bugs in various commands so keep it away from any large servers you manage. +Our [development](https://github.com/modmail-dev/modmail/tree/development) branch is where most of our features are tested before public release. Be warned that there could be bugs in various commands so keep it away from any large servers you manage. If you wish to test the new features and play around with them, feel free to join our [Public Test Server](https://discord.gg/v5hTjKC). Bugs can be raised within that server or in our Github issues (state that you are using the development branch though). diff --git a/app.json b/app.json index 1cf5d107e4..eee99b54bf 100644 --- a/app.json +++ b/app.json @@ -1,7 +1,7 @@ { "name": "Modmail", "description": "An easy to install Modmail bot for Discord - DM to contact mods!", - "repository": "https://github.com/kyb3r/modmail", + "repository": "https://github.com/modmail-dev/modmail", "env": { "TOKEN": { "description": "Your discord bot's token.", diff --git a/cogs/modmail.py b/cogs/modmail.py index 376f954cbe..d620520487 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -94,7 +94,7 @@ async def setup(self, ctx): embed.add_field( name="Thanks for using our bot!", value="If you like what you see, consider giving the " - "[repo a star](https://github.com/kyb3r/modmail) :star: and if you are " + "[repo a star](https://github.com/modmail-dev/modmail) :star: and if you are " "feeling extra generous, buy us coffee on [Patreon](https://patreon.com/kyber) :heart:!", ) diff --git a/cogs/plugins.py b/cogs/plugins.py index c99f74ef40..f225d90caa 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -114,7 +114,7 @@ class Plugins(commands.Cog): These addons could have a range of features from moderation to simply making your life as a moderator easier! Learn how to create a plugin yourself here: - https://github.com/kyb3r/modmail/wiki/Plugins + https://github.com/modmail-dev/modmail/wiki/Plugins """ def __init__(self, bot): @@ -131,7 +131,7 @@ async def cog_load(self): logger.info("Plugins not loaded since ENABLE_PLUGINS=false.") async def populate_registry(self): - url = "https://raw.githubusercontent.com/kyb3r/modmail/master/plugins/registry.json" + url = "https://raw.githubusercontent.com/modmail-dev/modmail/master/plugins/registry.json" async with self.bot.session.get(url) as resp: self.registry = json.loads(await resp.text()) diff --git a/cogs/utility.py b/cogs/utility.py index 5c0ea09eb3..bcc1ea951a 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -351,7 +351,7 @@ async def about(self, ctx): embed.add_field( name="Want Modmail in Your Server?", - value="Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " + value="Follow the installation guide on [GitHub](https://github.com/modmail-dev/modmail/) " "and join our [Discord server](https://discord.gg/F34cRU8)!", inline=False, ) @@ -380,7 +380,7 @@ async def sponsors(self, ctx): """Shows the sponsors of this project.""" async with self.bot.session.get( - "https://raw.githubusercontent.com/kyb3r/modmail/master/SPONSORS.json" + "https://raw.githubusercontent.com/modmail-dev/modmail/master/SPONSORS.json" ) as resp: data = loads(await resp.text()) @@ -1941,7 +1941,7 @@ async def update(self, ctx, *, flag: str = ""): desc = ( f"The latest version is [`{self.bot.version}`]" - "(https://github.com/kyb3r/modmail/blob/master/bot.py#L1)" + "(https://github.com/modmail-dev/modmail/blob/master/bot.py#L1)" ) if self.bot.version >= parse_version(latest.version) and flag.lower() != "force": diff --git a/core/changelog.py b/core/changelog.py index a4f88ed323..06f141fce1 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -53,7 +53,7 @@ def __init__(self, bot, branch: str, version: str, lines: str): self.version = version.lstrip("vV") self.lines = lines.strip() self.fields = {} - self.changelog_url = f"https://github.com/kyb3r/modmail/blob/{branch}/CHANGELOG.md" + self.changelog_url = f"https://github.com/modmail-dev/modmail/blob/{branch}/CHANGELOG.md" self.description = "" self.parse() @@ -186,7 +186,7 @@ async def from_url(cls, bot, url: str = "") -> "Changelog": if branch not in ("master", "development"): branch = "master" - url = url or f"https://raw.githubusercontent.com/kyb3r/modmail/{branch}/CHANGELOG.md" + url = url or f"https://raw.githubusercontent.com/modmail-dev/modmail/{branch}/CHANGELOG.md" async with await bot.session.get(url) as resp: return cls(bot, branch, await resp.text()) diff --git a/core/clients.py b/core/clients.py index eebe3bcff6..f504b7051d 100644 --- a/core/clients.py +++ b/core/clients.py @@ -63,10 +63,10 @@ class GitHub: """ BASE = "https://api.github.com" - REPO = BASE + "/repos/kyb3r/modmail" + REPO = BASE + "/repos/modmail-dev/modmail" MERGE_URL = BASE + "/repos/{username}/modmail/merges" FORK_URL = REPO + "/forks" - STAR_URL = BASE + "/user/starred/kyb3r/modmail" + STAR_URL = BASE + "/user/starred/modmail-dev/modmail" def __init__(self, bot, access_token: str = "", username: str = "", **kwargs): self.bot = bot diff --git a/docker-compose.yml b/docker-compose.yml index 0bdd3808bd..fcb0e1b32f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.7" services: bot: - image: ghcr.io/kyb3r/modmail:master + image: ghcr.io/modmail-dev/modmail:master restart: always env_file: - .env @@ -10,7 +10,7 @@ services: depends_on: - mongo logviewer: - image: ghcr.io/kyb3r/logviewer:master + image: ghcr.io/modmail-dev/logviewer:master restart: always depends_on: - mongo diff --git a/pyproject.toml b/pyproject.toml index 468dc29112..751cc5a75a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,8 +30,8 @@ authors = [ 'Taki <noemail@example.com>' ] readme = 'README.md' -repository = 'https://github.com/kyb3r/modmail' -homepage = 'https://github.com/kyb3r/modmail' +repository = 'https://github.com/modmail-dev/modmail' +homepage = 'https://github.com/modmail-dev/modmail' keywords = ['discord', 'modmail'] [tool.pylint.format] From 960a36ea04774ab449f1b2c51a24f8fb8822ae7e Mon Sep 17 00:00:00 2001 From: Spencer C <109806759+SpencerIsGiddy@users.noreply.github.com> Date: Tue, 14 Mar 2023 07:00:23 -0400 Subject: [PATCH 616/705] Lints: update to setup Python v4 (#3243) * Update lints.yml * Update lints.yml --------- Co-authored-by: Spencer Comfort <109806759+GiddyGoatGaming@users.noreply.github.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- .github/workflows/lints.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 21bf39368e..0f254d2980 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} architecture: x64 From e91930440aebfedc425b067791b5e92f2533bdfe Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 14 Mar 2023 04:00:54 -0700 Subject: [PATCH 617/705] Remove python 3.8 and windows/macos lint check. (#3258) Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --- .github/workflows/lints.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 0f254d2980..eaad52221f 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -4,13 +4,12 @@ on: [push, pull_request] jobs: code-style: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.9', '3.10'] - name: Python ${{ matrix.python-version }} on ${{ matrix.os }} + name: Python ${{ matrix.python-version }} on ubuntu-latest steps: - uses: actions/checkout@v3 From f2a434b0f0c32f7f61cdde0e16c2cd3b7b1b9d07 Mon Sep 17 00:00:00 2001 From: Cyrus Yip <54488650+RealCyGuy@users.noreply.github.com> Date: Tue, 14 Mar 2023 04:21:00 -0700 Subject: [PATCH 618/705] Fix replies in dms not being sent (#3239) * Fix replies not being sent * Use a list instead of a set --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index b23b2449b2..46eb00cb5c 100644 --- a/bot.py +++ b/bot.py @@ -888,7 +888,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: return sent_emoji, blocked_emoji = await self.retrieve_emoji() - if message.type != discord.MessageType.default: + if message.type not in [discord.MessageType.default, discord.MessageType.reply]: return thread = await self.threads.find(recipient=message.author) From 726fb0cedb930cf77f6b31a3dae1e854303c1268 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 14 Mar 2023 04:22:12 -0700 Subject: [PATCH 619/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb6e3f27d..0c1631dec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed - `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) +- Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) # v4.0.2 From b21037cbd794a962569de6240c1d95c13009a64e Mon Sep 17 00:00:00 2001 From: Martin <box152535@gmail.com> Date: Tue, 14 Mar 2023 13:26:18 +0100 Subject: [PATCH 620/705] Reminder Plugin (#3254) * Reminder Plugin Created a reminder plugin * Fix indentations --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- plugins/registry.json | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index 8b6d26bf5f..fe175ea58a 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -35,6 +35,15 @@ "icon_url": "https://i.imgur.com/qtE7AH8.png", "thumbnail_url": "https://i.imgur.com/qtE7AH8.png" }, + "reminder": { + "repository": "martinbndr/kyb3r-modmail-plugins", + "branch": "master", + "description": "Let´s you create reminders.", + "bot_version": "4.0.0", + "title": "Reminder", + "icon_url": "https://raw.githubusercontent.com/martinbndr/kyb3r-modmail-plugins/master/reminder/logo.png", + "thumbnail_url": "https://raw.githubusercontent.com/martinbndr/kyb3r-modmail-plugins/master/reminder/logo.png" + }, "welcomer": { "repository": "fourjr/modmail-plugins", "branch": "v4", @@ -66,43 +75,43 @@ "repository": "fourjr/modmail-plugins", "branch": "v4", "description": "Allows managing server emotes via ?emoji", - "bot_version": "4.0.0", + "bot_version": "4.0.0", "title": "Emote Manager", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, - "gen-log": { + "gen-log": { "repository": "fourjr/modmail-plugins", "branch": "v4", "description": "Outputs a text log of a thread in a specified channel", - "bot_version": "4.0.0", + "bot_version": "4.0.0", "title": "Log Generator", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, - "media-logger": { + "media-logger": { "repository": "fourjr/modmail-plugins", "branch": "v4", "description": "Re-posts detected media from all visible channels into a specified logging channel", - "bot_version": "4.0.0", + "bot_version": "4.0.0", "title": "Media Logger", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, - "report": { + "report": { "repository": "fourjr/modmail-plugins", "branch": "v4", "description": "Specify an emoji to react with on messages. Generates a 'report' in specified logging channel upon react.", - "bot_version": "4.0.0", + "bot_version": "4.0.0", "title": "Report", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" }, - "top-supporters": { + "top-supporters": { "repository": "fourjr/modmail-plugins", "branch": "v4", "description": "Gathers and prints the top supporters of handling threads.", - "bot_version": "4.0.0", + "bot_version": "4.0.0", "title": "Top Supporters", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" From a7a7ce1390e6717bf41d82f8febc35a8a7c4147a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Serba?= <radoslaw@serba.ovh> Date: Thu, 18 May 2023 08:50:02 +0200 Subject: [PATCH 621/705] feat(build): drop root privileges, update .dockerignore --- .dockerignore | 5 +++++ Dockerfile | 3 +++ 2 files changed, 8 insertions(+) diff --git a/.dockerignore b/.dockerignore index 74003e7e30..4b3d7b8274 100644 --- a/.dockerignore +++ b/.dockerignore @@ -138,13 +138,18 @@ temp/ test.py # Other stuff +.dockerignore .env.example .gitignore .github/ app.json CHANGELOG.md +docker-compose.yml +LICENSE +PRIVACY.md Procfile pyproject.toml README.md Pipfile Pipfile.lock +SPONSORS.json diff --git a/Dockerfile b/Dockerfile index 3c88a0e7ca..2729a24826 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,3 +14,6 @@ COPY --from=build /inst /usr/local WORKDIR /modmailbot CMD ["python", "bot.py"] COPY . /modmailbot +RUN adduser --disabled-password --gecos '' app && \ + chown -R app /modmailbot +USER app From eb7995d90652345fd5521603ca25fbddb3e57549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Serba?= <radoslaw@serba.ovh> Date: Thu, 18 May 2023 08:57:55 +0200 Subject: [PATCH 622/705] feat(build): add Dockerfile to .dockerignore --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index 4b3d7b8274..27f3de980f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -144,6 +144,7 @@ test.py .github/ app.json CHANGELOG.md +Dockerfile docker-compose.yml LICENSE PRIVACY.md From fa1a9494e8f51542eb55b7ad986239a9f8c36cf0 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 9 Jul 2023 06:35:01 +0200 Subject: [PATCH 623/705] Remove modmail_guild_id from env examples (#3281) * Update .env.example The removal of `modmail_guild_id` since its causing more confusion to people then it helps them. Features relying on this never were made. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update app.json --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> --- .env.example | 1 - app.json | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 44c91c59c7..14bdf060bf 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,5 @@ TOKEN=MyBotToken LOG_URL=https://logviewername.herokuapp.com/ GUILD_ID=1234567890 -MODMAIL_GUILD_ID=1234567890 OWNERS=Owner1ID,Owner2ID,Owner3ID CONNECTION_URI=mongodb+srv://mongodburi diff --git a/app.json b/app.json index eee99b54bf..decd58695c 100644 --- a/app.json +++ b/app.json @@ -11,10 +11,6 @@ "description": "The id for the server you are hosting this bot for.", "required": true }, - "MODMAIL_GUILD_ID": { - "description": "The ID of the discord server where the threads channels should be created (receiving server). Default to GUILD_ID.", - "required": false - }, "OWNERS": { "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", "required": true @@ -40,4 +36,4 @@ "required": false } } -} \ No newline at end of file +} From 319000b6b4c5e4523cb0de4e2a57c1cbd6f383f8 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 9 Jul 2023 10:34:13 +0000 Subject: [PATCH 624/705] Renamed user from app to modmail - Rename the user from 'app' to 'modmail', and made it a system user instead. - Moved user creation to a higher layer in the Dockerfile. Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --- Dockerfile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2729a24826..96a398fad4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,17 +3,18 @@ FROM python:3.10 as py FROM py as build RUN apt update && apt install -y g++ git + COPY requirements.txt / RUN pip install --prefix=/inst -U -r /requirements.txt FROM py -ENV USING_DOCKER yes COPY --from=build /inst /usr/local +ENV USING_DOCKER yes +RUN useradd --system --no-create-home modmail +USER modmail + WORKDIR /modmailbot CMD ["python", "bot.py"] -COPY . /modmailbot -RUN adduser --disabled-password --gecos '' app && \ - chown -R app /modmailbot -USER app +COPY --chown=modmail:modmail . /modmailbot From 8a68f42ea0c7c3df051d8e9f68b232f6c466abcc Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 9 Jul 2023 10:38:09 +0000 Subject: [PATCH 625/705] Added .git to .dockerignore and unignored some files Removed LICENSE, PRIVACY.md, and SPONSORS.json from .dockerignore. Although they don't affect the functionalities of the bot, we prefer to include them due to their respective purposes. Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --- .dockerignore | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index 27f3de980f..a3de147db4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -140,17 +140,15 @@ test.py # Other stuff .dockerignore .env.example +.git/ .gitignore .github/ app.json CHANGELOG.md Dockerfile docker-compose.yml -LICENSE -PRIVACY.md Procfile pyproject.toml README.md Pipfile Pipfile.lock -SPONSORS.json From fa572eed29fa9551c52ffc0897b8df5f4f33c394 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 13 Jul 2023 20:16:40 -0700 Subject: [PATCH 626/705] Fixed unset registry_plugins_only causing non-registry plugins to fail to install --- cogs/plugins.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index f225d90caa..4fb8341c70 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -302,10 +302,10 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): plugin = Plugin(user, repo, plugin_name, branch) else: - if not self.bot.config.get("registry_plugins_only", False): + if self.bot.config.get("registry_plugins_only"): embed = discord.Embed( - description="This plugin is not in the registry. " - "To install it, you must set `REGISTRY_PLUGINS_ONLY=false` in your .env file or config settings.", + description="This plugin is not in the registry. To install this plugin, " + "you must set `REGISTRY_PLUGINS_ONLY=no` or remove this key in your .env file.", color=self.bot.error_color, ) await ctx.send(embed=embed) From 389dfb68648c1616aafe611c0e2bde5321042070 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 13 Jul 2023 20:19:28 -0700 Subject: [PATCH 627/705] To avoid confusion, config.get() only accepts one pos argument now --- CHANGELOG.md | 3 +++ core/config.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46cf14177c..e191fafb5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Changed - Repo moved to https://github.com/modmail-dev/modmail. +### Internal +- `ConfigManager.get` no longer accepts two positional arguments: the `convert` argument is now keyword-only. + # v4.0.2 ### Breaking diff --git a/core/config.py b/core/config.py index 9a033167b7..9476352573 100644 --- a/core/config.py +++ b/core/config.py @@ -301,7 +301,7 @@ def __getitem__(self, key: str) -> typing.Any: def __delitem__(self, key: str) -> None: return self.remove(key) - def get(self, key: str, convert=True) -> typing.Any: + def get(self, key: str, *, convert: bool = True) -> typing.Any: key = key.lower() if key not in self.all_keys: raise InvalidConfigError(f'Configuration "{key}" is invalid.') From 5ddb4e0444c1195e730924f8b9471e87ac330198 Mon Sep 17 00:00:00 2001 From: Baptiste Girardeau <contact@bgirardeau.me> Date: Sat, 15 Jul 2023 13:36:18 +0200 Subject: [PATCH 628/705] Set smaller size for guild icons urls on embed icons (#3261) * Set size for guild icons on embeds * Update changelog * Format with black * Fixed incorrect function return type --------- Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 3 +-- bot.py | 14 +++++++++----- cogs/modmail.py | 8 ++++---- cogs/utility.py | 9 ++++++--- core/thread.py | 8 +++++--- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adee789203..bf75ef37d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,12 +13,11 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) - Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) -# [UNRELEASED] - ### Added - New .env config option: `REGISTRY_PLUGINS_ONLY`, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) ### Changed +- Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) - Repo moved to https://github.com/modmail-dev/modmail. # v4.0.2 diff --git a/bot.py b/bot.py index 46eb00cb5c..8f2f74e00c 100644 --- a/bot.py +++ b/bot.py @@ -90,12 +90,16 @@ def __init__(self): self.plugin_db = PluginDatabaseClient(self) # Deprecated self.startup() - def get_guild_icon(self, guild: typing.Optional[discord.Guild]) -> str: + def get_guild_icon( + self, guild: typing.Optional[discord.Guild], *, size: typing.Optional[int] = None + ) -> str: if guild is None: guild = self.guild if guild.icon is None: return "https://cdn.discordapp.com/embed/avatars/0.png" - return guild.icon.url + if size is None: + return guild.icon.url + return guild.icon.with_size(size).url def _resolve_snippet(self, name: str) -> typing.Optional[str]: """ @@ -912,7 +916,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: ) embed.set_footer( text=self.config["disabled_new_thread_footer"], - icon_url=self.get_guild_icon(guild=message.guild), + icon_url=self.get_guild_icon(guild=message.guild, size=128), ) logger.info("A new thread was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -928,7 +932,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: ) embed.set_footer( text=self.config["disabled_current_thread_footer"], - icon_url=self.get_guild_icon(guild=message.guild), + icon_url=self.get_guild_icon(guild=message.guild, size=128), ) logger.info("A message was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -1335,7 +1339,7 @@ async def handle_react_to_contact(self, payload): ) embed.set_footer( text=self.config["disabled_new_thread_footer"], - icon_url=self.get_guild_icon(guild=channel.guild), + icon_url=self.get_guild_icon(guild=channel.guild, size=128), ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", diff --git a/cogs/modmail.py b/cogs/modmail.py index d95b74d465..21ee536dab 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -160,7 +160,7 @@ async def snippet(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any snippets at the moment." ) embed.set_footer(text=f'Check "{self.bot.prefix}help snippet add" to add a snippet.') - embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) return await ctx.send(embed=embed) embeds = [] @@ -168,7 +168,7 @@ async def snippet(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): description = format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1031,7 +1031,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.get_guild_icon(guild=ctx.guild) + avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) em.set_footer(text=name, icon_url=avatar_url) for u in users: @@ -1120,7 +1120,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.get_guild_icon(guild=ctx.guild) + avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) em.set_footer(text=name, icon_url=avatar_url) for u in users: diff --git a/cogs/utility.py b/cogs/utility.py index 245060c22b..b3a6d49aeb 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1020,7 +1020,7 @@ async def alias(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any aliases at the moment." ) embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') - embed.set_author(name="Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author(name="Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) return await ctx.send(embed=embed) embeds = [] @@ -1028,7 +1028,9 @@ async def alias(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.aliases)),) * 15)): description = utils.format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Command Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author( + name="Command Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128) + ) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1612,7 +1614,8 @@ async def permissions_get( ) embed = discord.Embed(color=self.bot.main_color, description=description) embed.set_author( - name="Permission Overrides", icon_url=self.bot.get_guild_icon(guild=ctx.guild) + name="Permission Overrides", + icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128), ) embeds.append(embed) diff --git a/core/thread.py b/core/thread.py index 53cdd1d202..0d2fb6408c 100644 --- a/core/thread.py +++ b/core/thread.py @@ -228,7 +228,9 @@ async def send_recipient_genesis_message(): else: footer = self.bot.config["thread_creation_footer"] - embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.modmail_guild)) + embed.set_footer( + text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.modmail_guild, size=128) + ) embed.title = self.bot.config["thread_creation_title"] if creator is None or creator == recipient: @@ -521,7 +523,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, embed.description = message footer = self.bot.config["thread_close_footer"] - embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.guild)) + embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.guild, size=128)) if not silent: for user in self.recipients: @@ -957,7 +959,7 @@ async def send( name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.get_guild_icon(guild=self.bot.guild) + avatar_url = self.bot.get_guild_icon(guild=self.bot.guild, size=128) embed.set_author( name=name, icon_url=avatar_url, From b1f3645a830dd914158315af1daea47f6479b9f5 Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sat, 15 Jul 2023 17:10:51 +0530 Subject: [PATCH 629/705] `logs id` command (#3196) * Update modmail.py * Update clients.py * Formatting * Change log id to log key, added id as an alias * Print the log even if it is closed and fix bug * Update modmail.py * Added a missing period * Updated changelog --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 1 + cogs/modmail.py | 22 ++++++++++++++++++++++ core/clients.py | 10 ++++++++++ 3 files changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf75ef37d3..fad0639ae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added - New .env config option: `REGISTRY_PLUGINS_ONLY`, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) +- `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) ### Changed - Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) diff --git a/cogs/modmail.py b/cogs/modmail.py index 21ee536dab..d72ea78cd5 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1212,6 +1212,28 @@ async def logs_closed_by(self, ctx, *, user: User = None): session = EmbedPaginatorSession(ctx, *embeds) await session.run() + @logs.command(name="key", aliases=["id"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + async def logs_key(self, ctx, key: str): + """ + Get the log link for the specified log key. + """ + icon_url = ctx.author.avatar.url + + logs = await self.bot.api.find_log_entry(key) + + if not logs: + embed = discord.Embed( + color=self.bot.error_color, + description=f"Log entry `{key}` not found.", + ) + return await ctx.send(embed=embed) + + embeds = self.format_log_embeds(logs, avatar_url=icon_url) + + session = EmbedPaginatorSession(ctx, *embeds) + await session.run() + @logs.command(name="delete", aliases=["wipe"]) @checks.has_permissions(PermissionLevel.OWNER) async def logs_delete(self, ctx, key_or_link: str): diff --git a/core/clients.py b/core/clients.py index f504b7051d..61c39fdd4b 100644 --- a/core/clients.py +++ b/core/clients.py @@ -356,6 +356,9 @@ async def validate_database_connection(self): async def get_user_logs(self, user_id: Union[str, int]) -> list: return NotImplemented + async def find_log_entry(self, key: str) -> list: + return NotImplemented + async def get_latest_user_logs(self, user_id: Union[str, int]): return NotImplemented @@ -529,6 +532,13 @@ async def get_user_logs(self, user_id: Union[str, int]) -> list: return await self.logs.find(query, projection).to_list(None) + async def find_log_entry(self, key: str) -> list: + query = {"key": key} + projection = {"messages": {"$slice": 5}} + logger.debug(f"Retrieving log ID {key}.") + + return await self.logs.find(query, projection).to_list(None) + async def get_latest_user_logs(self, user_id: Union[str, int]): query = {"recipient.id": str(user_id), "guild_id": str(self.bot.guild_id), "open": False} projection = {"messages": {"$slice": 5}} From 43fbc312cfe9f1f8d8222f3e80a39ea5394038ea Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sat, 15 Jul 2023 19:45:36 +0800 Subject: [PATCH 630/705] Enable discord.py logger by default. (#3216) * Enable `discord.py` logger by default. * Revert: - Restore import orders - Logging stuff is now completely handled in `core.models.configure_logging` * Update logging configurations * Updated changelog * Fix overflow characters in logs when using `?debug` command. * Update changelog --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 9 +- bot.py | 41 +------- cogs/utility.py | 23 +---- core/config.py | 1 + core/config_help.json | 9 ++ core/models.py | 214 +++++++++++++++++++++++++++++++----------- 6 files changed, 185 insertions(+), 112 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fad0639ae3..d90473d40d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,12 +14,17 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) ### Added -- New .env config option: `REGISTRY_PLUGINS_ONLY`, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) +- `REGISTRY_PLUGINS_ONLY`, environment variable, when set, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) +- `DISCORD_LOG_LEVEL` environment variable to set the log level of discord.py. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) ### Changed -- Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) - Repo moved to https://github.com/modmail-dev/modmail. +- Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) +- Discord.py internal logging is now enabled by default. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) + +### Internal +- Renamed `Bot.log_file_name` to `Bot.log_file_path`. Log files are now created at `temp/logs/modmail.log`. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) # v4.0.2 diff --git a/bot.py b/bot.py index 8f2f74e00c..45530a908f 100644 --- a/bot.py +++ b/bot.py @@ -52,7 +52,6 @@ logger = getLogger(__name__) - temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp") if not os.path.exists(temp_dir): os.mkdir(temp_dir) @@ -84,8 +83,11 @@ def __init__(self): self.threads = ThreadManager(self) - self.log_file_name = os.path.join(temp_dir, f"{self.token.split('.')[0]}.log") - self._configure_logging() + log_dir = os.path.join(temp_dir, "logs") + if not os.path.exists(log_dir): + os.mkdir(log_dir) + self.log_file_path = os.path.join(log_dir, "modmail.log") + configure_logging(self) self.plugin_db = PluginDatabaseClient(self) # Deprecated self.startup() @@ -182,29 +184,6 @@ async def load_extensions(self): logger.exception("Failed to load %s.", cog) logger.line("debug") - def _configure_logging(self): - level_text = self.config["log_level"].upper() - logging_levels = { - "CRITICAL": logging.CRITICAL, - "ERROR": logging.ERROR, - "WARNING": logging.WARNING, - "INFO": logging.INFO, - "DEBUG": logging.DEBUG, - } - logger.line() - - log_level = logging_levels.get(level_text) - if log_level is None: - log_level = self.config.remove("log_level") - logger.warning("Invalid logging level set: %s.", level_text) - logger.warning("Using default logging level: INFO.") - else: - logger.info("Logging level: %s", level_text) - - logger.info("Log file: %s", self.log_file_name) - configure_logging(self.log_file_name, log_level) - logger.debug("Successfully configured logging.") - @property def version(self): return parse_version(__version__) @@ -1801,16 +1780,6 @@ def main(): ) sys.exit(0) - # Set up discord.py internal logging - if os.environ.get("LOG_DISCORD"): - logger.debug(f"Discord logging enabled: {os.environ['LOG_DISCORD'].upper()}") - d_logger = logging.getLogger("discord") - - d_logger.setLevel(os.environ["LOG_DISCORD"].upper()) - handler = logging.FileHandler(filename="discord.log", encoding="utf-8", mode="w") - handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s")) - d_logger.addHandler(handler) - bot = ModmailBot() bot.run() diff --git a/cogs/utility.py b/cogs/utility.py index b3a6d49aeb..47889c2c93 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -401,13 +401,7 @@ async def sponsors(self, ctx): async def debug(self, ctx): """Shows the recent application logs of the bot.""" - log_file_name = self.bot.token.split(".")[0] - - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "r+", - encoding="utf-8", - ) as f: + with open(self.bot.log_file_path, "r+", encoding="utf-8") as f: logs = f.read().strip() if not logs: @@ -433,7 +427,7 @@ async def debug(self, ctx): msg = "```Haskell\n" msg += line if len(msg) + 3 > 2000: - msg = msg[:1993] + "[...]```" + msg = msg[:1992] + "[...]```" messages.append(msg) msg = "```Haskell\n" @@ -455,12 +449,8 @@ async def debug_hastebin(self, ctx): """Posts application-logs to Hastebin.""" haste_url = os.environ.get("HASTE_URL", "https://hastebin.cc") - log_file_name = self.bot.token.split(".")[0] - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "rb+", - ) as f: + with open(self.bot.log_file_path, "rb+") as f: logs = BytesIO(f.read().strip()) try: @@ -491,12 +481,7 @@ async def debug_hastebin(self, ctx): async def debug_clear(self, ctx): """Clears the locally cached logs.""" - log_file_name = self.bot.token.split(".")[0] - - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "w", - ): + with open(self.bot.log_file_path, "w"): pass await ctx.send( embed=discord.Embed(color=self.bot.main_color, description="Cached logs are now cleared.") diff --git a/core/config.py b/core/config.py index 9a033167b7..fa48864aed 100644 --- a/core/config.py +++ b/core/config.py @@ -178,6 +178,7 @@ class ConfigManager: "disable_updates": False, # Logging "log_level": "INFO", + "discord_log_level": "INFO", # data collection "data_collection": True, } diff --git a/core/config_help.json b/core/config_help.json index e7ebb9590d..f5b08d64ad 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -1129,6 +1129,15 @@ "This configuration can only to be set through `.env` file or environment (config) variables." ] }, + "discord_log_level": { + "default": "INFO", + "description": "The `discord.py` library logging level for logging to stdout.", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] + }, "enable_plugins": { "default": "Yes", "description": "Whether plugins should be enabled and loaded into Modmail.", diff --git a/core/models.py b/core/models.py index 2eab1ceebb..29f6af71bb 100644 --- a/core/models.py +++ b/core/models.py @@ -1,16 +1,19 @@ import logging +import os import re import sys -import os +import _string + from difflib import get_close_matches from enum import IntEnum +from logging import FileHandler, StreamHandler, Handler from logging.handlers import RotatingFileHandler from string import Formatter +from typing import Optional import discord from discord.ext import commands -import _string try: from colorama import Fore, Style @@ -23,29 +26,6 @@ Fore = Style = type("Dummy", (object,), {"__getattr__": lambda self, item: ""})() -class PermissionLevel(IntEnum): - OWNER = 5 - ADMINISTRATOR = 4 - ADMIN = 4 - MODERATOR = 3 - MOD = 3 - SUPPORTER = 2 - RESPONDER = 2 - REGULAR = 1 - INVALID = -1 - - -class InvalidConfigError(commands.BadArgument): - def __init__(self, msg, *args): - super().__init__(msg, *args) - self.msg = msg - - @property - def embed(self): - # Single reference of Color.red() - return discord.Embed(title="Error", description=self.msg, color=discord.Color.red()) - - class ModmailLogger(logging.Logger): @staticmethod def _debug_(*msgs): @@ -94,18 +74,92 @@ def line(self, level="info"): ) -logging.setLoggerClass(ModmailLogger) -log_level = logging.INFO -loggers = set() +class FileFormatter(logging.Formatter): + ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]") + + def format(self, record): + record.msg = self.ansi_escape.sub("", record.msg) + return super().format(record) + -ch = logging.StreamHandler(stream=sys.stdout) -ch.setLevel(log_level) -formatter = logging.Formatter( +log_stream_formatter = logging.Formatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%m/%d/%y %H:%M:%S" ) -ch.setFormatter(formatter) +log_file_formatter = FileFormatter( + "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", +) -ch_debug = None + +def create_log_handler( + filename: Optional[str] = None, + *, + rotating: bool = False, + level: int = logging.DEBUG, + mode: str = "a+", + encoding: str = "utf-8", + maxBytes: int = 28000000, + backupCount: int = 1, + **kwargs, +) -> Handler: + """ + Creates a pre-configured log handler. This function is made for consistency's sake with + pre-defined default values for parameters and formatters to pass to handler class. + Additional keyword arguments also can be specified, just in case. + + Plugin developers should not use this and use `models.getLogger` instead. + + Parameters + ---------- + filename : Optional[Path] + Specifies that a `FileHandler` or `RotatingFileHandler` be created, using the specified filename, + rather than a `StreamHandler`. Defaults to `None`. + rotating : bool + Whether the file handler should be the `RotatingFileHandler`. Defaults to `False`. Note, this + argument only compatible if the `filename` is specified, otherwise `ValueError` will be raised. + level : int + The root logger level for the handler. Defaults to `logging.DEBUG`. + mode : str + If filename is specified, open the file in this mode. Defaults to 'a+'. + encoding : str + If this keyword argument is specified along with filename, its value is used when the `FileHandler` is created, + and thus used when opening the output file. Defaults to 'utf-8'. + maxBytes : int + The max file size before the rollover occurs. Defaults to 28000000 (28MB). Rollover occurs whenever the current + log file is nearly `maxBytes` in length; but if either of `maxBytes` or `backupCount` is zero, + rollover never occurs, so you generally want to set `backupCount` to at least 1. + backupCount : int + Max number of backup files. Defaults to 1. If this is set to zero, rollover will never occur. + + Returns + ------- + `StreamHandler` when `filename` is `None`, otherwise `FileHandler` or `RotatingFileHandler` + depending on the `rotating` value. + """ + if filename is None and rotating: + raise ValueError("`filename` must be set to instantiate a `RotatingFileHandler`.") + + if filename is None: + handler = StreamHandler(stream=sys.stdout, **kwargs) + handler.setFormatter(log_stream_formatter) + elif not rotating: + handler = FileHandler(filename, mode=mode, encoding=encoding, **kwargs) + handler.setFormatter(log_file_formatter) + else: + handler = RotatingFileHandler( + filename, mode=mode, encoding=encoding, maxBytes=maxBytes, backupCount=backupCount, **kwargs + ) + handler.setFormatter(log_file_formatter) + + handler.setLevel(level) + return handler + + +logging.setLoggerClass(ModmailLogger) +log_level = logging.INFO +loggers = set() +ch = create_log_handler(level=log_level) +ch_debug: Optional[RotatingFileHandler] = None def getLogger(name=None) -> ModmailLogger: @@ -118,33 +172,71 @@ def getLogger(name=None) -> ModmailLogger: return logger -class FileFormatter(logging.Formatter): - ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]") - - def format(self, record): - record.msg = self.ansi_escape.sub("", record.msg) - return super().format(record) - - -def configure_logging(name, level=None): +def configure_logging(bot) -> None: global ch_debug, log_level - ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=48000, backupCount=1, encoding="utf-8") - formatter_debug = FileFormatter( - "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", - datefmt="%Y-%m-%d %H:%M:%S", - ) - ch_debug.setFormatter(formatter_debug) - ch_debug.setLevel(logging.DEBUG) + logger = getLogger(__name__) + level_text = bot.config["log_level"].upper() + logging_levels = { + "CRITICAL": logging.CRITICAL, + "ERROR": logging.ERROR, + "WARNING": logging.WARNING, + "INFO": logging.INFO, + "DEBUG": logging.DEBUG, + } + logger.line() + + level = logging_levels.get(level_text) + if level is None: + level = bot.config.remove("log_level") + logger.warning("Invalid logging level set: %s.", level_text) + logger.warning("Using default logging level: %s.", level) + level = logging_levels[level] + else: + logger.info("Logging level: %s", level_text) + log_level = level + + logger.info("Log file: %s", bot.log_file_path) + ch_debug = create_log_handler(bot.log_file_path, rotating=True) + ch.setLevel(log_level) - if level is not None: - log_level = level + for log in loggers: + log.setLevel(log_level) + log.addHandler(ch_debug) + + # Set up discord.py logging + d_level_text = bot.config["discord_log_level"].upper() + d_level = logging_levels.get(d_level_text) + if d_level is None: + d_level = bot.config.remove("discord_log_level") + logger.warning("Invalid discord logging level set: %s.", d_level_text) + logger.warning("Using default discord logging level: %s.", d_level) + d_level = logging_levels[d_level] + d_logger = logging.getLogger("discord") + d_logger.setLevel(d_level) + + non_verbose_log_level = max(d_level, logging.INFO) + stream_handler = create_log_handler(level=non_verbose_log_level) + if non_verbose_log_level != d_level: + logger.info("Discord logging level (stdout): %s.", logging.getLevelName(non_verbose_log_level)) + logger.info("Discord logging level (logfile): %s.", logging.getLevelName(d_level)) + else: + logger.info("Discord logging level: %s.", logging.getLevelName(d_level)) + d_logger.addHandler(stream_handler) + d_logger.addHandler(ch_debug) + + logger.debug("Successfully configured logging.") - ch.setLevel(log_level) - for logger in loggers: - logger.setLevel(log_level) - logger.addHandler(ch_debug) +class InvalidConfigError(commands.BadArgument): + def __init__(self, msg, *args): + super().__init__(msg, *args) + self.msg = msg + + @property + def embed(self): + # Single reference of Color.red() + return discord.Embed(title="Error", description=self.msg, color=discord.Color.red()) class _Default: @@ -271,6 +363,18 @@ async def ack(self): return +class PermissionLevel(IntEnum): + OWNER = 5 + ADMINISTRATOR = 4 + ADMIN = 4 + MODERATOR = 3 + MOD = 3 + SUPPORTER = 2 + RESPONDER = 2 + REGULAR = 1 + INVALID = -1 + + class DMDisabled(IntEnum): NONE = 0 NEW_THREADS = 1 From a784f8299d023428e9a9d5a6fde0e06aab4d4feb Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sat, 15 Jul 2023 19:48:33 +0800 Subject: [PATCH 631/705] Cleanup after unloading extension. (#3226) * Cleanup after unloading extension, resolve #3223. * Remove leftover modules loaded from `plugins` path when purging. --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 1 + cogs/plugins.py | 37 ++++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d90473d40d..68502a05a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) - Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) +- Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226)) ### Added - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) diff --git a/cogs/plugins.py b/cogs/plugins.py index f225d90caa..b4d7ca415c 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -264,6 +264,17 @@ async def load_plugin(self, plugin): logger.error("Plugin load failure: %s", plugin.ext_string, exc_info=True) raise InvalidPluginError("Cannot load extension, plugin invalid.") from exc + async def unload_plugin(self, plugin: Plugin) -> None: + try: + await self.bot.unload_extension(plugin.ext_string) + except commands.ExtensionError as exc: + raise exc + + ext_parent = ".".join(plugin.ext_string.split(".")[:-1]) + for module in list(sys.modules.keys()): + if module == ext_parent or module.startswith(ext_parent + "."): + del sys.modules[module] + async def parse_user_input(self, ctx, plugin_name, check_version=False): if not self.bot.config["enable_plugins"]: @@ -378,7 +389,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): logger.warning("Unable to download plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", + description=f"Failed to download plugin, check logs for error.\n{type(e).__name__}: {e}", color=self.bot.error_color, ) @@ -397,7 +408,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): logger.warning("Unable to load plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", + description=f"Failed to load plugin, check logs for error.\n{type(e).__name__}: {e}", color=self.bot.error_color, ) @@ -438,7 +449,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): if self.bot.config.get("enable_plugins"): try: - await self.bot.unload_extension(plugin.ext_string) + await self.unload_plugin(plugin) self.loaded_plugins.remove(plugin) except (commands.ExtensionNotLoaded, KeyError): logger.warning("Plugin was never loaded.") @@ -480,9 +491,10 @@ async def update_plugin(self, ctx, plugin_name): await self.download_plugin(plugin, force=True) if self.bot.config.get("enable_plugins"): try: - await self.bot.unload_extension(plugin.ext_string) + await self.unload_plugin(plugin) except commands.ExtensionError: logger.warning("Plugin unload fail.", exc_info=True) + try: await self.load_plugin(plugin) except Exception: @@ -529,17 +541,20 @@ async def plugins_reset(self, ctx): for ext in list(self.bot.extensions): if not ext.startswith("plugins."): continue + logger.error("Unloading plugin: %s.", ext) try: - logger.error("Unloading plugin: %s.", ext) - await self.bot.unload_extension(ext) - except Exception: - logger.error("Failed to unload plugin: %s.", ext) - else: - if not self.loaded_plugins: - continue plugin = next((p for p in self.loaded_plugins if p.ext_string == ext), None) if plugin: + await self.unload_plugin(plugin) self.loaded_plugins.remove(plugin) + else: + await self.bot.unload_extension(ext) + except Exception: + logger.error("Failed to unload plugin: %s.", ext) + + for module in list(sys.modules.keys()): + if module.startswith("plugins."): + del sys.modules[module] self.bot.config["plugins"].clear() await self.bot.config.update() From cc21725f2ff31a0566c7efe691a6bf87e4174bbd Mon Sep 17 00:00:00 2001 From: Cordila <49218334+Cordila@users.noreply.github.com> Date: Sat, 15 Jul 2023 17:23:46 +0530 Subject: [PATCH 632/705] Fix typo #3210 (#3233) * Fix typo * Rephrase the silently close messsage * Update changelog --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 1 + cogs/modmail.py | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68502a05a0..e69f0f1849 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) - Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) - Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226)) +- Fixed a syntactic error in the close message when a thread is closed after a certain duration. ([PR #3233](https://github.com/modmail-dev/Modmail/pull/3233)) ### Added - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) diff --git a/cogs/modmail.py b/cogs/modmail.py index d72ea78cd5..33086116c5 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -444,11 +444,9 @@ async def move(self, ctx, *, arguments): async def send_scheduled_close_message(self, ctx, after, silent=False): human_delta = human_timedelta(after.dt) - silent = "*silently* " if silent else "" - embed = discord.Embed( title="Scheduled close", - description=f"This thread will close {silent}{human_delta}.", + description=f"This thread will{' silently' if silent else ''} close in {human_delta}.", color=self.bot.error_color, ) From 1adbacfad21f12691d9b170d1c52ad61fad2ec9f Mon Sep 17 00:00:00 2001 From: Cyrus Yip <cyruscmyip1@gmail.com> Date: Sat, 15 Jul 2023 04:56:33 -0700 Subject: [PATCH 633/705] Strip whitespace in help command titles (#3271) * strip help command title * Update changelog --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 1 + cogs/utility.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69f0f1849..3feb557449 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) - Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226)) - Fixed a syntactic error in the close message when a thread is closed after a certain duration. ([PR #3233](https://github.com/modmail-dev/Modmail/pull/3233)) +- Removed an extra space in the help command title when the command has no parameters. ([PR #3271](https://github.com/modmail-dev/Modmail/pull/3271)) ### Added - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) diff --git a/cogs/utility.py b/cogs/utility.py index 47889c2c93..5386a86770 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -142,7 +142,7 @@ async def _get_help_embed(self, topic): perm_level = "NONE" embed = discord.Embed( - title=f"`{self.get_command_signature(topic)}`", + title=f"`{self.get_command_signature(topic).strip()}`", color=self.context.bot.main_color, description=self.process_help_msg(topic.help), ) From 77fbb6937b09d8994fbafea74dd34535ba767ed0 Mon Sep 17 00:00:00 2001 From: Martin <box152535@gmail.com> Date: Sat, 15 Jul 2023 13:59:26 +0200 Subject: [PATCH 634/705] confirm_thread_creation Buttons instead of reactions (#3273) * Reminder Plugin Created a reminder plugin * Fix indentations * confirm_thread_creation Buttons instead of reactions * Changelog+Small fixes * Updated the react to confirm message, and removed changelog entry * Code linting with black * Update changelog --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 1 + core/config.py | 2 +- core/config_help.json | 4 ++-- core/thread.py | 51 +++++++++++++++---------------------------- core/utils.py | 29 ++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3feb557449..35cabb1e58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Repo moved to https://github.com/modmail-dev/modmail. - Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) - Discord.py internal logging is now enabled by default. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) +- The confirm-thread-creation dialog now uses buttons instead of reactions. ([PR #3273](https://github.com/modmail-dev/Modmail/pull/3273)) ### Internal - Renamed `Bot.log_file_name` to `Bot.log_file_path`. Log files are now created at `temp/logs/modmail.log`. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) diff --git a/core/config.py b/core/config.py index fa48864aed..9e4cf949de 100644 --- a/core/config.py +++ b/core/config.py @@ -123,7 +123,7 @@ class ConfigManager: # confirm thread creation "confirm_thread_creation": False, "confirm_thread_creation_title": "Confirm thread creation", - "confirm_thread_response": "React to confirm thread creation which will directly contact the moderators", + "confirm_thread_response": "Click the button to confirm thread creation which will directly contact the moderators.", "confirm_thread_creation_accept": "\N{WHITE HEAVY CHECK MARK}", "confirm_thread_creation_deny": "\N{NO ENTRY SIGN}", # regex diff --git a/core/config_help.json b/core/config_help.json index f5b08d64ad..4fafd7a3a6 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -1014,10 +1014,10 @@ ] }, "confirm_thread_response": { - "default": "React to confirm thread creation which will directly contact the moderators", + "default": "Click the button to confirm thread creation which will directly contact the moderators.", "description": "Description for the embed message sent to users to confirm a thread creation", "examples":[ - "`{prefix}config set confirm_thread_response React to confirm`" + "`{prefix}config set confirm_thread_response Click to confirm`" ], "notes": [ "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny`" diff --git a/core/thread.py b/core/thread.py index 0d2fb6408c..46be932c1a 100644 --- a/core/thread.py +++ b/core/thread.py @@ -29,6 +29,9 @@ get_top_role, create_thread_channel, get_joint_id, + AcceptButton, + DenyButton, + ConfirmThreadCreationView, ) logger = getLogger(__name__) @@ -1418,30 +1421,19 @@ async def create( destination = recipient else: destination = message.channel + view = ConfirmThreadCreationView() + view.add_item(AcceptButton(self.bot.config["confirm_thread_creation_accept"])) + view.add_item(DenyButton(self.bot.config["confirm_thread_creation_deny"])) confirm = await destination.send( embed=discord.Embed( title=self.bot.config["confirm_thread_creation_title"], description=self.bot.config["confirm_thread_response"], color=self.bot.main_color, - ) + ), + view=view, ) - accept_emoji = self.bot.config["confirm_thread_creation_accept"] - deny_emoji = self.bot.config["confirm_thread_creation_deny"] - emojis = [accept_emoji, deny_emoji] - for emoji in emojis: - await confirm.add_reaction(emoji) - await asyncio.sleep(0.2) - - try: - r, _ = await self.bot.wait_for( - "reaction_add", - check=lambda r, u: u.id == recipient.id - and r.message.id == confirm.id - and r.message.channel.id == confirm.channel.id - and str(r.emoji) in (accept_emoji, deny_emoji), - timeout=20, - ) - except asyncio.TimeoutError: + await view.wait() + if view.value is None: thread.cancelled = True self.bot.loop.create_task( destination.send( @@ -1452,23 +1444,16 @@ async def create( ) ) ) - else: - if str(r.emoji) == deny_emoji: - thread.cancelled = True - self.bot.loop.create_task( - destination.send( - embed=discord.Embed( - title=self.bot.config["thread_cancelled"], color=self.bot.error_color - ) + await confirm.edit(view=None) + if view.value is False: + thread.cancelled = True + self.bot.loop.create_task( + destination.send( + embed=discord.Embed( + title=self.bot.config["thread_cancelled"], color=self.bot.error_color ) ) - - async def remove_reactions(): - for emoji in emojis: - await confirm.remove_reaction(emoji, self.bot.user) - await asyncio.sleep(0.2) - - self.bot.loop.create_task(remove_reactions()) + ) if thread.cancelled: del self.cache[recipient.id] return thread diff --git a/core/utils.py b/core/utils.py index d8046ade5f..0e9f090d12 100644 --- a/core/utils.py +++ b/core/utils.py @@ -39,6 +39,9 @@ "get_top_role", "get_joint_id", "extract_block_timestamp", + "AcceptButton", + "DenyButton", + "ConfirmThreadCreationView", ] @@ -559,3 +562,29 @@ def extract_block_timestamp(reason, id_): raise return end_time, after + + +class AcceptButton(discord.ui.Button): + def __init__(self, emoji): + super().__init__(style=discord.ButtonStyle.gray, emoji=emoji) + + async def callback(self, interaction: discord.Interaction): + self.view.value = True + await interaction.response.edit_message(view=None) + self.view.stop() + + +class DenyButton(discord.ui.Button): + def __init__(self, emoji): + super().__init__(style=discord.ButtonStyle.gray, emoji=emoji) + + async def callback(self, interaction: discord.Interaction): + self.view.value = False + await interaction.response.edit_message(view=None) + self.view.stop() + + +class ConfirmThreadCreationView(discord.ui.View): + def __init__(self): + super().__init__(timeout=20) + self.value = None From 48bf245c24833c36a986ab670b50b1d999dc05cb Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Sat, 15 Jul 2023 14:01:48 +0200 Subject: [PATCH 635/705] Fixed the description of some config help descriptions having copy-paste errors (#3277) * Added the option for secure_plugins_only * Change config name * Forgot to update app.json * Forgot a period. Thanks taku :( * Fixed some copy-paste errors in descriptions * Update changelog --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 1 + core/config_help.json | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35cabb1e58..2f27da4d1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226)) - Fixed a syntactic error in the close message when a thread is closed after a certain duration. ([PR #3233](https://github.com/modmail-dev/Modmail/pull/3233)) - Removed an extra space in the help command title when the command has no parameters. ([PR #3271](https://github.com/modmail-dev/Modmail/pull/3271)) +- Corrected some incorrect config help descriptions. ([PR #3277](https://github.com/modmail-dev/Modmail/pull/3277)) ### Added - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) diff --git a/core/config_help.json b/core/config_help.json index 4fafd7a3a6..f909d27821 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -131,7 +131,7 @@ "`{prefix}config set use_nickname_channel_name no`" ], "notes": [ - "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", + "This config is NOT suitable for servers in Server Discovery to comply with channel name restrictions.", "This cannot be applied with `use_timestamp_channel_name`, `use_random_channel_name` or `use_user_id_channel_name`.", "See also: `use_timestamp_channel_name`, `use_user_id_channel_name`, `use_random_channel_name`." ] @@ -864,7 +864,7 @@ "default": "\"{{moderator.name}} has added you to a Modmail thread.\"", "description": "This is the message embed content sent to the recipient that is just added to a thread.", "examples": [ - "`{prefix}config set private_added_to_group_description Any message sent here will be sent to all otherthread recipients.`" + "`{prefix}config set private_added_to_group_response Any message sent here will be sent to all other thread recipients.`" ], "notes": [ "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", @@ -936,7 +936,7 @@ "default": "\"{{moderator.name}} has removed you from the Modmail thread.\"", "description": "This is the message embed content sent to the recipient that is just removed from a thread.", "examples": [ - "`{prefix}config set private_removed_from_group_description Bye`" + "`{prefix}config set private_removed_from_group_response Bye`" ], "notes": [ "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", From d4ec13ed058dddd6c4a84c7bf47f4c516618f526 Mon Sep 17 00:00:00 2001 From: Martin <box152535@gmail.com> Date: Sat, 15 Jul 2023 14:04:53 +0200 Subject: [PATCH 636/705] [Fix] disable new command not updating db config (#3278) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Fix] disable new command not updating ``disable new`` command didn´t update db config if modmail was already disabled for all threads. * Update changelog --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 1 + cogs/modmail.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f27da4d1c..c13d8a757d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) - Discord.py internal logging is now enabled by default. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - The confirm-thread-creation dialog now uses buttons instead of reactions. ([PR #3273](https://github.com/modmail-dev/Modmail/pull/3273)) +- `?disable all` no longer overrides `?disable new`. ([PR #3278](https://github.com/modmail-dev/Modmail/pull/3278)) ### Internal - Renamed `Bot.log_file_name` to `Bot.log_file_path`. Log files are now created at `temp/logs/modmail.log`. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) diff --git a/cogs/modmail.py b/cogs/modmail.py index 33086116c5..445015e4de 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -2152,7 +2152,7 @@ async def disable_new(self, ctx): description="Modmail will not create any new threads.", color=self.bot.main_color, ) - if self.bot.config["dm_disabled"] < DMDisabled.NEW_THREADS: + if self.bot.config["dm_disabled"] != DMDisabled.NEW_THREADS: self.bot.config["dm_disabled"] = DMDisabled.NEW_THREADS await self.bot.config.update() From f405aedf4af009ffa9f5502aa13c99d86e48e506 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 15 Jul 2023 05:11:21 -0700 Subject: [PATCH 637/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c13d8a757d..158eb63a91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Discord.py internal logging is now enabled by default. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - The confirm-thread-creation dialog now uses buttons instead of reactions. ([PR #3273](https://github.com/modmail-dev/Modmail/pull/3273)) - `?disable all` no longer overrides `?disable new`. ([PR #3278](https://github.com/modmail-dev/Modmail/pull/3278)) +- Dropped root privileges for Modmail running under Docker. ([PR #3284](https://github.com/modmail-dev/Modmail/pull/3284)) ### Internal - Renamed `Bot.log_file_name` to `Bot.log_file_path`. Log files are now created at `temp/logs/modmail.log`. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) From d891ad18ca0983f344a8c7da083c559e9bd96112 Mon Sep 17 00:00:00 2001 From: Stephen <48072084+StephenDaDev@users.noreply.github.com> Date: Sat, 15 Jul 2023 08:12:30 -0400 Subject: [PATCH 638/705] Remove Heroku Reference from Debug Command (#3292) * Very few users are still using Heroku for hosting, so this comment could cause confusion. * Fix mistake --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- cogs/utility.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 5386a86770..d0ecbeda22 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -410,7 +410,7 @@ async def debug(self, ctx): title="Debug Logs:", description="You don't have any logs at the moment.", ) - embed.set_footer(text="Go to Heroku to see your logs.") + embed.set_footer(text="Go to your console to see your logs.") return await ctx.send(embed=embed) messages = [] @@ -472,7 +472,7 @@ async def debug_hastebin(self, ctx): color=self.bot.main_color, description="Something's wrong. We're unable to upload your logs to hastebin.", ) - embed.set_footer(text="Go to Heroku to see your logs.") + embed.set_footer(text="Go to your console to see your logs.") await ctx.send(embed=embed) @debug.command(name="clear", aliases=["wipe"]) From 5170035df47e5f5571d94f1cb3f2175f1e70db62 Mon Sep 17 00:00:00 2001 From: Martin <box152535@gmail.com> Date: Sat, 15 Jul 2023 14:22:21 +0200 Subject: [PATCH 639/705] Added Autoreact plugin (#3285) * Added Autoreact plugin * Update changelog * black format (from a different pr's mistake) --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- CHANGELOG.md | 3 +-- cogs/plugins.py | 2 +- plugins/registry.json | 9 +++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75553acc79..9830415b10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) - `REGISTRY_PLUGINS_ONLY`, environment variable, when set, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) - `DISCORD_LOG_LEVEL` environment variable to set the log level of discord.py. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) +- New registry plugin: [`autoreact`](https://github.com/martinbndr/kyb3r-modmail-plugins/tree/master/autoreact). ### Changed - Repo moved to https://github.com/modmail-dev/modmail. @@ -32,8 +33,6 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Internal - Renamed `Bot.log_file_name` to `Bot.log_file_path`. Log files are now created at `temp/logs/modmail.log`. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - -### Internal - `ConfigManager.get` no longer accepts two positional arguments: the `convert` argument is now keyword-only. # v4.0.2 diff --git a/cogs/plugins.py b/cogs/plugins.py index 6922a1c79c..6bae7738c6 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -316,7 +316,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if self.bot.config.get("registry_plugins_only"): embed = discord.Embed( description="This plugin is not in the registry. To install this plugin, " - "you must set `REGISTRY_PLUGINS_ONLY=no` or remove this key in your .env file.", + "you must set `REGISTRY_PLUGINS_ONLY=no` or remove this key in your .env file.", color=self.bot.error_color, ) await ctx.send(embed=embed) diff --git a/plugins/registry.json b/plugins/registry.json index fe175ea58a..be138a30b2 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -17,6 +17,15 @@ "icon_url": "https://github.com/Jerrie-Aries.png", "thumbnail_url": "https://raw.githubusercontent.com/Jerrie-Aries/modmail-plugins/master/.static/announcement.jpg" }, + "autoreact": { + "repository": "martinbndr/kyb3r-modmail-plugins", + "branch": "master", + "description": "Automatically reacts with emojis in certain channels.", + "bot_version": "4.0.0", + "title": "Autoreact", + "icon_url": "https://raw.githubusercontent.com/martinbndr/kyb3r-modmail-plugins/master/autoreact/logo.png", + "thumbnail_url": "https://raw.githubusercontent.com/martinbndr/kyb3r-modmail-plugins/master/autoreact/logo.png" + }, "giveaway": { "repository": "Jerrie-Aries/modmail-plugins", "branch": "master", From 2b667102e95354fbdf07f88c3c88e95d802be0b7 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:55:37 -0700 Subject: [PATCH 640/705] Fix #3291: Resolve code scanning alert for URL sanitization --- core/utils.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/core/utils.py b/core/utils.py index 0e9f090d12..60a1d654fd 100644 --- a/core/utils.py +++ b/core/utils.py @@ -147,13 +147,17 @@ def is_image_url(url: str, **kwargs) -> str: bool Whether the URL is a valid image URL. """ - if url.startswith("https://gyazo.com") or url.startswith("http://gyazo.com"): - # gyazo support - url = re.sub( - r"(http[s]?:\/\/)((?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)", - r"\1i.\2.png", - url, - ) + try: + result = parse.urlparse(url) + if result.netloc == 'gyazo.com' and result.scheme in ['http', 'https']: + # gyazo support + url = re.sub( + r"(https?://)((?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|%[0-9a-fA-F][0-9a-fA-F])+)", + r"\1i.\2.png", + url, + ) + except ValueError: + pass return parse_image_url(url, **kwargs) From f0c469ed1905ade9492f31dcd80e344de04f023b Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:24:02 -0700 Subject: [PATCH 641/705] Implement #3187: Enhance bot join/leave logs across servers --- bot.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index 45530a908f..5c8edd0843 100644 --- a/bot.py +++ b/bot.py @@ -48,7 +48,7 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint +from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint, human_join logger = getLogger(__name__) @@ -1380,28 +1380,44 @@ async def on_guild_channel_delete(self, channel): await thread.close(closer=mod, silent=True, delete_channel=False) async def on_member_remove(self, member): - if member.guild != self.guild: - return thread = await self.threads.find(recipient=member) if thread: - if self.config["close_on_leave"]: + if member.guild == self.guild and self.config["close_on_leave"]: await thread.close( closer=member.guild.me, message=self.config["close_on_leave_reason"], silent=True, ) else: - embed = discord.Embed( - description=self.config["close_on_leave_reason"], color=self.error_color - ) + if len(self.guilds) > 1: + guild_left = member.guild + remaining_guilds = member.mutual_guilds + + if remaining_guilds: + remaining_guild_names = [guild.name for guild in remaining_guilds] + leave_message = ( + f"The recipient has left {guild_left}. " + f"They are still in {human_join(remaining_guild_names, final='and')}." + ) + else: + leave_message = ( + f"The recipient has left {guild_left}. We no longer share any mutual servers." + ) + else: + leave_message = "The recipient has left the server." + + embed = discord.Embed(description=leave_message, color=self.error_color) await thread.channel.send(embed=embed) async def on_member_join(self, member): - if member.guild != self.guild: - return thread = await self.threads.find(recipient=member) if thread: - embed = discord.Embed(description="The recipient has joined the server.", color=self.mod_color) + if len(self.guilds) > 1: + guild_joined = member.guild + join_message = f"The recipient has joined {guild_joined}." + else: + join_message = "The recipient has joined the server." + embed = discord.Embed(description=join_message, color=self.mod_color) await thread.channel.send(embed=embed) async def on_message_delete(self, message): From 7508d524a5e3c6d2df3eabad5ec7d551a5edd4e6 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 10 Oct 2023 17:23:32 -0700 Subject: [PATCH 642/705] Update readme with new documentation links, python version, and removed obsolete installion steps --- README.md | 119 +++++++++++++----------------------------------------- 1 file changed, 28 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 062bf6d8a4..319a9742cf 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ </a> <a href="https://www.python.org/downloads/"> - <img src="https://img.shields.io/badge/Made%20With-Python%203.8-blue.svg?style=for-the-badge&logo=Python" alt="Made with Python 3.8"> + <img src="https://img.shields.io/badge/Made%20With-Python%203.10-blue.svg?style=for-the-badge&logo=Python" alt="Made with Python 3.10"> </a> <a href="https://github.com/ambv/black"> @@ -50,11 +50,13 @@ Modmail is similar to Reddit's Modmail, both in functionality and purpose. It se This bot is free for everyone and always will be. If you like this project and would like to show your appreciation, you can support us on **[Patreon](https://www.patreon.com/kyber)**, cool benefits included! +For up-to-date setup instructions, please visit our [**documentation**](https://docs.modmail.dev/installation) page. + ## How does it work? When a member sends a direct message to the bot, Modmail will create a channel or "thread" into a designated category. All further DM messages will automatically relay to that channel; any available staff can respond within the channel. -Our Logviewer will save the threads so you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.modmail.dev/example). +Our Logviewer will save the threads so you can view previous threads through their corresponding log link. ~~Here is an [**example**](https://logs.modmail.dev/example)~~ (demo not available at the moment). ## Features @@ -67,7 +69,7 @@ Our Logviewer will save the threads so you can view previous threads through the * Minimum length for members to be in the guild before allowed to contact Modmail (`guild_age`). * **Advanced Logging Functionality:** - * When you close a thread, Modmail will generate a [log link](https://logs.modmail.dev/example) and post it to your log channel. + * When you close a thread, Modmail will generate a log link and post it to your log channel. * Native Discord dark-mode feel. * Markdown/formatting support. * Login via Discord to protect your logs ([premium Patreon feature](https://patreon.com/kyber)). @@ -84,88 +86,34 @@ This list is ever-growing thanks to active development and our exceptional contr ## Installation -Q: Where can I find the Modmail bot invite link? +There are a number of options for hosting your very own dedicated Modmail bot. + +Visit our [**documentation**](https://docs.modmail.dev/installation) page for detailed guidance on how to deploy your Modmail bot. -A: Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following one of the methods listed below (roughly takes 15 minutes of your time). +### Patreon Hosting -There are a few options for hosting your very own dedicated Modmail bot. +If you don't want the trouble of renting and configuring your server to host Modmail, we got a solution for you! We offer hosting and maintenance of your own, private Modmail bot (including a Logviewer) through [**Patreon**](https://patreon.com/kyber). -1. Patreon hosting -2. Local hosting (VPS, Dedicated Server, RPi, your computer, etc.) -3. PaaS (we provide a guide for Heroku) +## FAQ -### Patreon Hosting +**Q: Where can I find the Modmail bot invite link?** + +**A:** Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following our [**documentation**](https://docs.modmail.dev/installation) steps or subscribe to [**Patreon**](https://patreon.com/kyber). + +**Q: Where can I find out more info about Modmail?** + +**A:** You can find more info about Modmail on our [**documentation**](https://docs.modmail.dev) page. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/cnUpwrnpYb) for help and support. + +## Plugins + +Modmail supports the use of third-party plugins to extend or add functionalities to the bot. +Plugins allow niche features as well as anything else outside of the scope of the core functionality of Modmail. + +You can find a list of third-party plugins using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/modmail-dev/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. -If you don't want the trouble of renting and configuring your server to host Modmail, we got a solution for you! We offer hosting and maintenance of your own, private Modmail bot (including a Logviewer) through [**Patreon**](https://patreon.com/kyber). Join our [Modmail Discord Server](https://discord.gg/cnUpwrnpYb) for more info! - -### Local hosting (General Guide) - -Modmail can be hosted on any modern hardware, including your PC. For stability and reliability, we suggest purchasing a cloud server (VPS) for under $10/mo. If you need recommendations on choosing a VPS, join our [Discord server](https://discord.gg/cnUpwrnpYb), and we'll send you a list of non-affiliated hosting providers. Alternatively, we can host Modmail for you when you're subscribed to our [Patreon](https://patreon.com/kyber). - -This guide assumes you've downloaded [`Python 3.10`](https://www.python.org/downloads/release/python-376/) and added python and pip to PATH. - -1. Clone this repo - ```console - $ git clone https://github.com/modmail-dev/modmail - $ cd modmail - ``` -2. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/modmail-dev/modmail/wiki/Installation#2-discord-bot-account)) -3. Create a free MongoDB database ([guide](https://github.com/modmail-dev/modmail/wiki/Installation-(cont.)#3-create-a-database), follow it carefully!) -4. Rename the file `.env.example` to `.env` and fill it with appropriate values - - If you can't find `.env.example` because it's hidden, create a new text file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/modmail-dev/modmail/master/.env.example) and replace the placeholders with their values - - If you're on Windows and cannot save the file as `.env`, save it as `.env.` instead (this only applies to Windows!) - - If you do not have a Logviewer yet, leave the `LOG_URL` field as-is -5. Update pip, install pipenv, and install dependencies using pipenv - ```console - $ pip install -U pip - $ pip install pipenv - $ pipenv install - ``` -6. Start the bot - ```console - $ pipenv run bot - ``` -7. Set up the Logviewer, see the [Logviewer installation guide](https://github.com/modmail-dev/logviewer) - -### Local Hosting (Docker) - -We provide support for Docker to simplify the deployment of Modmail and Logviewer. -We assume you already have Docker and Docker Compose Plugin installed, if not, see [here](https://docs.docker.com/get-docker/). - -1. Create a Discord bot account, grant the necessary intents, and invite the bot ([guide](https://github.com/modmail-dev/modmail/wiki/Installation#2-discord-bot-account)) -2. Create a file named `.env`, then copy the contents of [this file](https://raw.githubusercontent.com/modmail-dev/modmail/master/.env.example) and replace the placeholders with their values -3. Create a file named `docker-compose.yml`, then copy the contents of [this file](https://raw.githubusercontent.com/modmail-dev/modmail/master/docker-compose.yml), do not change anything! -4. Start the bot - ```console - $ docker compose up -d - ``` - - For older Docker versions, you may need to run `docker-compose up -d` instead -5. View the status of your bot, using `docker ps` and `docker logs [container-id]` - -Our Docker images are hosted on [GitHub Container Registry](ghcr.io), you can build your own image if you wish: -```console -$ docker build --tag=modmail:master . -``` - -Then simply remove `ghcr.io/modmail-dev/` from the `docker-compose.yml` file. - -### Local Hosting (OS-Specific) - -This guide is a WIP. Join our [Discord server](https://discord.gg/cnUpwrnpYb) for more info. - -### Platform as a Service (PaaS) - -You can host this bot on Heroku (no longer free). - -Installation via Heroku is possible with your web browser alone. -The [**installation guide**](https://github.com/modmail-dev/modmail/wiki/Installation) (which includes a video tutorial!) will guide you through the entire installation process. If you run into any problems, join our [Modmail Discord Server](https://discord.gg/cnUpwrnpYb) for help and support. - -When using Heroku, you can configure automatic updates: - - Login to [GitHub](https://github.com/) and verify your account. - - [Fork the repo](https://github.com/modmail-dev/modmail/fork). - - Install the [Pull app](https://github.com/apps/pull) for your fork. - - Then go to the Deploy tab in your [Heroku account](https://dashboard.heroku.com/apps) of your bot app, select GitHub and connect your fork (usually by typing "Modmail"). - - Turn on auto-deploy for the `master` branch. +To develop your own, check out the [plugins documentation](https://github.com/modmail-dev/modmail/wiki/Plugins). + +Plugins requests and support are available in our [Modmail Support Server](https://discord.gg/cnUpwrnpYb). ## Sponsors @@ -208,17 +156,6 @@ Discord Advice Center: Become a sponsor on [Patreon](https://patreon.com/kyber). -## Plugins - -Modmail supports the use of third-party plugins to extend or add functionalities to the bot. -Plugins allow niche features as well as anything else outside of the scope of the core functionality of Modmail. - -You can find a list of third-party plugins using the `?plugins registry` command or visit the [Unofficial List of Plugins](https://github.com/modmail-dev/modmail/wiki/Unofficial-List-of-Plugins) for a list of plugins contributed by the community. - -To develop your own, check out the [plugins documentation](https://github.com/modmail-dev/modmail/wiki/Plugins). - -Plugins requests and support are available in our [Modmail Support Server](https://discord.gg/cnUpwrnpYb). - ## Contributing Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/modmail-dev/modmail/blob/master/.github/CONTRIBUTING.md) before you get started. From 6d61cf29ff0d9e8a3b984eb44a6337402246bff0 Mon Sep 17 00:00:00 2001 From: Amy <git@amyerskine.me> Date: Sun, 19 Nov 2023 05:45:13 +0000 Subject: [PATCH 643/705] Add JSON logging support (#3305) * Add JSON logging support This adds support for JSON logging, along with the relevant options required. This does not change the default log behaviour, so should be backwards compatible. It is opt in via the LOG_FORMAT option, which can be 'json' to use the new logger, or anything else to fallback to the old behaviour. This is implemented in terms of a custom formatter, which is optionally applied to the stdout stream. The debug stream is unaffected by this. * Allow JSON to be selected when creating handlers * Allow different formats to be selected for streams/files * Remove old / unused code * Add new config opts to helpfile * Formatting, basic typing and reorder for consistency in project. --------- Co-authored-by: Jerrie-Aries <hidzrie@gmail.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- core/config.py | 2 + core/config_help.json | 18 +++++++ core/models.py | 110 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 125 insertions(+), 5 deletions(-) diff --git a/core/config.py b/core/config.py index 527b2dc19f..a9e16a0df1 100644 --- a/core/config.py +++ b/core/config.py @@ -178,6 +178,8 @@ class ConfigManager: "disable_updates": False, # Logging "log_level": "INFO", + "stream_log_format": "plain", + "file_log_format": "plain", "discord_log_level": "INFO", # data collection "data_collection": True, diff --git a/core/config_help.json b/core/config_help.json index f909d27821..501c265827 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -1129,6 +1129,24 @@ "This configuration can only to be set through `.env` file or environment (config) variables." ] }, + "stream_log_format": { + "default": "plain", + "description": "The logging format when through a stream, can be 'plain' or 'json'", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] + }, + "file_log_format": { + "default": "plain", + "description": "The logging format when logging to a file, can be 'plain' or 'json'", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] + }, "discord_log_level": { "default": "INFO", "description": "The `discord.py` library logging level for logging to stdout.", diff --git a/core/models.py b/core/models.py index 29f6af71bb..2a397541c1 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,4 @@ +import json import logging import os import re @@ -9,7 +10,7 @@ from logging import FileHandler, StreamHandler, Handler from logging.handlers import RotatingFileHandler from string import Formatter -from typing import Optional +from typing import Dict, Optional import discord from discord.ext import commands @@ -74,6 +75,71 @@ def line(self, level="info"): ) +class JsonFormatter(logging.Formatter): + """ + Formatter that outputs JSON strings after parsing the LogRecord. + + Parameters + ---------- + fmt_dict : Optional[Dict[str, str]] + {key: logging format attribute} pairs. Defaults to {"message": "message"}. + time_format: str + time.strftime() format string. Default: "%Y-%m-%dT%H:%M:%S" + msec_format: str + Microsecond formatting. Appended at the end. Default: "%s.%03dZ" + """ + + def __init__( + self, + fmt_dict: Optional[Dict[str, str]] = None, + time_format: str = "%Y-%m-%dT%H:%M:%S", + msec_format: str = "%s.%03dZ", + ): + self.fmt_dict: Dict[str, str] = fmt_dict if fmt_dict is not None else {"message": "message"} + self.default_time_format: str = time_format + self.default_msec_format: str = msec_format + self.datefmt: Optional[str] = None + + def usesTime(self) -> bool: + """ + Overwritten to look for the attribute in the format dict values instead of the fmt string. + """ + return "asctime" in self.fmt_dict.values() + + def formatMessage(self, record) -> Dict[str, str]: + """ + Overwritten to return a dictionary of the relevant LogRecord attributes instead of a string. + KeyError is raised if an unknown attribute is provided in the fmt_dict. + """ + return {fmt_key: record.__dict__[fmt_val] for fmt_key, fmt_val in self.fmt_dict.items()} + + def format(self, record) -> str: + """ + Mostly the same as the parent's class method, the difference being that a dict is manipulated and dumped as JSON + instead of a string. + """ + record.message = record.getMessage() + + if self.usesTime(): + record.asctime = self.formatTime(record, self.datefmt) + + message_dict = self.formatMessage(record) + + if record.exc_info: + # Cache the traceback text to avoid converting it multiple times + # (it's constant anyway) + if not record.exc_text: + record.exc_text = self.formatException(record.exc_info) + + if record.exc_text: + message_dict["exc_info"] = record.exc_text + + if record.stack_info: + message_dict["stack_info"] = self.formatStack(record.stack_info) + + return json.dumps(message_dict, default=str) + + class FileFormatter(logging.Formatter): ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]") @@ -85,11 +151,25 @@ def format(self, record): log_stream_formatter = logging.Formatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%m/%d/%y %H:%M:%S" ) + log_file_formatter = FileFormatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) +json_formatter = JsonFormatter( + { + "level": "levelname", + "message": "message", + "loggerName": "name", + "processName": "processName", + "processID": "process", + "threadName": "threadName", + "threadID": "thread", + "timestamp": "asctime", + } +) + def create_log_handler( filename: Optional[str] = None, @@ -98,6 +178,7 @@ def create_log_handler( level: int = logging.DEBUG, mode: str = "a+", encoding: str = "utf-8", + format: str = "plain", maxBytes: int = 28000000, backupCount: int = 1, **kwargs, @@ -124,6 +205,9 @@ def create_log_handler( encoding : str If this keyword argument is specified along with filename, its value is used when the `FileHandler` is created, and thus used when opening the output file. Defaults to 'utf-8'. + format : str + The format to output with, can either be 'json' or 'plain'. Will apply to whichever handler is created, + based on other conditional logic. maxBytes : int The max file size before the rollover occurs. Defaults to 28000000 (28MB). Rollover occurs whenever the current log file is nearly `maxBytes` in length; but if either of `maxBytes` or `backupCount` is zero, @@ -141,23 +225,28 @@ def create_log_handler( if filename is None: handler = StreamHandler(stream=sys.stdout, **kwargs) - handler.setFormatter(log_stream_formatter) + formatter = log_stream_formatter elif not rotating: handler = FileHandler(filename, mode=mode, encoding=encoding, **kwargs) - handler.setFormatter(log_file_formatter) + formatter = log_file_formatter else: handler = RotatingFileHandler( filename, mode=mode, encoding=encoding, maxBytes=maxBytes, backupCount=backupCount, **kwargs ) - handler.setFormatter(log_file_formatter) + formatter = log_file_formatter + + if format == "json": + formatter = json_formatter handler.setLevel(level) + handler.setFormatter(formatter) return handler logging.setLoggerClass(ModmailLogger) log_level = logging.INFO loggers = set() + ch = create_log_handler(level=log_level) ch_debug: Optional[RotatingFileHandler] = None @@ -173,7 +262,11 @@ def getLogger(name=None) -> ModmailLogger: def configure_logging(bot) -> None: - global ch_debug, log_level + global ch_debug, log_level, ch + + stream_log_format, file_log_format = bot.config["stream_log_format"], bot.config["file_log_format"] + if stream_log_format == "json": + ch.setFormatter(json_formatter) logger = getLogger(__name__) level_text = bot.config["log_level"].upper() @@ -198,8 +291,15 @@ def configure_logging(bot) -> None: logger.info("Log file: %s", bot.log_file_path) ch_debug = create_log_handler(bot.log_file_path, rotating=True) + + if file_log_format == "json": + ch_debug.setFormatter(json_formatter) + ch.setLevel(log_level) + logger.info("Stream log format: %s", stream_log_format) + logger.info("File log format: %s", file_log_format) + for log in loggers: log.setLevel(log_level) log.addHandler(ch_debug) From 5c710596c870121d2df864ceec8d86f0333fbb49 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sat, 18 Nov 2023 21:47:34 -0800 Subject: [PATCH 644/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9830415b10..0b3a61943a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `REGISTRY_PLUGINS_ONLY`, environment variable, when set, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) - `DISCORD_LOG_LEVEL` environment variable to set the log level of discord.py. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - New registry plugin: [`autoreact`](https://github.com/martinbndr/kyb3r-modmail-plugins/tree/master/autoreact). +- `STREAM_LOG_FORMAT` and `FILE_LOG_FORMAT` for settings the log format of the stream and file handlers respectively. Possible options are `json` and `plain` (default). ([PR #3305](https://github.com/modmail-dev/Modmail/pull/3305)) ### Changed - Repo moved to https://github.com/modmail-dev/modmail. From ae99060a3fe4a0afcd2d2fa35af85e8fce5b8aaa Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Sun, 19 Nov 2023 16:38:42 +0800 Subject: [PATCH 645/705] Fix rate limit issue on raw reaction add/remove events. (#3306) * Fix rate limit issue on raw reaction add/remove events. * Pasd message object to `find_linked_messages` since it is already fetched. --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- bot.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/bot.py b/bot.py index 45530a908f..3701d826ea 100644 --- a/bot.py +++ b/bot.py @@ -1222,25 +1222,36 @@ async def handle_reaction_events(self, payload): return channel = self.get_channel(payload.channel_id) - if not channel: # dm channel not in internal cache - _thread = await self.threads.find(recipient=user) - if not _thread: + thread = None + # dm channel not in internal cache + if not channel: + thread = await self.threads.find(recipient=user) + if not thread: + return + channel = await thread.recipient.create_dm() + if channel.id != payload.channel_id: + return + + from_dm = isinstance(channel, discord.DMChannel) + from_txt = isinstance(channel, discord.TextChannel) + if not from_dm and not from_txt: + return + + if not thread: + params = {"recipient": user} if from_dm else {"channel": channel} + thread = await self.threads.find(**params) + if not thread: return - channel = await _thread.recipient.create_dm() + # thread must exist before doing this API call try: message = await channel.fetch_message(payload.message_id) except (discord.NotFound, discord.Forbidden): return reaction = payload.emoji - close_emoji = await self.convert_emoji(self.config["close_emoji"]) - - if isinstance(channel, discord.DMChannel): - thread = await self.threads.find(recipient=user) - if not thread: - return + if from_dm: if ( payload.event_type == "REACTION_ADD" and message.embeds @@ -1248,7 +1259,7 @@ async def handle_reaction_events(self, payload): and self.config.get("recipient_thread_close") ): ts = message.embeds[0].timestamp - if thread and ts == thread.channel.created_at: + if ts == thread.channel.created_at: # the reacted message is the corresponding thread creation embed # closing thread return await thread.close(closer=user) @@ -1268,11 +1279,10 @@ async def handle_reaction_events(self, payload): logger.warning("Failed to find linked message for reactions: %s", e) return else: - thread = await self.threads.find(channel=channel) - if not thread: - return try: - _, *linked_messages = await thread.find_linked_messages(message.id, either_direction=True) + _, *linked_messages = await thread.find_linked_messages( + message1=message, either_direction=True + ) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return From a8d7c26d8cfd863c13b4862ffae1cb998a13fda8 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 19 Nov 2023 02:21:42 -0800 Subject: [PATCH 646/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b3a61943a..76a929b178 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Fixed a syntactic error in the close message when a thread is closed after a certain duration. ([PR #3233](https://github.com/modmail-dev/Modmail/pull/3233)) - Removed an extra space in the help command title when the command has no parameters. ([PR #3271](https://github.com/modmail-dev/Modmail/pull/3271)) - Corrected some incorrect config help descriptions. ([PR #3277](https://github.com/modmail-dev/Modmail/pull/3277)) +- Rate limit issue when fetch the messages due to reaction linking. ([PR #3306](https://github.com/modmail-dev/Modmail/pull/3306)) ### Added - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) From 54f7b1cd916db6a8490544748318e007def52699 Mon Sep 17 00:00:00 2001 From: Atharv Agarwal <49218334+Atharv-Agarwal@users.noreply.github.com> Date: Mon, 20 Nov 2023 02:20:42 +0530 Subject: [PATCH 647/705] Add config to manage how long logs are stored (#3257) * Add config to change how long logs are stored * Optimize deleting logs * Update core/config_help.json Co-authored-by: khakers <22665282+khakers@users.noreply.github.com> Signed-off-by: Cordila <49218334+Cordila@users.noreply.github.com> * Testing changes * Update core/config_help.json (Fix copy paste) Co-authored-by: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Signed-off-by: Cordila <49218334+Cordila@users.noreply.github.com> --------- Signed-off-by: Cordila <49218334+Cordila@users.noreply.github.com> Co-authored-by: Cordila <49218334+Cordila@users.noreply.github.com> Co-authored-by: khakers <22665282+khakers@users.noreply.github.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> --- bot.py | 18 ++++++++++++++---- cogs/plugins.py | 2 -- cogs/utility.py | 1 - core/config.py | 4 ++-- core/config_help.json | 11 +++++++++++ core/models.py | 1 - core/thread.py | 2 -- 7 files changed, 27 insertions(+), 12 deletions(-) diff --git a/bot.py b/bot.py index 3701d826ea..5e8854faa8 100644 --- a/bot.py +++ b/bot.py @@ -12,7 +12,7 @@ import sys import platform import typing -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta from subprocess import PIPE from types import SimpleNamespace @@ -616,6 +616,7 @@ async def on_ready(self): self.post_metadata.start() self.autoupdate.start() + self.log_expiry.start() self._started = True async def convert_emoji(self, name: str) -> str: @@ -640,7 +641,6 @@ async def get_or_fetch_user(self, id: int) -> discord.User: return self.get_user(id) or await self.fetch_user(id) async def retrieve_emoji(self) -> typing.Tuple[str, str]: - sent_emoji = self.config["sent_emoji"] blocked_emoji = self.config["blocked_emoji"] @@ -714,7 +714,6 @@ def check_manual_blocked_roles(self, author: discord.Member) -> bool: if isinstance(author, discord.Member): for r in author.roles: if str(r.id) in self.blocked_roles: - blocked_reason = self.blocked_roles.get(str(r.id)) or "" try: @@ -773,7 +772,6 @@ async def is_blocked( channel: discord.TextChannel = None, send_message: bool = False, ) -> bool: - member = self.guild.get_member(author.id) if member is None: # try to find in other guilds @@ -1707,6 +1705,18 @@ async def before_autoupdate(self): self.autoupdate.cancel() return + @tasks.loop(hours=1, reconnect=False) + async def log_expiry(self): + log_expire_after = self.config.get("log_expiration") + if log_expire_after == isodate.Duration(): + return self.log_expiry.stop() + + now = discord.utils.utcnow() + expiration_datetime = now - log_expire_after + expired_logs = await self.db.logs.delete_many({"closed_at": {"$lte": str(expiration_datetime)}}) + + logger.info(f"Deleted {expired_logs.deleted_count} expired logs.") + def format_channel_name(self, author, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names diff --git a/cogs/plugins.py b/cogs/plugins.py index 6bae7738c6..59a2c9d24d 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -276,7 +276,6 @@ async def unload_plugin(self, plugin: Plugin) -> None: del sys.modules[module] async def parse_user_input(self, ctx, plugin_name, check_version=False): - if not self.bot.config["enable_plugins"]: embed = discord.Embed( description="Plugins are disabled, enable them by setting `ENABLE_PLUGINS=true`", @@ -399,7 +398,6 @@ async def plugins_add(self, ctx, *, plugin_name: str): await self.bot.config.update() if self.bot.config.get("enable_plugins"): - invalidate_caches() try: diff --git a/cogs/utility.py b/cogs/utility.py index d0ecbeda22..749cf3e160 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -584,7 +584,6 @@ async def status(self, ctx, *, status_type: str.lower): return await ctx.send(embed=embed) async def set_presence(self, *, status=None, activity_type=None, activity_message=None): - if status is None: status = self.bot.config.get("status") diff --git a/core/config.py b/core/config.py index a9e16a0df1..5c6b0dd09d 100644 --- a/core/config.py +++ b/core/config.py @@ -21,7 +21,6 @@ class ConfigManager: - public_keys = { # activity "twitch_url": "https://www.twitch.tv/discordmodmail/", @@ -37,6 +36,7 @@ class ConfigManager: "account_age": isodate.Duration(), "guild_age": isodate.Duration(), "thread_cooldown": isodate.Duration(), + "log_expiration": isodate.Duration(), "reply_without_command": False, "anon_reply_without_command": False, "plain_reply_without_command": False, @@ -187,7 +187,7 @@ class ConfigManager: colors = {"mod_color", "recipient_color", "main_color", "error_color"} - time_deltas = {"account_age", "guild_age", "thread_auto_close", "thread_cooldown"} + time_deltas = {"account_age", "guild_age", "thread_auto_close", "thread_cooldown", "log_expiration"} booleans = { "use_user_id_channel_name", diff --git a/core/config_help.json b/core/config_help.json index 501c265827..d301763fe4 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -373,6 +373,17 @@ "To disable thread cooldown, do `{prefix}config del thread_cooldown`." ] }, + "log_expiration": { + "default": "Never", + "description": "The duration closed threads will be stored within the database before deletion. Logs that have been closed for longer than this duration will be deleted automatically.", + "examples": [ + "`{prefix}config set log_expiration P12DT3H` (stands for 12 days and 3 hours in [ISO-8601 Duration Format](https://en.wikipedia.org/wiki/ISO_8601#Durations))", + "`{prefix}config set log_expiration 3 days and 5 hours` (accepted readable time)" + ], + "notes": [ + "To disable log expiration, do `{prefix}config del log_expiration`." + ] + }, "thread_cancelled": { "default": "\"Cancelled\"", "description": "This is the message to display when a thread times out and creation is cancelled.", diff --git a/core/models.py b/core/models.py index 2a397541c1..611db375f0 100644 --- a/core/models.py +++ b/core/models.py @@ -394,7 +394,6 @@ async def convert(self, ctx, argument): try: return await super().convert(ctx, argument) except commands.ChannelNotFound: - if guild: categories = {c.name.casefold(): c for c in guild.categories} else: diff --git a/core/thread.py b/core/thread.py index 46be932c1a..09c5df46ee 100644 --- a/core/thread.py +++ b/core/thread.py @@ -721,7 +721,6 @@ async def delete_message( async def find_linked_message_from_dm( self, message, either_direction=False, get_thread_channel=False ) -> typing.List[discord.Message]: - joint_id = None if either_direction: joint_id = get_joint_id(message) @@ -914,7 +913,6 @@ async def send( persistent_note: bool = False, thread_creation: bool = False, ) -> None: - if not note and from_mod: self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close From 2bc51e8f9eb34758e7c997d7eb6d23338867a83a Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 19 Nov 2023 12:54:53 -0800 Subject: [PATCH 648/705] Update changelog and added a note for comparing dates by string --- CHANGELOG.md | 3 ++- bot.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76a929b178..3e5d335e44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `REGISTRY_PLUGINS_ONLY`, environment variable, when set, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) - `DISCORD_LOG_LEVEL` environment variable to set the log level of discord.py. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - New registry plugin: [`autoreact`](https://github.com/martinbndr/kyb3r-modmail-plugins/tree/master/autoreact). -- `STREAM_LOG_FORMAT` and `FILE_LOG_FORMAT` for settings the log format of the stream and file handlers respectively. Possible options are `json` and `plain` (default). ([PR #3305](https://github.com/modmail-dev/Modmail/pull/3305)) +- `STREAM_LOG_FORMAT` and `FILE_LOG_FORMAT` environment variable to set the log format of the stream and file handlers respectively. Possible options are `json` and `plain` (default). ([PR #3305](https://github.com/modmail-dev/Modmail/pull/3305)) +- `LOG_EXPIRATION` environment variable to set the expiration time of logs. ([PR #3257](https://github.com/modmail-dev/Modmail/pull/3257)) ### Changed - Repo moved to https://github.com/modmail-dev/modmail. diff --git a/bot.py b/bot.py index 5e8854faa8..f36ecc8351 100644 --- a/bot.py +++ b/bot.py @@ -1713,6 +1713,8 @@ async def log_expiry(self): now = discord.utils.utcnow() expiration_datetime = now - log_expire_after + # WARNING: comparison is done lexicographically, not by date. + # This is fine as long as the date is in zero-padded ISO format, which it should be. expired_logs = await self.db.logs.delete_many({"closed_at": {"$lte": str(expiration_datetime)}}) logger.info(f"Deleted {expired_logs.deleted_count} expired logs.") From c6f87cdb0cffec3d88a0c75f003f95f30bd7980d Mon Sep 17 00:00:00 2001 From: Nicklaus <100449899+Nicklaus-s@users.noreply.github.com> Date: Sun, 19 Nov 2023 14:58:52 -0600 Subject: [PATCH 649/705] Add `rename` to `registry.json` (#3276) * Add `rename` to `registry.json` Signed-off-by: Nicklaus <100449899+Nicklaus-s@users.noreply.github.com> * Change icon Signed-off-by: Nicklaus <100449899+Nicklaus-s@users.noreply.github.com> --------- Signed-off-by: Nicklaus <100449899+Nicklaus-s@users.noreply.github.com> --- plugins/registry.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/registry.json b/plugins/registry.json index be138a30b2..4079001a50 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -124,5 +124,14 @@ "title": "Top Supporters", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "rename": { + "repository": "Nicklaus-s/modmail-plugins", + "branch": "master", + "description": "Set a thread channel name.", + "bot_version": "4.0.0", + "title": "Rename", + "icon_url": "https://i.imgur.com/A1auJ95.png", + "thumbnail_url": "https://i.imgur.com/A1auJ95.png" } } From 5b2770caf2c8277f1de50d70db1407e1b5fdbb8b Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 19 Nov 2023 13:00:23 -0800 Subject: [PATCH 650/705] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e5d335e44..1b7910bfff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,9 +22,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) - `REGISTRY_PLUGINS_ONLY`, environment variable, when set, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) - `DISCORD_LOG_LEVEL` environment variable to set the log level of discord.py. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) -- New registry plugin: [`autoreact`](https://github.com/martinbndr/kyb3r-modmail-plugins/tree/master/autoreact). - `STREAM_LOG_FORMAT` and `FILE_LOG_FORMAT` environment variable to set the log format of the stream and file handlers respectively. Possible options are `json` and `plain` (default). ([PR #3305](https://github.com/modmail-dev/Modmail/pull/3305)) - `LOG_EXPIRATION` environment variable to set the expiration time of logs. ([PR #3257](https://github.com/modmail-dev/Modmail/pull/3257)) +- New registry plugins: [`autoreact`](https://github.com/martinbndr/kyb3r-modmail-plugins/tree/master/autoreact) and [`rename`](https://github.com/Nicklaus-s/modmail-plugins/tree/main/rename). ### Changed - Repo moved to https://github.com/modmail-dev/modmail. From a94e7a984172801c03e9a316e93ea1a5b47df9fd Mon Sep 17 00:00:00 2001 From: Jerrie <70805800+Jerrie-Aries@users.noreply.github.com> Date: Mon, 20 Nov 2023 05:26:12 +0800 Subject: [PATCH 651/705] Fix bug with `?plugin update`. (#3295) --- cogs/plugins.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index 59a2c9d24d..d5787956f1 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -500,12 +500,12 @@ async def update_plugin(self, ctx, plugin_name): description=f"Failed to update {plugin.name}. This plugin will now be removed from your bot.", color=self.bot.error_color, ) - self.bot.config["plugins"].remove(plugin_name) - logger.debug("Failed to update %s. Removed plugin from config.", plugin_name) + self.bot.config["plugins"].remove(str(plugin)) + logger.debug("Failed to update %s. Removed plugin from config.", plugin) else: - logger.debug("Updated %s.", plugin_name) + logger.debug("Updated %s.", plugin) else: - logger.debug("Updated %s.", plugin_name) + logger.debug("Updated %s.", plugin) return await ctx.send(embed=embed) @plugins.command(name="update") From 8bd30dc90760b5e5a6581abae0a72126b092da44 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 19 Nov 2023 13:27:48 -0800 Subject: [PATCH 652/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b7910bfff..f79f46c491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Removed an extra space in the help command title when the command has no parameters. ([PR #3271](https://github.com/modmail-dev/Modmail/pull/3271)) - Corrected some incorrect config help descriptions. ([PR #3277](https://github.com/modmail-dev/Modmail/pull/3277)) - Rate limit issue when fetch the messages due to reaction linking. ([PR #3306](https://github.com/modmail-dev/Modmail/pull/3306)) +- Update command fails when the plugin is invalid. ([PR #3295](https://github.com/modmail-dev/Modmail/pull/3295)) ### Added - `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) From 53d40e0585919eadba97e7d0abcb822d1ebcbb34 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Sun, 19 Nov 2023 22:41:29 +0100 Subject: [PATCH 653/705] fix: discord invite ( new server ) (#3307) * fix: discord invite ( new server ) Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update link Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index 749cf3e160..579c4a7e4e 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -352,7 +352,7 @@ async def about(self, ctx): embed.add_field( name="Want Modmail in Your Server?", value="Follow the installation guide on [GitHub](https://github.com/modmail-dev/modmail/) " - "and join our [Discord server](https://discord.gg/F34cRU8)!", + "and join our [Discord server](https://discord.gg/cnUpwrnpYb)!", inline=False, ) From ec95eb7f6b6abfb1a89c48eb8e0915313a699116 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:16:04 -0800 Subject: [PATCH 654/705] Update deps: aiohttp, colorama, emoji --- Pipfile | 6 +- Pipfile.lock | 1435 ++++++++++++++++++++++++++------------------------ bot.py | 6 +- 3 files changed, 752 insertions(+), 695 deletions(-) diff --git a/Pipfile b/Pipfile index e61e3b9288..f2590a1e2b 100644 --- a/Pipfile +++ b/Pipfile @@ -10,10 +10,10 @@ pylint = "~=2.9.3" typing-extensions = "==4.2.0" [packages] -aiohttp = "==3.8.1" -colorama = "~=0.4.5" +aiohttp = "==3.9.0" +colorama = "==0.4.6" "discord.py" = "==2.0.1" -emoji = "==1.7.0" +emoji = "==2.8.0" isodate = "~=0.6.0" motor = "==2.5.1" natural = "~=0.2.0" diff --git a/Pipfile.lock b/Pipfile.lock index e1c531856e..35808d048b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9d1171901e036b1f78a2e89855d564e9f559736ca076128fa27eb14ee8f917a4" + "sha256": "f28fd3a11b8f1550ba6731a0bc17740966b1fd98d10c1b004d416ca5b1dd3b84" }, "pipfile-spec": 6, "requires": {}, @@ -16,196 +16,190 @@ "default": { "aiohttp": { "hashes": [ - "sha256:01d7bdb774a9acc838e6b8f1d114f45303841b89b95984cbb7d80ea41172a9e3", - "sha256:03a6d5349c9ee8f79ab3ff3694d6ce1cfc3ced1c9d36200cb8f08ba06bd3b782", - "sha256:04d48b8ce6ab3cf2097b1855e1505181bdd05586ca275f2505514a6e274e8e75", - "sha256:0770e2806a30e744b4e21c9d73b7bee18a1cfa3c47991ee2e5a65b887c49d5cf", - "sha256:07b05cd3305e8a73112103c834e91cd27ce5b4bd07850c4b4dbd1877d3f45be7", - "sha256:086f92daf51a032d062ec5f58af5ca6a44d082c35299c96376a41cbb33034675", - "sha256:099ebd2c37ac74cce10a3527d2b49af80243e2a4fa39e7bce41617fbc35fa3c1", - "sha256:0c7ebbbde809ff4e970824b2b6cb7e4222be6b95a296e46c03cf050878fc1785", - "sha256:102e487eeb82afac440581e5d7f8f44560b36cf0bdd11abc51a46c1cd88914d4", - "sha256:11691cf4dc5b94236ccc609b70fec991234e7ef8d4c02dd0c9668d1e486f5abf", - "sha256:11a67c0d562e07067c4e86bffc1553f2cf5b664d6111c894671b2b8712f3aba5", - "sha256:12de6add4038df8f72fac606dff775791a60f113a725c960f2bab01d8b8e6b15", - "sha256:13487abd2f761d4be7c8ff9080de2671e53fff69711d46de703c310c4c9317ca", - "sha256:15b09b06dae900777833fe7fc4b4aa426556ce95847a3e8d7548e2d19e34edb8", - "sha256:1c182cb873bc91b411e184dab7a2b664d4fea2743df0e4d57402f7f3fa644bac", - "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8", - "sha256:28d490af82bc6b7ce53ff31337a18a10498303fe66f701ab65ef27e143c3b0ef", - "sha256:2e5d962cf7e1d426aa0e528a7e198658cdc8aa4fe87f781d039ad75dcd52c516", - "sha256:2ed076098b171573161eb146afcb9129b5ff63308960aeca4b676d9d3c35e700", - "sha256:2f2f69dca064926e79997f45b2f34e202b320fd3782f17a91941f7eb85502ee2", - "sha256:31560d268ff62143e92423ef183680b9829b1b482c011713ae941997921eebc8", - "sha256:31d1e1c0dbf19ebccbfd62eff461518dcb1e307b195e93bba60c965a4dcf1ba0", - "sha256:37951ad2f4a6df6506750a23f7cbabad24c73c65f23f72e95897bb2cecbae676", - "sha256:3af642b43ce56c24d063325dd2cf20ee012d2b9ba4c3c008755a301aaea720ad", - "sha256:44db35a9e15d6fe5c40d74952e803b1d96e964f683b5a78c3cc64eb177878155", - "sha256:473d93d4450880fe278696549f2e7aed8cd23708c3c1997981464475f32137db", - "sha256:477c3ea0ba410b2b56b7efb072c36fa91b1e6fc331761798fa3f28bb224830dd", - "sha256:4a4a4e30bf1edcad13fb0804300557aedd07a92cabc74382fdd0ba6ca2661091", - "sha256:4aed991a28ea3ce320dc8ce655875e1e00a11bdd29fe9444dd4f88c30d558602", - "sha256:51467000f3647d519272392f484126aa716f747859794ac9924a7aafa86cd411", - "sha256:55c3d1072704d27401c92339144d199d9de7b52627f724a949fc7d5fc56d8b93", - "sha256:589c72667a5febd36f1315aa6e5f56dd4aa4862df295cb51c769d16142ddd7cd", - "sha256:5bfde62d1d2641a1f5173b8c8c2d96ceb4854f54a44c23102e2ccc7e02f003ec", - "sha256:5c23b1ad869653bc818e972b7a3a79852d0e494e9ab7e1a701a3decc49c20d51", - "sha256:61bfc23df345d8c9716d03717c2ed5e27374e0fe6f659ea64edcd27b4b044cf7", - "sha256:6ae828d3a003f03ae31915c31fa684b9890ea44c9c989056fea96e3d12a9fa17", - "sha256:6c7cefb4b0640703eb1069835c02486669312bf2f12b48a748e0a7756d0de33d", - "sha256:6d69f36d445c45cda7b3b26afef2fc34ef5ac0cdc75584a87ef307ee3c8c6d00", - "sha256:6f0d5f33feb5f69ddd57a4a4bd3d56c719a141080b445cbf18f238973c5c9923", - "sha256:6f8b01295e26c68b3a1b90efb7a89029110d3a4139270b24fda961893216c440", - "sha256:713ac174a629d39b7c6a3aa757b337599798da4c1157114a314e4e391cd28e32", - "sha256:718626a174e7e467f0558954f94af117b7d4695d48eb980146016afa4b580b2e", - "sha256:7187a76598bdb895af0adbd2fb7474d7f6025d170bc0a1130242da817ce9e7d1", - "sha256:71927042ed6365a09a98a6377501af5c9f0a4d38083652bcd2281a06a5976724", - "sha256:7d08744e9bae2ca9c382581f7dce1273fe3c9bae94ff572c3626e8da5b193c6a", - "sha256:7dadf3c307b31e0e61689cbf9e06be7a867c563d5a63ce9dca578f956609abf8", - "sha256:81e3d8c34c623ca4e36c46524a3530e99c0bc95ed068fd6e9b55cb721d408fb2", - "sha256:844a9b460871ee0a0b0b68a64890dae9c415e513db0f4a7e3cab41a0f2fedf33", - "sha256:8b7ef7cbd4fec9a1e811a5de813311ed4f7ac7d93e0fda233c9b3e1428f7dd7b", - "sha256:97ef77eb6b044134c0b3a96e16abcb05ecce892965a2124c566af0fd60f717e2", - "sha256:99b5eeae8e019e7aad8af8bb314fb908dd2e028b3cdaad87ec05095394cce632", - "sha256:a25fa703a527158aaf10dafd956f7d42ac6d30ec80e9a70846253dd13e2f067b", - "sha256:a2f635ce61a89c5732537a7896b6319a8fcfa23ba09bec36e1b1ac0ab31270d2", - "sha256:a79004bb58748f31ae1cbe9fa891054baaa46fb106c2dc7af9f8e3304dc30316", - "sha256:a996d01ca39b8dfe77440f3cd600825d05841088fd6bc0144cc6c2ec14cc5f74", - "sha256:b0e20cddbd676ab8a64c774fefa0ad787cc506afd844de95da56060348021e96", - "sha256:b6613280ccedf24354406caf785db748bebbddcf31408b20c0b48cb86af76866", - "sha256:b9d00268fcb9f66fbcc7cd9fe423741d90c75ee029a1d15c09b22d23253c0a44", - "sha256:bb01ba6b0d3f6c68b89fce7305080145d4877ad3acaed424bae4d4ee75faa950", - "sha256:c2aef4703f1f2ddc6df17519885dbfa3514929149d3ff900b73f45998f2532fa", - "sha256:c34dc4958b232ef6188c4318cb7b2c2d80521c9a56c52449f8f93ab7bc2a8a1c", - "sha256:c3630c3ef435c0a7c549ba170a0633a56e92629aeed0e707fec832dee313fb7a", - "sha256:c3d6a4d0619e09dcd61021debf7059955c2004fa29f48788a3dfaf9c9901a7cd", - "sha256:d15367ce87c8e9e09b0f989bfd72dc641bcd04ba091c68cd305312d00962addd", - "sha256:d2f9b69293c33aaa53d923032fe227feac867f81682f002ce33ffae978f0a9a9", - "sha256:e999f2d0e12eea01caeecb17b653f3713d758f6dcc770417cf29ef08d3931421", - "sha256:ea302f34477fda3f85560a06d9ebdc7fa41e82420e892fc50b577e35fc6a50b2", - "sha256:eaba923151d9deea315be1f3e2b31cc39a6d1d2f682f942905951f4e40200922", - "sha256:ef9612483cb35171d51d9173647eed5d0069eaa2ee812793a75373447d487aa4", - "sha256:f5315a2eb0239185af1bddb1abf472d877fede3cc8d143c6cddad37678293237", - "sha256:fa0ffcace9b3aa34d205d8130f7873fcfefcb6a4dd3dd705b0dab69af6712642", - "sha256:fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578" + "sha256:05857848da443c8c12110d99285d499b4e84d59918a21132e45c3f0804876994", + "sha256:05a183f1978802588711aed0dea31e697d760ce9055292db9dc1604daa9a8ded", + "sha256:09f23292d29135025e19e8ff4f0a68df078fe4ee013bca0105b2e803989de92d", + "sha256:11ca808f9a6b63485059f5f6e164ef7ec826483c1212a44f268b3653c91237d8", + "sha256:1736d87dad8ef46a8ec9cddd349fa9f7bd3a064c47dd6469c0d6763d3d49a4fc", + "sha256:1df43596b826022b14998f0460926ce261544fedefe0d2f653e1b20f49e96454", + "sha256:23170247ef89ffa842a02bbfdc425028574d9e010611659abeb24d890bc53bb8", + "sha256:2779f5e7c70f7b421915fd47db332c81de365678180a9f3ab404088f87ba5ff9", + "sha256:28185e36a78d247c55e9fbea2332d16aefa14c5276a582ce7a896231c6b1c208", + "sha256:2cbc14a13fb6b42d344e4f27746a4b03a2cb0c1c3c5b932b0d6ad8881aa390e3", + "sha256:2d71abc15ff7047412ef26bf812dfc8d0d1020d664617f4913df2df469f26b76", + "sha256:2d820162c8c2bdbe97d328cd4f417c955ca370027dce593345e437b2e9ffdc4d", + "sha256:317719d7f824eba55857fe0729363af58e27c066c731bc62cd97bc9c3d9c7ea4", + "sha256:35a68cd63ca6aaef5707888f17a70c36efe62b099a4e853d33dc2e9872125be8", + "sha256:3607375053df58ed6f23903aa10cf3112b1240e8c799d243bbad0f7be0666986", + "sha256:366bc870d7ac61726f32a489fbe3d1d8876e87506870be66b01aeb84389e967e", + "sha256:3abf0551874fecf95f93b58f25ef4fc9a250669a2257753f38f8f592db85ddea", + "sha256:3d7f6235c7475658acfc1769d968e07ab585c79f6ca438ddfecaa9a08006aee2", + "sha256:3dd8119752dd30dd7bca7d4bc2a92a59be6a003e4e5c2cf7e248b89751b8f4b7", + "sha256:42fe4fd9f0dfcc7be4248c162d8056f1d51a04c60e53366b0098d1267c4c9da8", + "sha256:45820ddbb276113ead8d4907a7802adb77548087ff5465d5c554f9aa3928ae7d", + "sha256:4790e44f46a4aa07b64504089def5744d3b6780468c4ec3a1a36eb7f2cae9814", + "sha256:4afa8f71dba3a5a2e1e1282a51cba7341ae76585345c43d8f0e624882b622218", + "sha256:4b777c9286b6c6a94f50ddb3a6e730deec327e9e2256cb08b5530db0f7d40fd8", + "sha256:4ee1b4152bc3190cc40ddd6a14715e3004944263ea208229ab4c297712aa3075", + "sha256:51a4cd44788ea0b5e6bb8fa704597af3a30be75503a7ed1098bc5b8ffdf6c982", + "sha256:536b01513d67d10baf6f71c72decdf492fb7433c5f2f133e9a9087379d4b6f31", + "sha256:571760ad7736b34d05597a1fd38cbc7d47f7b65deb722cb8e86fd827404d1f6b", + "sha256:5a2eb5311a37fe105aa35f62f75a078537e1a9e4e1d78c86ec9893a3c97d7a30", + "sha256:5ab16c254e2312efeb799bc3c06897f65a133b38b69682bf75d1f1ee1a9c43a9", + "sha256:65b0a70a25456d329a5e1426702dde67be0fb7a4ead718005ba2ca582d023a94", + "sha256:673343fbc0c1ac44d0d2640addc56e97a052504beacd7ade0dc5e76d3a4c16e8", + "sha256:6777a390e41e78e7c45dab43a4a0196c55c3b8c30eebe017b152939372a83253", + "sha256:6896b8416be9ada4d22cd359d7cb98955576ce863eadad5596b7cdfbf3e17c6c", + "sha256:694df243f394629bcae2d8ed94c589a181e8ba8604159e6e45e7b22e58291113", + "sha256:70e851f596c00f40a2f00a46126c95c2e04e146015af05a9da3e4867cfc55911", + "sha256:7276fe0017664414fdc3618fca411630405f1aaf0cc3be69def650eb50441787", + "sha256:76a86a9989ebf82ee61e06e2bab408aec4ea367dc6da35145c3352b60a112d11", + "sha256:7a94bde005a8f926d0fa38b88092a03dea4b4875a61fbcd9ac6f4351df1b57cd", + "sha256:7ae5f99a32c53731c93ac3075abd3e1e5cfbe72fc3eaac4c27c9dd64ba3b19fe", + "sha256:7e8a3b79b6d186a9c99761fd4a5e8dd575a48d96021f220ac5b5fa856e5dd029", + "sha256:816f4db40555026e4cdda604a1088577c1fb957d02f3f1292e0221353403f192", + "sha256:8303531e2c17b1a494ffaeba48f2da655fe932c4e9a2626c8718403c83e5dd2b", + "sha256:8488519aa05e636c5997719fe543c8daf19f538f4fa044f3ce94bee608817cff", + "sha256:87c8b0a6487e8109427ccf638580865b54e2e3db4a6e0e11c02639231b41fc0f", + "sha256:8c9e5f4d7208cda1a2bb600e29069eecf857e6980d0ccc922ccf9d1372c16f4b", + "sha256:94697c7293199c2a2551e3e3e18438b4cba293e79c6bc2319f5fd652fccb7456", + "sha256:9623cfd9e85b76b83ef88519d98326d4731f8d71869867e47a0b979ffec61c73", + "sha256:98d21092bf2637c5fa724a428a69e8f5955f2182bff61f8036827cf6ce1157bf", + "sha256:99ae01fb13a618b9942376df77a1f50c20a281390dad3c56a6ec2942e266220d", + "sha256:9c196b30f1b1aa3363a69dd69079ae9bec96c2965c4707eaa6914ba099fb7d4f", + "sha256:a00ce44c21612d185c5275c5cba4bab8d7c1590f248638b667ed8a782fa8cd6f", + "sha256:a1b66dbb8a7d5f50e9e2ea3804b01e766308331d0cac76eb30c563ac89c95985", + "sha256:a1d7edf74a36de0e5ca50787e83a77cf352f5504eb0ffa3f07000a911ba353fb", + "sha256:a1e3b3c107ccb0e537f309f719994a55621acd2c8fdf6d5ce5152aed788fb940", + "sha256:a486ddf57ab98b6d19ad36458b9f09e6022de0381674fe00228ca7b741aacb2f", + "sha256:ac9669990e2016d644ba8ae4758688534aabde8dbbc81f9af129c3f5f01ca9cd", + "sha256:b1a2ea8252cacc7fd51df5a56d7a2bb1986ed39be9397b51a08015727dfb69bd", + "sha256:c5b7bf8fe4d39886adc34311a233a2e01bc10eb4e842220235ed1de57541a896", + "sha256:c67a51ea415192c2e53e4e048c78bab82d21955b4281d297f517707dc836bf3d", + "sha256:ca4fddf84ac7d8a7d0866664936f93318ff01ee33e32381a115b19fb5a4d1202", + "sha256:d5b9345ab92ebe6003ae11d8092ce822a0242146e6fa270889b9ba965457ca40", + "sha256:d97c3e286d0ac9af6223bc132dc4bad6540b37c8d6c0a15fe1e70fb34f9ec411", + "sha256:db04d1de548f7a62d1dd7e7cdf7c22893ee168e22701895067a28a8ed51b3735", + "sha256:dcf71c55ec853826cd70eadb2b6ac62ec577416442ca1e0a97ad875a1b3a0305", + "sha256:de3cc86f4ea8b4c34a6e43a7306c40c1275e52bfa9748d869c6b7d54aa6dad80", + "sha256:deac0a32aec29608eb25d730f4bc5a261a65b6c48ded1ed861d2a1852577c932", + "sha256:e18d92c3e9e22553a73e33784fcb0ed484c9874e9a3e96c16a8d6a1e74a0217b", + "sha256:eb6dfd52063186ac97b4caa25764cdbcdb4b10d97f5c5f66b0fa95052e744eb7", + "sha256:f09960b5bb1017d16c0f9e9f7fc42160a5a49fa1e87a175fd4a2b1a1833ea0af", + "sha256:f1e4f254e9c35d8965d377e065c4a8a55d396fe87c8e7e8429bcfdeeb229bfb3", + "sha256:f32c86dc967ab8c719fd229ce71917caad13cc1e8356ee997bf02c5b368799bf", + "sha256:f50b4663c3e0262c3a361faf440761fbef60ccdde5fe8545689a4b3a3c149fb4", + "sha256:f8e05f5163528962ce1d1806fce763ab893b1c5b7ace0a3538cd81a90622f844", + "sha256:f929f4c9b9a00f3e6cc0587abb95ab9c05681f8b14e0fe1daecfa83ea90f8318", + "sha256:f9e09a1c83521d770d170b3801eea19b89f41ccaa61d53026ed111cb6f088887" ], "index": "pypi", - "version": "==3.8.1" + "version": "==3.9.0" }, "aiosignal": { "hashes": [ - "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a", - "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2" + "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", + "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" ], - "markers": "python_version >= '3.6'", - "version": "==1.2.0" + "markers": "python_version >= '3.7'", + "version": "==1.3.1" }, "async-timeout": { "hashes": [ - "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", - "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" + "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", + "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" ], - "markers": "python_version >= '3.6'", - "version": "==4.0.2" + "markers": "python_version < '3.11'", + "version": "==4.0.3" }, "attrs": { "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" + "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", + "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" + "markers": "python_version >= '3.7'", + "version": "==23.1.0" }, "cairocffi": { "hashes": [ - "sha256:108a3a7cb09e203bdd8501d9baad91d786d204561bd71e9364e8b34897c47b91" + "sha256:78e6bbe47357640c453d0be929fa49cd05cce2e1286f3d2a1ca9cbda7efdb8b7", + "sha256:aa78ee52b9069d7475eeac457389b6275aa92111895d78fbaa2202a52dac112e" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.6.1" }, "cairosvg": { "hashes": [ - "sha256:98c276b7e4f0caf01e5c7176765c104ffa1aa1461d63b2053b04ab663cf7052b", - "sha256:b0b9929cf5dba005178d746a8036fcf0025550f498ca54db61873322384783bc" + "sha256:432531d72347291b9a9ebfb6777026b607563fd8719c46ee742db0aef7271ba0", + "sha256:8a5222d4e6c3f86f1f7046b63246877a63b49923a1cd202184c3a634ef546b3b" ], - "version": "==2.5.2" + "version": "==2.7.1" }, "certifi": { "hashes": [ - "sha256:36973885b9542e6bd01dea287b2b4b3b21236307c56324fcc3f1160f2d655ed5", - "sha256:e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516" + "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", + "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" ], "markers": "python_version >= '3.6'", - "version": "==2022.9.14" + "version": "==2023.11.17" }, "cffi": { "hashes": [ - "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", - "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", - "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", - "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", - "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", - "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", - "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", - "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", - "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", - "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", - "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", - "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", - "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", - "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", - "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", - "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", - "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", - "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", - "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", - "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", - "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", - "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", - "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", - "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", - "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", - "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", - "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", - "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", - "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", - "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", - "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", - "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", - "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", - "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", - "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", - "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", - "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", - "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", - "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", - "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", - "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", - "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", - "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", - "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", - "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", - "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", - "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", - "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", - "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", - "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", - "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", - "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", - "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", - "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", - "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", - "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", - "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", - "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", - "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", - "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", - "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", - "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", - "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", - "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", + "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", + "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", + "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", + "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", + "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", + "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", + "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", + "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", + "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", + "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", + "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", + "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", + "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", + "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", + "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", + "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", + "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", + "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", + "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", + "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", + "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", + "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", + "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", + "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", + "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", + "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", + "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", + "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", + "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", + "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", + "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", + "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", + "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", + "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", + "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", + "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", + "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", + "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", + "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", + "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", + "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", + "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", + "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", + "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", + "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", + "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", + "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", + "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", + "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", + "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", + "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" ], - "version": "==1.15.1" + "markers": "python_version >= '3.8'", + "version": "==1.16.0" }, "charset-normalizer": { "hashes": [ @@ -217,11 +211,11 @@ }, "colorama": { "hashes": [ - "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", - "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" ], "index": "pypi", - "version": "==0.4.5" + "version": "==0.4.6" }, "cssselect2": { "hashes": [ @@ -249,83 +243,86 @@ }, "dnspython": { "hashes": [ - "sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e", - "sha256:a851e51367fb93e9e1361732c1d60dab63eff98712e503ea7d92e6eccb109b4f" + "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8", + "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.2.1" + "version": "==2.4.2" }, "emoji": { "hashes": [ - "sha256:65c54533ea3c78f30d0729288998715f418d7467de89ec258a31c0ce8660a1d1" + "sha256:8d8b5dec3c507444b58890e598fc895fcec022b3f5acb49497c6ccc5208b8b00", + "sha256:a8468fd836b7ecb6d1eac054c9a591701ce0ccd6c6f7779ad71b66f76664df90" ], "index": "pypi", - "version": "==1.7.0" + "version": "==2.8.0" }, "frozenlist": { "hashes": [ - "sha256:022178b277cb9277d7d3b3f2762d294f15e85cd2534047e68a118c2bb0058f3e", - "sha256:086ca1ac0a40e722d6833d4ce74f5bf1aba2c77cbfdc0cd83722ffea6da52a04", - "sha256:0bc75692fb3770cf2b5856a6c2c9de967ca744863c5e89595df64e252e4b3944", - "sha256:0dde791b9b97f189874d654c55c24bf7b6782343e14909c84beebd28b7217845", - "sha256:12607804084d2244a7bd4685c9d0dca5df17a6a926d4f1967aa7978b1028f89f", - "sha256:19127f8dcbc157ccb14c30e6f00392f372ddb64a6ffa7106b26ff2196477ee9f", - "sha256:1b51eb355e7f813bcda00276b0114c4172872dc5fb30e3fea059b9367c18fbcb", - "sha256:1e1cf7bc8cbbe6ce3881863671bac258b7d6bfc3706c600008925fb799a256e2", - "sha256:219a9676e2eae91cb5cc695a78b4cb43d8123e4160441d2b6ce8d2c70c60e2f3", - "sha256:2743bb63095ef306041c8f8ea22bd6e4d91adabf41887b1ad7886c4c1eb43d5f", - "sha256:2af6f7a4e93f5d08ee3f9152bce41a6015b5cf87546cb63872cc19b45476e98a", - "sha256:31b44f1feb3630146cffe56344704b730c33e042ffc78d21f2125a6a91168131", - "sha256:31bf9539284f39ff9398deabf5561c2b0da5bb475590b4e13dd8b268d7a3c5c1", - "sha256:35c3d79b81908579beb1fb4e7fcd802b7b4921f1b66055af2578ff7734711cfa", - "sha256:3a735e4211a04ccfa3f4833547acdf5d2f863bfeb01cfd3edaffbc251f15cec8", - "sha256:42719a8bd3792744c9b523674b752091a7962d0d2d117f0b417a3eba97d1164b", - "sha256:49459f193324fbd6413e8e03bd65789e5198a9fa3095e03f3620dee2f2dabff2", - "sha256:4c0c99e31491a1d92cde8648f2e7ccad0e9abb181f6ac3ddb9fc48b63301808e", - "sha256:52137f0aea43e1993264a5180c467a08a3e372ca9d378244c2d86133f948b26b", - "sha256:526d5f20e954d103b1d47232e3839f3453c02077b74203e43407b962ab131e7b", - "sha256:53b2b45052e7149ee8b96067793db8ecc1ae1111f2f96fe1f88ea5ad5fd92d10", - "sha256:572ce381e9fe027ad5e055f143763637dcbac2542cfe27f1d688846baeef5170", - "sha256:58fb94a01414cddcdc6839807db77ae8057d02ddafc94a42faee6004e46c9ba8", - "sha256:5e77a8bd41e54b05e4fb2708dc6ce28ee70325f8c6f50f3df86a44ecb1d7a19b", - "sha256:5f271c93f001748fc26ddea409241312a75e13466b06c94798d1a341cf0e6989", - "sha256:5f63c308f82a7954bf8263a6e6de0adc67c48a8b484fab18ff87f349af356efd", - "sha256:61d7857950a3139bce035ad0b0945f839532987dfb4c06cfe160254f4d19df03", - "sha256:61e8cb51fba9f1f33887e22488bad1e28dd8325b72425f04517a4d285a04c519", - "sha256:625d8472c67f2d96f9a4302a947f92a7adbc1e20bedb6aff8dbc8ff039ca6189", - "sha256:6e19add867cebfb249b4e7beac382d33215d6d54476bb6be46b01f8cafb4878b", - "sha256:717470bfafbb9d9be624da7780c4296aa7935294bd43a075139c3d55659038ca", - "sha256:74140933d45271c1a1283f708c35187f94e1256079b3c43f0c2267f9db5845ff", - "sha256:74e6b2b456f21fc93ce1aff2b9728049f1464428ee2c9752a4b4f61e98c4db96", - "sha256:9494122bf39da6422b0972c4579e248867b6b1b50c9b05df7e04a3f30b9a413d", - "sha256:94e680aeedc7fd3b892b6fa8395b7b7cc4b344046c065ed4e7a1e390084e8cb5", - "sha256:97d9e00f3ac7c18e685320601f91468ec06c58acc185d18bb8e511f196c8d4b2", - "sha256:9c6ef8014b842f01f5d2b55315f1af5cbfde284eb184075c189fd657c2fd8204", - "sha256:a027f8f723d07c3f21963caa7d585dcc9b089335565dabe9c814b5f70c52705a", - "sha256:a718b427ff781c4f4e975525edb092ee2cdef6a9e7bc49e15063b088961806f8", - "sha256:ab386503f53bbbc64d1ad4b6865bf001414930841a870fc97f1546d4d133f141", - "sha256:ab6fa8c7871877810e1b4e9392c187a60611fbf0226a9e0b11b7b92f5ac72792", - "sha256:b47d64cdd973aede3dd71a9364742c542587db214e63b7529fbb487ed67cddd9", - "sha256:b499c6abe62a7a8d023e2c4b2834fce78a6115856ae95522f2f974139814538c", - "sha256:bbb1a71b1784e68870800b1bc9f3313918edc63dbb8f29fbd2e767ce5821696c", - "sha256:c3b31180b82c519b8926e629bf9f19952c743e089c41380ddca5db556817b221", - "sha256:c56c299602c70bc1bb5d1e75f7d8c007ca40c9d7aebaf6e4ba52925d88ef826d", - "sha256:c92deb5d9acce226a501b77307b3b60b264ca21862bd7d3e0c1f3594022f01bc", - "sha256:cc2f3e368ee5242a2cbe28323a866656006382872c40869b49b265add546703f", - "sha256:d82bed73544e91fb081ab93e3725e45dd8515c675c0e9926b4e1f420a93a6ab9", - "sha256:da1cdfa96425cbe51f8afa43e392366ed0b36ce398f08b60de6b97e3ed4affef", - "sha256:da5ba7b59d954f1f214d352308d1d86994d713b13edd4b24a556bcc43d2ddbc3", - "sha256:e0c8c803f2f8db7217898d11657cb6042b9b0553a997c4a0601f48a691480fab", - "sha256:ee4c5120ddf7d4dd1eaf079af3af7102b56d919fa13ad55600a4e0ebe532779b", - "sha256:eee0c5ecb58296580fc495ac99b003f64f82a74f9576a244d04978a7e97166db", - "sha256:f5abc8b4d0c5b556ed8cd41490b606fe99293175a82b98e652c3f2711b452988", - "sha256:f810e764617b0748b49a731ffaa525d9bb36ff38332411704c2400125af859a6", - "sha256:f89139662cc4e65a4813f4babb9ca9544e42bddb823d2ec434e18dad582543bc", - "sha256:fa47319a10e0a076709644a0efbcaab9e91902c8bd8ef74c6adb19d320f69b83", - "sha256:fabb953ab913dadc1ff9dcc3a7a7d3dc6a92efab3a0373989b8063347f8705be" + "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6", + "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01", + "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251", + "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9", + "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b", + "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87", + "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf", + "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f", + "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0", + "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2", + "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b", + "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc", + "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c", + "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467", + "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9", + "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1", + "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a", + "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79", + "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167", + "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300", + "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf", + "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea", + "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2", + "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab", + "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3", + "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb", + "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087", + "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc", + "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8", + "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62", + "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f", + "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326", + "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c", + "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431", + "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963", + "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7", + "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef", + "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3", + "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956", + "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781", + "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472", + "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc", + "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839", + "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672", + "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3", + "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503", + "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d", + "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8", + "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b", + "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc", + "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f", + "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559", + "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b", + "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95", + "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb", + "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963", + "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919", + "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f", + "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3", + "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", + "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" + "markers": "python_version >= '3.8'", + "version": "==1.4.0" }, "idna": { "hashes": [ @@ -363,68 +360,83 @@ }, "multidict": { "hashes": [ - "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60", - "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c", - "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672", - "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51", - "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032", - "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2", - "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b", - "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80", - "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88", - "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a", - "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d", - "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389", - "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c", - "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9", - "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c", - "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516", - "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b", - "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43", - "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee", - "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227", - "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d", - "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae", - "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7", - "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4", - "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9", - "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f", - "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013", - "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9", - "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e", - "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693", - "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a", - "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15", - "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb", - "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96", - "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87", - "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376", - "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658", - "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0", - "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071", - "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360", - "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc", - "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3", - "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba", - "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8", - "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9", - "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2", - "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3", - "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68", - "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8", - "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d", - "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49", - "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608", - "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57", - "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86", - "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20", - "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293", - "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849", - "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937", - "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d" + "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", + "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", + "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", + "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", + "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", + "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", + "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", + "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", + "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", + "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", + "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", + "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", + "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", + "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", + "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", + "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", + "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", + "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", + "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", + "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", + "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", + "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", + "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", + "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", + "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", + "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", + "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", + "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", + "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", + "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", + "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", + "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", + "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", + "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", + "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", + "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", + "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", + "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", + "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", + "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", + "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", + "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", + "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", + "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", + "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", + "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", + "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", + "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", + "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", + "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", + "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", + "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", + "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", + "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", + "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", + "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", + "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", + "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", + "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", + "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", + "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", + "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", + "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", + "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", + "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", + "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", + "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", + "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", + "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", + "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", + "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", + "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", + "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", + "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" ], "markers": "python_version >= '3.7'", - "version": "==6.0.2" + "version": "==6.0.4" }, "natural": { "hashes": [ @@ -443,69 +455,63 @@ }, "pillow": { "hashes": [ - "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927", - "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14", - "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc", - "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58", - "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60", - "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76", - "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c", - "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac", - "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490", - "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1", - "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f", - "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d", - "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", - "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", - "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", - "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437", - "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", - "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", - "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", - "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8", - "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff", - "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da", - "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004", - "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f", - "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20", - "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d", - "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c", - "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544", - "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9", - "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3", - "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04", - "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c", - "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5", - "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4", - "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb", - "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4", - "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c", - "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467", - "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e", - "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421", - "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b", - "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", - "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", - "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", - "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc", - "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", - "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", - "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", - "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28", - "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0", - "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1", - "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8", - "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd", - "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4", - "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8", - "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f", - "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013", - "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59", - "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc", - "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4" + "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d", + "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de", + "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616", + "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839", + "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099", + "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a", + "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219", + "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106", + "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b", + "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412", + "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b", + "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7", + "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2", + "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7", + "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14", + "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f", + "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27", + "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57", + "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262", + "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28", + "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610", + "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172", + "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273", + "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e", + "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d", + "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818", + "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f", + "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9", + "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01", + "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7", + "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651", + "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312", + "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80", + "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666", + "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061", + "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b", + "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992", + "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593", + "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4", + "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db", + "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba", + "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd", + "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e", + "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212", + "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb", + "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2", + "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34", + "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256", + "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f", + "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2", + "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38", + "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996", + "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", + "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" ], - "markers": "python_version >= '3.7'", - "version": "==9.2.0" + "markers": "python_version >= '3.8'", + "version": "==10.1.0" }, "pycparser": { "hashes": [ @@ -515,121 +521,121 @@ "version": "==2.21" }, "pymongo": { - "extras": [ - "srv" - ], + "extras": [], "hashes": [ - "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", - "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", - "sha256:0a02313e71b7c370c43056f6b16c45effbb2d29a44d24403a3d5ba6ed322fa3f", - "sha256:0a89cadc0062a5e53664dde043f6c097172b8c1c5f0094490095282ff9995a5f", - "sha256:0be605bfb8461384a4cb81e80f51eb5ca1b89851f2d0e69a75458c788a7263a4", - "sha256:0d52a70350ec3dfc39b513df12b03b7f4c8f8ec6873bbf958299999db7b05eb1", - "sha256:0e7a5d0b9077e8c3e57727f797ee8adf12e1d5e7534642230d98980d160d1320", - "sha256:145d78c345a38011497e55aff22c0f8edd40ee676a6810f7e69563d68a125e83", - "sha256:14dee106a10b77224bba5efeeb6aee025aabe88eb87a2b850c46d3ee55bdab4a", - "sha256:176fdca18391e1206c32fb1d8265628a84d28333c20ad19468d91e3e98312cd1", - "sha256:1b4c535f524c9d8c86c3afd71d199025daa070859a2bdaf94a298120b0de16db", - "sha256:1b5cb75d2642ff7db823f509641f143f752c0d1ab03166cafea1e42e50469834", - "sha256:1c6c71e198b36f0f0dfe354f06d3655ecfa30d69493a1da125a9a54668aad652", - "sha256:1c771f1a8b3cd2d697baaf57e9cfa4ae42371cacfbea42ea01d9577c06d92f96", - "sha256:208a61db8b8b647fb5b1ff3b52b4ed6dbced01eac3b61009958adb203596ee99", - "sha256:2157d68f85c28688e8b723bbe70c8013e0aba5570e08c48b3562f74d33fc05c4", - "sha256:2301051701b27aff2cbdf83fae22b7ca883c9563dfd088033267291b46196643", - "sha256:2567885ff0c8c7c0887ba6cefe4ae4af96364a66a7069f924ce0cd12eb971d04", - "sha256:2577b8161eeae4dd376d13100b2137d883c10bb457dd08935f60c9f9d4b5c5f6", - "sha256:27e5ea64332385385b75414888ce9d1a9806be8616d7cef4ef409f4f256c6d06", - "sha256:28bfd5244d32faf3e49b5a8d1fab0631e922c26e8add089312e4be19fb05af50", - "sha256:295a5beaecb7bf054c1c6a28749ed72b19f4d4b61edcd8a0815d892424baf780", - "sha256:2c46a0afef69d61938a6fe32c3afd75b91dec3ab3056085dc72abbeedcc94166", - "sha256:3100a2352bdded6232b385ceda0c0a4624598c517d52c2d8cf014b7abbebd84d", - "sha256:320a1fe403dd83a35709fcf01083d14bc1462e9789b711201349a9158db3a87e", - "sha256:320f8734553c50cffe8a8e1ae36dfc7d7be1941c047489db20a814d2a170d7b5", - "sha256:33ab8c031f788609924e329003088831045f683931932a52a361d4a955b7dce2", - "sha256:3492ae1f97209c66af70e863e6420e6301cecb0a51a5efa701058aa73a8ca29e", - "sha256:351a2efe1c9566c348ad0076f4bf541f4905a0ebe2d271f112f60852575f3c16", - "sha256:3f0ac6e0203bd88863649e6ed9c7cfe53afab304bc8225f2597c4c0a74e4d1f0", - "sha256:3fedad05147b40ff8a93fcd016c421e6c159f149a2a481cfa0b94bfa3e473bab", - "sha256:4294f2c1cd069b793e31c2e6d7ac44b121cf7cedccd03ebcc30f3fc3417b314a", - "sha256:463b974b7f49d65a16ca1435bc1c25a681bb7d630509dd23b2e819ed36da0b7f", - "sha256:4e0a3ea7fd01cf0a36509f320226bd8491e0f448f00b8cb89f601c109f6874e1", - "sha256:514e78d20d8382d5b97f32b20c83d1d0452c302c9a135f0a9022236eb9940fda", - "sha256:517b09b1dd842390a965a896d1327c55dfe78199c9f5840595d40facbcd81854", - "sha256:51d1d061df3995c2332ae78f036492cc188cb3da8ef122caeab3631a67bb477e", - "sha256:5296669bff390135528001b4e48d33a7acaffcd361d98659628ece7f282f11aa", - "sha256:5296e5e69243ffd76bd919854c4da6630ae52e46175c804bc4c0e050d937b705", - "sha256:58db209da08a502ce6948841d522dcec80921d714024354153d00b054571993c", - "sha256:5b779e87300635b8075e8d5cfd4fdf7f46078cd7610c381d956bca5556bb8f97", - "sha256:5cf113a46d81cff0559d57aa66ffa473d57d1a9496f97426318b6b5b14fdec1c", - "sha256:5d20072d81cbfdd8e15e6a0c91fc7e3a4948c71e0adebfc67d3b4bcbe8602711", - "sha256:5d67dbc8da2dac1644d71c1839d12d12aa333e266a9964d5b1a49feed036bc94", - "sha256:5f530f35e1a57d4360eddcbed6945aecdaee2a491cd3f17025e7b5f2eea88ee7", - "sha256:5fdffb0cfeb4dc8646a5381d32ec981ae8472f29c695bf09e8f7a8edb2db12ca", - "sha256:602284e652bb56ca8760f8e88a5280636c5b63d7946fca1c2fe0f83c37dffc64", - "sha256:648fcfd8e019b122b7be0e26830a3a2224d57c3e934f19c1e53a77b8380e6675", - "sha256:64b9122be1c404ce4eb367ad609b590394587a676d84bfed8e03c3ce76d70560", - "sha256:6526933760ee1e6090db808f1690a111ec409699c1990efc96f134d26925c37f", - "sha256:6632b1c63d58cddc72f43ab9f17267354ddce563dd5e11eadabd222dcc808808", - "sha256:6f93dbfa5a461107bc3f5026e0d5180499e13379e9404f07a9f79eb5e9e1303d", - "sha256:71c0db2c313ea8a80825fb61b7826b8015874aec29ee6364ade5cb774fe4511b", - "sha256:71c5c200fd37a5322706080b09c3ec8907cf01c377a7187f354fc9e9e13abc73", - "sha256:7738147cd9dbd6d18d5593b3491b4620e13b61de975fd737283e4ad6c255c273", - "sha256:7a6e4dccae8ef5dd76052647d78f02d5d0ffaff1856277d951666c54aeba3ad2", - "sha256:7b4a9fcd95e978cd3c96cdc2096aa54705266551422cf0883c12a4044def31c6", - "sha256:80710d7591d579442c67a3bc7ae9dcba9ff95ea8414ac98001198d894fc4ff46", - "sha256:81a3ebc33b1367f301d1c8eda57eec4868e951504986d5d3fe437479dcdac5b2", - "sha256:8455176fd1b86de97d859fed4ae0ef867bf998581f584c7a1a591246dfec330f", - "sha256:845b178bd127bb074835d2eac635b980c58ec5e700ebadc8355062df708d5a71", - "sha256:858af7c2ab98f21ed06b642578b769ecfcabe4754648b033168a91536f7beef9", - "sha256:87e18f29bac4a6be76a30e74de9c9005475e27100acf0830679420ce1fd9a6fd", - "sha256:89d7baa847383b9814de640c6f1a8553d125ec65e2761ad146ea2e75a7ad197c", - "sha256:8c7ad5cab282f53b9d78d51504330d1c88c83fbe187e472c07e6908a0293142e", - "sha256:8d92c6bb9174d47c2257528f64645a00bbc6324a9ff45a626192797aff01dc14", - "sha256:9252c991e8176b5a2fa574c5ab9a841679e315f6e576eb7cf0bd958f3e39b0ad", - "sha256:93111fd4e08fa889c126aa8baf5c009a941880a539c87672e04583286517450a", - "sha256:95d15cf81cd2fb926f2a6151a9f94c7aacc102b415e72bc0e040e29332b6731c", - "sha256:9d5b66d457d2c5739c184a777455c8fde7ab3600a56d8bbebecf64f7c55169e1", - "sha256:a055d29f1302892a9389a382bed10a3f77708bcf3e49bfb76f7712fa5f391cc6", - "sha256:a1ba93be779a9b8e5e44f5c133dc1db4313661cead8a2fd27661e6cb8d942ee9", - "sha256:a283425e6a474facd73072d8968812d1d9058490a5781e022ccf8895500b83ce", - "sha256:a351986d6c9006308f163c359ced40f80b6cffb42069f3e569b979829951038d", - "sha256:a766157b195a897c64945d4ff87b050bb0e763bb78f3964e996378621c703b00", - "sha256:a8a3540e21213cb8ce232e68a7d0ee49cdd35194856c50b8bd87eeb572fadd42", - "sha256:a8e0a086dbbee406cc6f603931dfe54d1cb2fba585758e06a2de01037784b737", - "sha256:ab23b0545ec71ea346bf50a5d376d674f56205b729980eaa62cdb7871805014b", - "sha256:b0db9a4691074c347f5d7ee830ab3529bc5ad860939de21c1f9c403daf1eda9a", - "sha256:b1b5be40ebf52c3c67ee547e2c4435ed5bc6352f38d23e394520b686641a6be4", - "sha256:b3e08aef4ea05afbc0a70cd23c13684e7f5e074f02450964ec5cfa1c759d33d2", - "sha256:b7df0d99e189b7027d417d4bfd9b8c53c9c7ed5a0a1495d26a6f547d820eca88", - "sha256:be1f10145f7ea76e3e836fdc5c8429c605675bdcddb0bca9725ee6e26874c00c", - "sha256:bf254a1a95e95fdf4eaa25faa1ea450a6533ed7a997f9f8e49ab971b61ea514d", - "sha256:bfc2d763d05ec7211313a06e8571236017d3e61d5fef97fcf34ec4b36c0b6556", - "sha256:c164eda0be9048f83c24b9b2656900041e069ddf72de81c17d874d0c32f6079f", - "sha256:c22591cff80188dd8543be0b559d0c807f7288bd353dc0bcfe539b4588b3a5cd", - "sha256:c5f83bb59d0ff60c6fdb1f8a7b0288fbc4640b1f0fd56f5ae2387749c35d34e3", - "sha256:c7e8221278e5f9e2b6d3893cfc3a3e46c017161a57bb0e6f244826e4cee97916", - "sha256:c8d6bf6fcd42cde2f02efb8126812a010c297eacefcd090a609639d2aeda6185", - "sha256:c8f7dd025cb0bf19e2f60a64dfc24b513c8330e0cfe4a34ccf941eafd6194d9e", - "sha256:c9d212e2af72d5c8d082775a43eb726520e95bf1c84826440f74225843975136", - "sha256:cebb3d8bcac4a6b48be65ebbc5c9881ed4a738e27bb96c86d9d7580a1fb09e05", - "sha256:d3082e5c4d7b388792124f5e805b469109e58f1ab1eb1fbd8b998e8ab766ffb7", - "sha256:d81047341ab56061aa4b6823c54d4632579c3b16e675089e8f520e9b918a133b", - "sha256:d81299f63dc33cc172c26faf59cc54dd795fc6dd5821a7676cca112a5ee8bbd6", - "sha256:dfa217bf8cf3ff6b30c8e6a89014e0c0e7b50941af787b970060ae5ba04a4ce5", - "sha256:dfec57f15f53d677b8e4535695ff3f37df7f8fe431f2efa8c3c8c4025b53d1eb", - "sha256:e099b79ccf7c40f18b149a64d3d10639980035f9ceb223169dd806ff1bb0d9cc", - "sha256:e1fc4d3985868860b6585376e511bb32403c5ffb58b0ed913496c27fd791deea", - "sha256:e2b4c95c47fb81b19ea77dc1c50d23af3eba87c9628fcc2e03d44124a3d336ea", - "sha256:e4e5d163e6644c2bc84dd9f67bfa89288c23af26983d08fefcc2cbc22f6e57e6", - "sha256:e66b3c9f8b89d4fd58a59c04fdbf10602a17c914fbaaa5e6ea593f1d54b06362", - "sha256:ed7d11330e443aeecab23866055e08a5a536c95d2c25333aeb441af2dbac38d2", - "sha256:f340a2a908644ea6cccd399be0fb308c66e05d2800107345f9f0f0d59e1731c4", - "sha256:f38b35ecd2628bf0267761ed659e48af7e620a7fcccfccf5774e7308fb18325c", - "sha256:f6d5443104f89a840250087863c91484a72f254574848e951d1bdd7d8b2ce7c9", - "sha256:fc2048d13ff427605fea328cbe5369dce549b8c7657b0e22051a5b8831170af6" + "sha256:028175dd8d2979a889153a2308e8e500b3df7d9e3fd1c33ca7fdeadf61cc87a2", + "sha256:02f0e1a75d3bc0e16c7e15daf9c56185642be055e425f3b34888fc6eb1b22401", + "sha256:0665412dce26b2318092a33bd2d2327d487c4490cfcde158d6946d39b1e28d78", + "sha256:09b9d0f5a445c7e0ddcc021b09835aa6556f0166afc498f57dfdd72cdf6f02ad", + "sha256:09de3bfc995ae8cb955abb0c9ae963c134dba1b5622be3bcc527b89b0fd4091c", + "sha256:0e5536994cf2d8488c6fd9dea71df3c4dbb3e0d2ba5e695da06d9142a29a0969", + "sha256:0f2c5a5984599a88d087a15859860579b825098b473d8c843f1979a83d159f2e", + "sha256:1037097708498bdc85f23c8798a5c46c7bce432d77d23608ff14e0d831f1a971", + "sha256:10f0fddc1d63ba3d4a4bffcc7720184c1b7efd570726ad5e2f55818da320239f", + "sha256:12721d926d43d33dd3318e58dce9b0250e8a9c6e1093fa8e09f4805193ff4b43", + "sha256:1410faa51ce835cc1234c99ec42e98ab4f3c6f50d92d86a2d4f6e11c97ee7a4e", + "sha256:16e74b9c2aca2734c7f49f00fe68d6830a30d26df60e2ace7fe40ccb92087b94", + "sha256:172db03182a22e9002157b262c1ea3b0045c73d4ff465adc152ce5b4b0e7b8d4", + "sha256:174fd1000e896d0dfbc7f6d7e6a1992a4868796c7dec31679e38218c78d6a942", + "sha256:1c2c5e2b00e2fadcd590c0b2e293d71215e98ed1cb635cfca2be4998d197e534", + "sha256:1c9d23f62a3fa7523d849c4942acc0d9ff7081ebc00c808ee7cfdc070df0687f", + "sha256:21e61a536ffed84d10376c21c13a6ed1ebefb61989a844952547c229d6aeedf3", + "sha256:222591b828de10ac90064047b5d4916953f38c38b155009c4b8b5e0d33117c2b", + "sha256:2406df90b2335371706c59b7d79e9633b81ed2a7ecd48c1faf8584552bdf2d90", + "sha256:24e954be35ad4537840f20bbc8d75320ae647d3cb4fab12cb8fcd2d55f408e76", + "sha256:26f9cc42a162faa241c82e117ac85734ae9f14343dc2df1c90c6b2181f791b22", + "sha256:28565e3dbd69fe5fe35a210067064dbb6ed5abe997079f653c19c873c3896fe6", + "sha256:2943d739715f265a2983ac43747595b6af3312d0a370614040959fd293763adf", + "sha256:2bfc39276c0e6d07c95bd1088b5003f049e986e089509f7dbd68bb7a4b1e65ac", + "sha256:2dae3b353a10c3767e0aa1c1492f2af388f1012b08117695ab3fd1f219e5814e", + "sha256:2e0854170813238f0c3131050c67cb1fb1ade75c93bf6cd156c1bd9a16095528", + "sha256:30245a8747dc90019a3c9ad9df987e0280a3ea632ad36227cde7d1d8dcba0830", + "sha256:30ed2788a6ec68743e2040ab1d16573d7d9f6e7333e45070ce9268cbc93d148c", + "sha256:32eac95bbb030b2376ffd897376c6f870222a3457f01a9ce466b9057876132f8", + "sha256:34cd48df7e1fc69222f296d8f69e3957eb7c6b5aa0709d3467184880ed7538c0", + "sha256:34dbf5fecf653c152edb75a35a8b15dfdc4549473484ee768aeb12c97983cead", + "sha256:398fb86d374dc351a4abc2e24cd15e5e14b2127f6d90ce0df3fdf2adcc55ac1b", + "sha256:3ad3a3df830f7df7e0856c2bdb54d19f5bf188bd7420985e18643b8e4d2a075f", + "sha256:3b261d593f2563299062733ae003a925420a86ff4ddda68a69097d67204e43f3", + "sha256:3c5cb6c93c94df76a879bad4b89db0104b01806d17c2b803c1316ba50962b6d6", + "sha256:3cfc9bc1e8b5667bc1f3dbe46d2f85b3f24ff7533893bdc1203058012db2c046", + "sha256:4092b660ec720d44d3ca81074280dc25c7a3718df1b6c0fe9fe36ac6ed2833e4", + "sha256:42ba8606492d76e6f9e4c7a458ed4bc712603be393259a52450345f0945da2cf", + "sha256:4a32f3dfcca4a4816373bdb6256c18c78974ebb3430e7da988516cd95b2bd6e4", + "sha256:4a82a1c10f5608e6494913faa169e213d703194bfca0aa710901f303be212414", + "sha256:4bbc0d27dfef7689285e54f2e0a224f0c7cd9d5c46d2638fabad5500b951c92f", + "sha256:4d9ed67c987bf9ac2ac684590ba3d2599cdfb0f331ee3db607f9684469b3b59d", + "sha256:4f6dd55dab77adf60b445c11f426ee5cdfa1b86f6d54cb937bfcbf09572333ab", + "sha256:50a81b2d9f188c7909e0a1084fa969bb92a788076809c437ac1ae80393f46df9", + "sha256:50b99f4d3eee6f03778fe841d6f470e6c18e744dc665156da6da3bc6e65b398d", + "sha256:5136ebe8da6a1604998a8eb96be55935aa5f7129c41cc7bddc400d48e8df43be", + "sha256:570ae3365b23d4fd8c669cb57613b1a90b2757e993588d3370ef90945dbeec4b", + "sha256:5831a377d15a626fbec10890ffebc4c6abcd37e4126737932cd780a171eabdc1", + "sha256:59c98e86c5e861032b71e6e5b65f23e6afaacea6e82483b66f1191a5021a7b4f", + "sha256:5bdeb71a610a7b801416268e500e716d0fe693fb10d809e17f0fb3dac5be5a34", + "sha256:5c1db7d366004d6c699eb08c716a63ae0a3e946d061cbebea65d7ce361950265", + "sha256:61660710b054ae52c8fc10368e91d74719eb05554b631d7f8ca93d21d2bff2e6", + "sha256:644470442beaf969df99c4e00367a817eee05f0bba5d888f1ba6fe97b5e1c102", + "sha256:64ed1a5ce5e5926727eb0f87c698c4d9a7a9f7b0953683a65e9ce2b7cc5f8e91", + "sha256:65a063970e15a4f338f14b820561cf6cdaf2839691ac0adb2474ddff9d0b8b0b", + "sha256:65b6fddf6a7b91da044f202771a38e71bbb9bf42720a406b26b25fe2256e7102", + "sha256:6af0a4b17faf26779d5caee8542a4f2cba040cea27d3bffc476cbc6ccbd4c8ee", + "sha256:70b67390e27e58876853efbb87e43c85252de2515e2887f7dd901b4fa3d21973", + "sha256:7219b1a726ced3bacecabef9bd114529bbb69477901373e800d7d0140baadc95", + "sha256:7593cb1214185a0c5b43b96effc51ce82ddc933298ee36db7dc2bd45d61b4adc", + "sha256:776f90bf2252f90a4ae838e7917638894c6356bef7265f424592e2fd1f577d05", + "sha256:79f777eaf3f5b2c6d81f9ef00d87837001d7063302503bbcbfdbf3e9bc27c96f", + "sha256:7c7cab8155f430ca460a6fc7ae8a705b34f3e279a57adb5f900eb81943ec777c", + "sha256:7cb987b199fa223ad78eebaa9fbc183d5a5944bfe568a9d6f617316ca1c1f32f", + "sha256:7ec2bb598847569ae34292f580842d37619eea3e546005042f485e15710180d5", + "sha256:80d8576b04d0824f63bf803190359c0d3bcb6e7fa63fefbd4bc0ceaa7faae38c", + "sha256:851f2bb52b5cb2f4711171ca925e0e05344a8452972a748a8a8ffdda1e1d72a7", + "sha256:8927f22ef6a16229da7f18944deac8605bdc2c0858be5184259f2f7ce7fd4459", + "sha256:8ad0515abb132f52ce9d8abd1a29681a1e65dba7b7fe13ea01e1a8db5715bf80", + "sha256:8cc37b437cba909bef06499dadd91a39c15c14225e8d8c7870020049f8a549fe", + "sha256:93d4e9a02c17813b34e4bd9f6fbf07310c140c8f74341537c24d07c1cdeb24d1", + "sha256:944249aa83dee314420c37d0f40c30a8f6dc4a3877566017b87062e53af449f4", + "sha256:9b2ed9c3b30f11cd4a3fbfc22167af7987b01b444215c2463265153fe7cf66d6", + "sha256:9c3d07ea19cd2856d9943dce37e75d69ecbb5baf93c3e4c82f73b6075c481292", + "sha256:9f592b202d77923498b32ddc5b376e5fa9ba280d3e16ed56cb8c932fe6d6a478", + "sha256:a149377d1ff766fd618500798d0d94637f66d0ae222bb6d28f41f3e15c626297", + "sha256:a17b81f22398e3e0f72bdf938e98c810286994b2bcc0a125cd5ad8fd4ea54ad7", + "sha256:a424bdedfd84454d2905a861e0d4bb947cc5bd024fdeb3600c1a97d2be0f4255", + "sha256:a6cbb73d9fc2282677e2b7a137d13da987bd0b13abd88ed27bba5534c226db06", + "sha256:a796ef39dadf9d73af05d24937644d386495e43a7d13617aa3651d836da542c8", + "sha256:aa3bca8e76f5c00ed2bb4325e0e383a547d71595926d5275d7c88175aaf7435e", + "sha256:b01ce58eec5edeededf1992d2dce63fb8565e437be12d6f139d75b15614c4d08", + "sha256:b0746d0d4535f56bbaa63a8f6da362f330804d578e66e126b226eebe76c2bf00", + "sha256:b1223b826acbef07a7f5eb9bf37247b0b580119916dca9eae19d92b1290f5855", + "sha256:b5b733694e7df22d5c049581acfc487695a6ff813322318bed8dd66f79978636", + "sha256:b6793baf4639c72a500698a49e9250b293e17ae1faf11ac1699d8141194786fe", + "sha256:b96e0e9d2d48948240b510bac81614458fc10adcd3a93240c2fd96448b4efd35", + "sha256:bc04c92d05c142889c26810a4842273deb42e66411273cab4ad09268fe69ba69", + "sha256:bdd34c57b4da51a7961beb33645646d197e41f8517801dc76b37c1441e7a4e10", + "sha256:c0379447587ee4b8f983ba183202496e86c0358f47c45612619d634d1fcd82bd", + "sha256:c3b70ed82f20d18d22eafc9bda0ea656605071762f7d31f3c5afc35c59d3393b", + "sha256:c7c45a8a1a752002b0a7c81ab3a4c5e3b6f67f9826b16fbe3943f5329f565f24", + "sha256:c8f755ff1f4ab4ca790d1d6d3229006100b301475948021b6b2757822e0d6c97", + "sha256:d1a19d6c5098f1f4e11430cd74621699453cbc534dd7ade9167e582f50814b19", + "sha256:d1ee773fb72ba024e7e3bb6ea8907fe52bccafcb5184aaced6bad995bd30ea20", + "sha256:d42eb29ba314adfd9c11234b4b646f61b0448bf9b00f14db4b317e6e4b947e77", + "sha256:d593d50815771f517d3ac4367ff716e3f3c78edae51d98e1e25791459f8848ff", + "sha256:d7910135f5de1c5c3578e61d6f4b087715b15e365f11d4fa51a9cee92988b2bd", + "sha256:d7c91747ec8dde51440dd594603158cc98abb3f7df84b2ed8a836f138285e4fb", + "sha256:db2e11507fe9cc2a722be21ccc62c1b1295398fe9724c1f14900cdc7166fc0d7", + "sha256:db5b4f8ad8607a3d612da1d4c89a84e4cf5c88f98b46365820d9babe5884ba45", + "sha256:e1956f3338c10308e2f99c2c9ff46ae412035cbcd7aaa76c39ccdb806854a247", + "sha256:e22d6cf5802cd09b674c307cc9e03870b8c37c503ebec3d25b86f2ce8c535dc7", + "sha256:e5161167b3840e9c84c80f2534ea6a099f51749d5673b662a3dd248be17c3208", + "sha256:e5e87c0eb774561c546f979342a8ff36ebee153c60a0b6c6b03ba989ceb9538c", + "sha256:e6f8191a282ef77e526f8f8f63753a437e4aa4bc78f5edd8b6b6ed0eaebd5363", + "sha256:e8f6979664ff477cd61b06bf8aba206df7b2334209815ab3b1019931dab643d6", + "sha256:ea8824ebc9a1a5c8269e8f1e3989b5a6bec876726e2f3c33ebd036cb488277f0", + "sha256:f4175fcdddf764d371ee52ec4505a40facee2533e84abf2953cda86d050cfa1f", + "sha256:fe8194f107f0fa3cabd14e9e809f174eca335993c1db72d1e74e0f496e7afe1f" ], "index": "pypi", - "version": "==3.12.3" + "version": "==3.13.0" }, "python-dateutil": { "hashes": [ @@ -665,55 +671,57 @@ }, "tinycss2": { "hashes": [ - "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf", - "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8" + "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847", + "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627" ], - "markers": "python_version >= '3.6'", - "version": "==1.1.1" + "markers": "python_version >= '3.7'", + "version": "==1.2.1" }, "urllib3": { "hashes": [ - "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", - "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" + "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", + "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", - "version": "==1.26.12" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.18" }, "uvloop": { "hashes": [ - "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d", - "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1", - "sha256:1436c8673c1563422213ac6907789ecb2b070f5939b9cbff9ef7113f2b531595", - "sha256:23609ca361a7fc587031429fa25ad2ed7242941adec948f9d10c045bfecab06b", - "sha256:2a6149e1defac0faf505406259561bc14b034cdf1d4711a3ddcdfbaa8d825a05", - "sha256:2deae0b0fb00a6af41fe60a675cec079615b01d68beb4cc7b722424406b126a8", - "sha256:307958f9fc5c8bb01fad752d1345168c0abc5d62c1b72a4a8c6c06f042b45b20", - "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded", - "sha256:3378eb62c63bf336ae2070599e49089005771cc651c8769aaad72d1bd9385a7c", - "sha256:3d97672dc709fa4447ab83276f344a165075fd9f366a97b712bdd3fee05efae8", - "sha256:3db8de10ed684995a7f34a001f15b374c230f7655ae840964d51496e2f8a8474", - "sha256:3ebeeec6a6641d0adb2ea71dcfb76017602ee2bfd8213e3fcc18d8f699c5104f", - "sha256:45cea33b208971e87a31c17622e4b440cac231766ec11e5d22c76fab3bf9df62", - "sha256:6708f30db9117f115eadc4f125c2a10c1a50d711461699a0cbfaa45b9a78e376", - "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c", - "sha256:6aafa5a78b9e62493539456f8b646f85abc7093dd997f4976bb105537cf2635e", - "sha256:7d37dccc7ae63e61f7b96ee2e19c40f153ba6ce730d8ba4d3b4e9738c1dccc1b", - "sha256:864e1197139d651a76c81757db5eb199db8866e13acb0dfe96e6fc5d1cf45fc4", - "sha256:8887d675a64cfc59f4ecd34382e5b4f0ef4ae1da37ed665adba0c2badf0d6578", - "sha256:8efcadc5a0003d3a6e887ccc1fb44dec25594f117a94e3127954c05cf144d811", - "sha256:9b09e0f0ac29eee0451d71798878eae5a4e6a91aa275e114037b27f7db72702d", - "sha256:a4aee22ece20958888eedbad20e4dbb03c37533e010fb824161b4f05e641f738", - "sha256:a5abddb3558d3f0a78949c750644a67be31e47936042d4f6c888dd6f3c95f4aa", - "sha256:c092a2c1e736086d59ac8e41f9c98f26bbf9b9222a76f21af9dfe949b99b2eb9", - "sha256:c686a47d57ca910a2572fddfe9912819880b8765e2f01dc0dd12a9bf8573e539", - "sha256:cbbe908fda687e39afd6ea2a2f14c2c3e43f2ca88e3a11964b297822358d0e6c", - "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718", - "sha256:dbbaf9da2ee98ee2531e0c780455f2841e4675ff580ecf93fe5c48fe733b5667", - "sha256:f1e507c9ee39c61bfddd79714e4f85900656db1aec4d40c6de55648e85c2799c", - "sha256:ff3d00b70ce95adce264462c930fbaecb29718ba6563db354608f37e49e09024" + "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", + "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", + "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b", + "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", + "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797", + "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5", + "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", + "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d", + "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be", + "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd", + "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", + "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17", + "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", + "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", + "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", + "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", + "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", + "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", + "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", + "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67", + "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", + "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", + "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd", + "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", + "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7", + "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", + "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", + "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", + "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", + "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7", + "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256" ], + "index": "pypi", "markers": "sys_platform != 'win32'", - "version": "==0.17.0" + "version": "==0.19.0" }, "webencodings": { "hashes": [ @@ -724,68 +732,83 @@ }, "yarl": { "hashes": [ - "sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb", - "sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3", - "sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035", - "sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453", - "sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d", - "sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a", - "sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231", - "sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f", - "sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae", - "sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b", - "sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3", - "sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507", - "sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd", - "sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae", - "sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe", - "sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c", - "sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4", - "sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64", - "sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357", - "sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54", - "sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461", - "sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4", - "sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497", - "sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0", - "sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1", - "sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957", - "sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350", - "sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780", - "sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843", - "sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548", - "sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6", - "sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40", - "sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee", - "sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b", - "sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6", - "sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0", - "sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e", - "sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880", - "sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc", - "sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e", - "sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead", - "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28", - "sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf", - "sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd", - "sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae", - "sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0", - "sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0", - "sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae", - "sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda", - "sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546", - "sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802", - "sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be", - "sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07", - "sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936", - "sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272", - "sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc", - "sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a", - "sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28", - "sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b" + "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571", + "sha256:066c163aec9d3d073dc9ffe5dd3ad05069bcb03fcaab8d221290ba99f9f69ee3", + "sha256:13414591ff516e04fcdee8dc051c13fd3db13b673c7a4cb1350e6b2ad9639ad3", + "sha256:149ddea5abf329752ea5051b61bd6c1d979e13fbf122d3a1f9f0c8be6cb6f63c", + "sha256:159d81f22d7a43e6eabc36d7194cb53f2f15f498dbbfa8edc8a3239350f59fe7", + "sha256:1b1bba902cba32cdec51fca038fd53f8beee88b77efc373968d1ed021024cc04", + "sha256:22a94666751778629f1ec4280b08eb11815783c63f52092a5953faf73be24191", + "sha256:2a96c19c52ff442a808c105901d0bdfd2e28575b3d5f82e2f5fd67e20dc5f4ea", + "sha256:2b0738fb871812722a0ac2154be1f049c6223b9f6f22eec352996b69775b36d4", + "sha256:2c315df3293cd521033533d242d15eab26583360b58f7ee5d9565f15fee1bef4", + "sha256:32f1d071b3f362c80f1a7d322bfd7b2d11e33d2adf395cc1dd4df36c9c243095", + "sha256:3458a24e4ea3fd8930e934c129b676c27452e4ebda80fbe47b56d8c6c7a63a9e", + "sha256:38a3928ae37558bc1b559f67410df446d1fbfa87318b124bf5032c31e3447b74", + "sha256:3da8a678ca8b96c8606bbb8bfacd99a12ad5dd288bc6f7979baddd62f71c63ef", + "sha256:494053246b119b041960ddcd20fd76224149cfea8ed8777b687358727911dd33", + "sha256:50f33040f3836e912ed16d212f6cc1efb3231a8a60526a407aeb66c1c1956dde", + "sha256:52a25809fcbecfc63ac9ba0c0fb586f90837f5425edfd1ec9f3372b119585e45", + "sha256:53338749febd28935d55b41bf0bcc79d634881195a39f6b2f767870b72514caf", + "sha256:5415d5a4b080dc9612b1b63cba008db84e908b95848369aa1da3686ae27b6d2b", + "sha256:5610f80cf43b6202e2c33ba3ec2ee0a2884f8f423c8f4f62906731d876ef4fac", + "sha256:566185e8ebc0898b11f8026447eacd02e46226716229cea8db37496c8cdd26e0", + "sha256:56ff08ab5df8429901ebdc5d15941b59f6253393cb5da07b4170beefcf1b2528", + "sha256:59723a029760079b7d991a401386390c4be5bfec1e7dd83e25a6a0881859e716", + "sha256:5fcd436ea16fee7d4207c045b1e340020e58a2597301cfbcfdbe5abd2356c2fb", + "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18", + "sha256:63c48f6cef34e6319a74c727376e95626f84ea091f92c0250a98e53e62c77c72", + "sha256:646d663eb2232d7909e6601f1a9107e66f9791f290a1b3dc7057818fe44fc2b6", + "sha256:662e6016409828ee910f5d9602a2729a8a57d74b163c89a837de3fea050c7582", + "sha256:674ca19cbee4a82c9f54e0d1eee28116e63bc6fd1e96c43031d11cbab8b2afd5", + "sha256:6a5883464143ab3ae9ba68daae8e7c5c95b969462bbe42e2464d60e7e2698368", + "sha256:6e7221580dc1db478464cfeef9b03b95c5852cc22894e418562997df0d074ccc", + "sha256:75df5ef94c3fdc393c6b19d80e6ef1ecc9ae2f4263c09cacb178d871c02a5ba9", + "sha256:783185c75c12a017cc345015ea359cc801c3b29a2966c2655cd12b233bf5a2be", + "sha256:822b30a0f22e588b32d3120f6d41e4ed021806418b4c9f0bc3048b8c8cb3f92a", + "sha256:8288d7cd28f8119b07dd49b7230d6b4562f9b61ee9a4ab02221060d21136be80", + "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8", + "sha256:832b7e711027c114d79dffb92576acd1bd2decc467dec60e1cac96912602d0e6", + "sha256:838162460b3a08987546e881a2bfa573960bb559dfa739e7800ceeec92e64417", + "sha256:83fcc480d7549ccebe9415d96d9263e2d4226798c37ebd18c930fce43dfb9574", + "sha256:84e0b1599334b1e1478db01b756e55937d4614f8654311eb26012091be109d59", + "sha256:891c0e3ec5ec881541f6c5113d8df0315ce5440e244a716b95f2525b7b9f3608", + "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82", + "sha256:8c56986609b057b4839968ba901944af91b8e92f1725d1a2d77cbac6972b9ed1", + "sha256:8ea48e0a2f931064469bdabca50c2f578b565fc446f302a79ba6cc0ee7f384d3", + "sha256:8ec53a0ea2a80c5cd1ab397925f94bff59222aa3cf9c6da938ce05c9ec20428d", + "sha256:95d2ecefbcf4e744ea952d073c6922e72ee650ffc79028eb1e320e732898d7e8", + "sha256:9b3152f2f5677b997ae6c804b73da05a39daa6a9e85a512e0e6823d81cdad7cc", + "sha256:9bf345c3a4f5ba7f766430f97f9cc1320786f19584acc7086491f45524a551ac", + "sha256:a60347f234c2212a9f0361955007fcf4033a75bf600a33c88a0a8e91af77c0e8", + "sha256:a74dcbfe780e62f4b5a062714576f16c2f3493a0394e555ab141bf0d746bb955", + "sha256:a83503934c6273806aed765035716216cc9ab4e0364f7f066227e1aaea90b8d0", + "sha256:ac9bb4c5ce3975aeac288cfcb5061ce60e0d14d92209e780c93954076c7c4367", + "sha256:aff634b15beff8902d1f918012fc2a42e0dbae6f469fce134c8a0dc51ca423bb", + "sha256:b03917871bf859a81ccb180c9a2e6c1e04d2f6a51d953e6a5cdd70c93d4e5a2a", + "sha256:b124e2a6d223b65ba8768d5706d103280914d61f5cae3afbc50fc3dfcc016623", + "sha256:b25322201585c69abc7b0e89e72790469f7dad90d26754717f3310bfe30331c2", + "sha256:b7232f8dfbd225d57340e441d8caf8652a6acd06b389ea2d3222b8bc89cbfca6", + "sha256:b8cc1863402472f16c600e3e93d542b7e7542a540f95c30afd472e8e549fc3f7", + "sha256:b9a4e67ad7b646cd6f0938c7ebfd60e481b7410f574c560e455e938d2da8e0f4", + "sha256:be6b3fdec5c62f2a67cb3f8c6dbf56bbf3f61c0f046f84645cd1ca73532ea051", + "sha256:bf74d08542c3a9ea97bb8f343d4fcbd4d8f91bba5ec9d5d7f792dbe727f88938", + "sha256:c027a6e96ef77d401d8d5a5c8d6bc478e8042f1e448272e8d9752cb0aff8b5c8", + "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9", + "sha256:c1012fa63eb6c032f3ce5d2171c267992ae0c00b9e164efe4d73db818465fac3", + "sha256:c3a53ba34a636a256d767c086ceb111358876e1fb6b50dfc4d3f4951d40133d5", + "sha256:d4e2c6d555e77b37288eaf45b8f60f0737c9efa3452c6c44626a5455aeb250b9", + "sha256:de119f56f3c5f0e2fb4dee508531a32b069a5f2c6e827b272d1e0ff5ac040333", + "sha256:e65610c5792870d45d7b68c677681376fcf9cc1c289f23e8e8b39c1485384185", + "sha256:e9fdc7ac0d42bc3ea78818557fab03af6181e076a2944f43c38684b4b6bed8e3", + "sha256:ee4afac41415d52d53a9833ebae7e32b344be72835bbb589018c9e938045a560", + "sha256:f364d3480bffd3aa566e886587eaca7c8c04d74f6e8933f3f2c996b7f09bee1b", + "sha256:f3b078dbe227f79be488ffcfc7a9edb3409d018e0952cf13f15fd6512847f3f7", + "sha256:f4e2d08f07a3d7d3e12549052eb5ad3eab1c349c53ac51c209a0e5991bbada78", + "sha256:f7a3d8146575e08c29ed1cd287068e6d02f1c7bdff8970db96683b9591b86ee7" ], "markers": "python_version >= '3.7'", - "version": "==1.8.1" + "version": "==1.9.2" } }, "develop": { @@ -799,11 +822,11 @@ }, "bandit": { "hashes": [ - "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2", - "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a" + "sha256:75665181dc1e0096369112541a056c59d1c5f66f9bb74a8d686c3c362b83f549", + "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e" ], "index": "pypi", - "version": "==1.7.4" + "version": "==1.7.5" }, "black": { "hashes": [ @@ -836,86 +859,85 @@ }, "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.3" - }, - "colorama": { - "hashes": [ - "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", - "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" - ], - "index": "pypi", - "version": "==0.4.5" + "version": "==8.1.7" }, "gitdb": { "hashes": [ - "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd", - "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa" + "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", + "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b" ], - "markers": "python_version >= '3.6'", - "version": "==4.0.9" + "markers": "python_version >= '3.7'", + "version": "==4.0.11" }, "gitpython": { "hashes": [ - "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704", - "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d" + "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4", + "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a" ], "markers": "python_version >= '3.7'", - "version": "==3.1.27" + "version": "==3.1.40" }, "isort": { "hashes": [ - "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", - "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" + "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", + "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", - "version": "==5.10.1" + "markers": "python_version >= '3.8'", + "version": "==5.12.0" }, "lazy-object-proxy": { "hashes": [ - "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7", - "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a", - "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c", - "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc", - "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f", - "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09", - "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442", - "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e", - "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029", - "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61", - "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb", - "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0", - "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35", - "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42", - "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1", - "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad", - "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443", - "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd", - "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9", - "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148", - "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38", - "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55", - "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36", - "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a", - "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b", - "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44", - "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6", - "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69", - "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4", - "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84", - "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de", - "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28", - "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c", - "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1", - "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8", - "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b", - "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb" + "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382", + "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82", + "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9", + "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494", + "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46", + "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30", + "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63", + "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4", + "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae", + "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be", + "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701", + "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd", + "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006", + "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a", + "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586", + "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8", + "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821", + "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07", + "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b", + "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171", + "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b", + "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2", + "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7", + "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4", + "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8", + "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e", + "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f", + "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda", + "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4", + "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e", + "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671", + "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11", + "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455", + "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734", + "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb", + "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59" ], - "markers": "python_version >= '3.6'", - "version": "==1.7.1" + "markers": "python_version >= '3.7'", + "version": "==1.9.0" + }, + "markdown-it-py": { + "hashes": [ + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" }, "mccabe": { "hashes": [ @@ -924,36 +946,53 @@ ], "version": "==0.6.1" }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, "mypy-extensions": { "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" ], - "version": "==0.4.3" + "markers": "python_version >= '3.5'", + "version": "==1.0.0" }, "pathspec": { "hashes": [ - "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93", - "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d" + "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", + "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" ], "markers": "python_version >= '3.7'", - "version": "==0.10.1" + "version": "==0.11.2" }, "pbr": { "hashes": [ - "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a", - "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf" + "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda", + "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9" ], "markers": "python_version >= '2.6'", - "version": "==5.10.0" + "version": "==6.0.0" }, "platformdirs": { "hashes": [ - "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", - "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" + "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b", + "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731" + ], + "markers": "python_version >= '3.7'", + "version": "==4.0.0" + }, + "pygments": { + "hashes": [ + "sha256:1b37f1b1e1bff2af52ecaf28cc601e2ef7077000b227a0675da25aef85784bc4", + "sha256:e45a0e74bf9c530f564ca81b8952343be986a29f6afe7f5ad95c5f06b7bdf5e8" ], "markers": "python_version >= '3.7'", - "version": "==2.5.2" + "version": "==2.17.1" }, "pylint": { "hashes": [ @@ -965,73 +1004,91 @@ }, "pyyaml": { "hashes": [ - "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", - "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", - "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", - "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", - "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", - "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", - "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", - "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", - "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", - "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", - "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", - "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", - "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", - "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", - "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", - "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", - "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", - "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", - "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", - "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", - "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", - "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", - "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", - "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", - "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", - "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", - "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", - "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", - "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", - "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", - "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", - "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", - "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", - "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", - "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", - "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", - "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", - "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", - "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", - "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" ], "markers": "python_version >= '3.6'", - "version": "==6.0" + "version": "==6.0.1" }, - "setuptools": { + "rich": { "hashes": [ - "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82", - "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57" + "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", + "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" ], "markers": "python_version >= '3.7'", - "version": "==65.3.0" + "version": "==13.7.0" + }, + "setuptools": { + "hashes": [ + "sha256:4c65d4f7891e5b046e9146913b87098144de2ca2128fbc10135b8556a6ddd946", + "sha256:eb03b43f23910c5fd0909cb677ad017cd9531f493d27f8b3f5316ff1fb07390e" + ], + "markers": "python_version >= '3.8'", + "version": "==69.0.0" }, "smmap": { "hashes": [ - "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", - "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" + "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", + "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" ], - "markers": "python_version >= '3.6'", - "version": "==5.0.0" + "markers": "python_version >= '3.7'", + "version": "==5.0.1" }, "stevedore": { "hashes": [ - "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8", - "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786" + "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d", + "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c" ], "markers": "python_version >= '3.8'", - "version": "==4.0.0" + "version": "==5.1.0" }, "toml": { "hashes": [ diff --git a/bot.py b/bot.py index f36ecc8351..4245ce408b 100644 --- a/bot.py +++ b/bot.py @@ -21,7 +21,7 @@ from aiohttp import ClientSession, ClientResponseError from discord.ext import commands, tasks from discord.ext.commands.view import StringView -from emoji import UNICODE_EMOJI +from emoji import is_emoji from pkg_resources import parse_version @@ -623,11 +623,11 @@ async def convert_emoji(self, name: str) -> str: ctx = SimpleNamespace(bot=self, guild=self.modmail_guild) converter = commands.EmojiConverter() - if name not in UNICODE_EMOJI["en"]: + if not is_emoji(name): try: name = await converter.convert(ctx, name.strip(":")) except commands.BadArgument as e: - logger.warning("%s is not a valid emoji. %s.", name, e) + logger.warning("%s is not a valid emoji: %s", name, e) raise return name From 6fea4b61f1bfc20e2e9fcd9b235a5b39b14bb814 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:38:57 -0800 Subject: [PATCH 655/705] Updated the rest of the dependencies --- .github/workflows/lints.yml | 2 +- Pipfile | 26 +- Pipfile.lock | 490 +++++++++++++++++++----------------- pyproject.toml | 2 +- 4 files changed, 269 insertions(+), 251 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index eaad52221f..b283dff078 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10'] + python-version: ['3.10', '3.11'] name: Python ${{ matrix.python-version }} on ubuntu-latest diff --git a/Pipfile b/Pipfile index f2590a1e2b..95c75285b5 100644 --- a/Pipfile +++ b/Pipfile @@ -4,26 +4,26 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -bandit = "~=1.7.0" -black = "==22.3.0" -pylint = "~=2.9.3" -typing-extensions = "==4.2.0" +bandit = ">=1.7.5" +black = "==23.11.0" +pylint = "==3.0.2" +typing-extensions = "==4.8.0" [packages] aiohttp = "==3.9.0" colorama = "==0.4.6" "discord.py" = "==2.0.1" emoji = "==2.8.0" -isodate = "~=0.6.0" -motor = "==2.5.1" -natural = "~=0.2.0" -parsedatetime = "~=2.6" +isodate = "==0.6.1" +motor = "==3.3.2" +natural = "==0.2.0" # Why is this needed? +parsedatetime = "==2.6" pymongo = {extras = ["srv"], version = "*"} # Required by motor -python-dateutil = "~=2.8.1" -python-dotenv = "==0.20.0" -uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} -lottie = {version = "==0.6.11", extras = ["pdf"]} -requests = "==2.28.1" +python-dateutil = "==2.8.2" +python-dotenv = "==1.0.0" +uvloop = {version = ">=0.19.0", markers = "sys_platform != 'win32'"} +lottie = {version = "==0.7.0", extras = ["pdf"]} +requests = "==2.31.0" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 35808d048b..640ea61ff6 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f28fd3a11b8f1550ba6731a0bc17740966b1fd98d10c1b004d416ca5b1dd3b84" + "sha256": "e883a9f5e7c62e52df23b5a710713897b06264d3a35fd4af2251ef78e7ddc82e" }, "pipfile-spec": 6, "requires": {}, @@ -133,6 +133,7 @@ "sha256:432531d72347291b9a9ebfb6777026b607563fd8719c46ee742db0aef7271ba0", "sha256:8a5222d4e6c3f86f1f7046b63246877a63b49923a1cd202184c3a634ef546b3b" ], + "markers": "python_version >= '3.5'", "version": "==2.7.1" }, "certifi": { @@ -198,16 +199,104 @@ "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" ], - "markers": "python_version >= '3.8'", + "markers": "python_full_version >= '3.8.0'", "version": "==1.16.0" }, "charset-normalizer": { "hashes": [ - "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", - "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" ], - "markers": "python_version >= '3.6'", - "version": "==2.1.1" + "markers": "python_version >= '3.7'", + "version": "==3.3.2" }, "colorama": { "hashes": [ @@ -246,7 +335,7 @@ "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8", "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version < '4.0' and python_full_version >= '3.8.0'", "version": "==2.4.2" }, "emoji": { @@ -321,7 +410,7 @@ "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" ], - "markers": "python_version >= '3.8'", + "markers": "python_full_version >= '3.8.0'", "version": "==1.4.0" }, "idna": { @@ -345,18 +434,18 @@ "pdf" ], "hashes": [ - "sha256:d53e96265887aa9187c7c707fd612b3d52f38da64c81ea82297783efb47f7e3f" + "sha256:a3242f8ba37051fbdd7503ecd168203a08e4af26f17be2ecca08a64af1e7d3c1" ], "index": "pypi", - "version": "==0.6.11" + "version": "==0.7.0" }, "motor": { "hashes": [ - "sha256:663473f4498f955d35db7b6f25651cb165514c247136f368b84419cb7635f6b8", - "sha256:961fdceacaae2c7236c939166f66415be81be8bbb762da528386738de3a0f509" + "sha256:6fe7e6f0c4f430b9e030b9d22549b732f7c2226af3ab71ecc309e4a1b7d19953", + "sha256:d2fc38de15f1c8058f389c1a44a4d4105c0405c48c061cd492a654496f7bc26a" ], "index": "pypi", - "version": "==2.5.1" + "version": "==3.3.2" }, "multidict": { "hashes": [ @@ -510,7 +599,7 @@ "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" ], - "markers": "python_version >= '3.8'", + "markers": "python_full_version >= '3.8.0'", "version": "==10.1.0" }, "pycparser": { @@ -521,121 +610,94 @@ "version": "==2.21" }, "pymongo": { - "extras": [], + "extras": [ + "srv" + ], "hashes": [ - "sha256:028175dd8d2979a889153a2308e8e500b3df7d9e3fd1c33ca7fdeadf61cc87a2", - "sha256:02f0e1a75d3bc0e16c7e15daf9c56185642be055e425f3b34888fc6eb1b22401", - "sha256:0665412dce26b2318092a33bd2d2327d487c4490cfcde158d6946d39b1e28d78", - "sha256:09b9d0f5a445c7e0ddcc021b09835aa6556f0166afc498f57dfdd72cdf6f02ad", - "sha256:09de3bfc995ae8cb955abb0c9ae963c134dba1b5622be3bcc527b89b0fd4091c", - "sha256:0e5536994cf2d8488c6fd9dea71df3c4dbb3e0d2ba5e695da06d9142a29a0969", - "sha256:0f2c5a5984599a88d087a15859860579b825098b473d8c843f1979a83d159f2e", - "sha256:1037097708498bdc85f23c8798a5c46c7bce432d77d23608ff14e0d831f1a971", - "sha256:10f0fddc1d63ba3d4a4bffcc7720184c1b7efd570726ad5e2f55818da320239f", - "sha256:12721d926d43d33dd3318e58dce9b0250e8a9c6e1093fa8e09f4805193ff4b43", - "sha256:1410faa51ce835cc1234c99ec42e98ab4f3c6f50d92d86a2d4f6e11c97ee7a4e", - "sha256:16e74b9c2aca2734c7f49f00fe68d6830a30d26df60e2ace7fe40ccb92087b94", - "sha256:172db03182a22e9002157b262c1ea3b0045c73d4ff465adc152ce5b4b0e7b8d4", - "sha256:174fd1000e896d0dfbc7f6d7e6a1992a4868796c7dec31679e38218c78d6a942", - "sha256:1c2c5e2b00e2fadcd590c0b2e293d71215e98ed1cb635cfca2be4998d197e534", - "sha256:1c9d23f62a3fa7523d849c4942acc0d9ff7081ebc00c808ee7cfdc070df0687f", - "sha256:21e61a536ffed84d10376c21c13a6ed1ebefb61989a844952547c229d6aeedf3", - "sha256:222591b828de10ac90064047b5d4916953f38c38b155009c4b8b5e0d33117c2b", - "sha256:2406df90b2335371706c59b7d79e9633b81ed2a7ecd48c1faf8584552bdf2d90", - "sha256:24e954be35ad4537840f20bbc8d75320ae647d3cb4fab12cb8fcd2d55f408e76", - "sha256:26f9cc42a162faa241c82e117ac85734ae9f14343dc2df1c90c6b2181f791b22", - "sha256:28565e3dbd69fe5fe35a210067064dbb6ed5abe997079f653c19c873c3896fe6", - "sha256:2943d739715f265a2983ac43747595b6af3312d0a370614040959fd293763adf", - "sha256:2bfc39276c0e6d07c95bd1088b5003f049e986e089509f7dbd68bb7a4b1e65ac", - "sha256:2dae3b353a10c3767e0aa1c1492f2af388f1012b08117695ab3fd1f219e5814e", - "sha256:2e0854170813238f0c3131050c67cb1fb1ade75c93bf6cd156c1bd9a16095528", - "sha256:30245a8747dc90019a3c9ad9df987e0280a3ea632ad36227cde7d1d8dcba0830", - "sha256:30ed2788a6ec68743e2040ab1d16573d7d9f6e7333e45070ce9268cbc93d148c", - "sha256:32eac95bbb030b2376ffd897376c6f870222a3457f01a9ce466b9057876132f8", - "sha256:34cd48df7e1fc69222f296d8f69e3957eb7c6b5aa0709d3467184880ed7538c0", - "sha256:34dbf5fecf653c152edb75a35a8b15dfdc4549473484ee768aeb12c97983cead", - "sha256:398fb86d374dc351a4abc2e24cd15e5e14b2127f6d90ce0df3fdf2adcc55ac1b", - "sha256:3ad3a3df830f7df7e0856c2bdb54d19f5bf188bd7420985e18643b8e4d2a075f", - "sha256:3b261d593f2563299062733ae003a925420a86ff4ddda68a69097d67204e43f3", - "sha256:3c5cb6c93c94df76a879bad4b89db0104b01806d17c2b803c1316ba50962b6d6", - "sha256:3cfc9bc1e8b5667bc1f3dbe46d2f85b3f24ff7533893bdc1203058012db2c046", - "sha256:4092b660ec720d44d3ca81074280dc25c7a3718df1b6c0fe9fe36ac6ed2833e4", - "sha256:42ba8606492d76e6f9e4c7a458ed4bc712603be393259a52450345f0945da2cf", - "sha256:4a32f3dfcca4a4816373bdb6256c18c78974ebb3430e7da988516cd95b2bd6e4", - "sha256:4a82a1c10f5608e6494913faa169e213d703194bfca0aa710901f303be212414", - "sha256:4bbc0d27dfef7689285e54f2e0a224f0c7cd9d5c46d2638fabad5500b951c92f", - "sha256:4d9ed67c987bf9ac2ac684590ba3d2599cdfb0f331ee3db607f9684469b3b59d", - "sha256:4f6dd55dab77adf60b445c11f426ee5cdfa1b86f6d54cb937bfcbf09572333ab", - "sha256:50a81b2d9f188c7909e0a1084fa969bb92a788076809c437ac1ae80393f46df9", - "sha256:50b99f4d3eee6f03778fe841d6f470e6c18e744dc665156da6da3bc6e65b398d", - "sha256:5136ebe8da6a1604998a8eb96be55935aa5f7129c41cc7bddc400d48e8df43be", - "sha256:570ae3365b23d4fd8c669cb57613b1a90b2757e993588d3370ef90945dbeec4b", - "sha256:5831a377d15a626fbec10890ffebc4c6abcd37e4126737932cd780a171eabdc1", - "sha256:59c98e86c5e861032b71e6e5b65f23e6afaacea6e82483b66f1191a5021a7b4f", - "sha256:5bdeb71a610a7b801416268e500e716d0fe693fb10d809e17f0fb3dac5be5a34", - "sha256:5c1db7d366004d6c699eb08c716a63ae0a3e946d061cbebea65d7ce361950265", - "sha256:61660710b054ae52c8fc10368e91d74719eb05554b631d7f8ca93d21d2bff2e6", - "sha256:644470442beaf969df99c4e00367a817eee05f0bba5d888f1ba6fe97b5e1c102", - "sha256:64ed1a5ce5e5926727eb0f87c698c4d9a7a9f7b0953683a65e9ce2b7cc5f8e91", - "sha256:65a063970e15a4f338f14b820561cf6cdaf2839691ac0adb2474ddff9d0b8b0b", - "sha256:65b6fddf6a7b91da044f202771a38e71bbb9bf42720a406b26b25fe2256e7102", - "sha256:6af0a4b17faf26779d5caee8542a4f2cba040cea27d3bffc476cbc6ccbd4c8ee", - "sha256:70b67390e27e58876853efbb87e43c85252de2515e2887f7dd901b4fa3d21973", - "sha256:7219b1a726ced3bacecabef9bd114529bbb69477901373e800d7d0140baadc95", - "sha256:7593cb1214185a0c5b43b96effc51ce82ddc933298ee36db7dc2bd45d61b4adc", - "sha256:776f90bf2252f90a4ae838e7917638894c6356bef7265f424592e2fd1f577d05", - "sha256:79f777eaf3f5b2c6d81f9ef00d87837001d7063302503bbcbfdbf3e9bc27c96f", - "sha256:7c7cab8155f430ca460a6fc7ae8a705b34f3e279a57adb5f900eb81943ec777c", - "sha256:7cb987b199fa223ad78eebaa9fbc183d5a5944bfe568a9d6f617316ca1c1f32f", - "sha256:7ec2bb598847569ae34292f580842d37619eea3e546005042f485e15710180d5", - "sha256:80d8576b04d0824f63bf803190359c0d3bcb6e7fa63fefbd4bc0ceaa7faae38c", - "sha256:851f2bb52b5cb2f4711171ca925e0e05344a8452972a748a8a8ffdda1e1d72a7", - "sha256:8927f22ef6a16229da7f18944deac8605bdc2c0858be5184259f2f7ce7fd4459", - "sha256:8ad0515abb132f52ce9d8abd1a29681a1e65dba7b7fe13ea01e1a8db5715bf80", - "sha256:8cc37b437cba909bef06499dadd91a39c15c14225e8d8c7870020049f8a549fe", - "sha256:93d4e9a02c17813b34e4bd9f6fbf07310c140c8f74341537c24d07c1cdeb24d1", - "sha256:944249aa83dee314420c37d0f40c30a8f6dc4a3877566017b87062e53af449f4", - "sha256:9b2ed9c3b30f11cd4a3fbfc22167af7987b01b444215c2463265153fe7cf66d6", - "sha256:9c3d07ea19cd2856d9943dce37e75d69ecbb5baf93c3e4c82f73b6075c481292", - "sha256:9f592b202d77923498b32ddc5b376e5fa9ba280d3e16ed56cb8c932fe6d6a478", - "sha256:a149377d1ff766fd618500798d0d94637f66d0ae222bb6d28f41f3e15c626297", - "sha256:a17b81f22398e3e0f72bdf938e98c810286994b2bcc0a125cd5ad8fd4ea54ad7", - "sha256:a424bdedfd84454d2905a861e0d4bb947cc5bd024fdeb3600c1a97d2be0f4255", - "sha256:a6cbb73d9fc2282677e2b7a137d13da987bd0b13abd88ed27bba5534c226db06", - "sha256:a796ef39dadf9d73af05d24937644d386495e43a7d13617aa3651d836da542c8", - "sha256:aa3bca8e76f5c00ed2bb4325e0e383a547d71595926d5275d7c88175aaf7435e", - "sha256:b01ce58eec5edeededf1992d2dce63fb8565e437be12d6f139d75b15614c4d08", - "sha256:b0746d0d4535f56bbaa63a8f6da362f330804d578e66e126b226eebe76c2bf00", - "sha256:b1223b826acbef07a7f5eb9bf37247b0b580119916dca9eae19d92b1290f5855", - "sha256:b5b733694e7df22d5c049581acfc487695a6ff813322318bed8dd66f79978636", - "sha256:b6793baf4639c72a500698a49e9250b293e17ae1faf11ac1699d8141194786fe", - "sha256:b96e0e9d2d48948240b510bac81614458fc10adcd3a93240c2fd96448b4efd35", - "sha256:bc04c92d05c142889c26810a4842273deb42e66411273cab4ad09268fe69ba69", - "sha256:bdd34c57b4da51a7961beb33645646d197e41f8517801dc76b37c1441e7a4e10", - "sha256:c0379447587ee4b8f983ba183202496e86c0358f47c45612619d634d1fcd82bd", - "sha256:c3b70ed82f20d18d22eafc9bda0ea656605071762f7d31f3c5afc35c59d3393b", - "sha256:c7c45a8a1a752002b0a7c81ab3a4c5e3b6f67f9826b16fbe3943f5329f565f24", - "sha256:c8f755ff1f4ab4ca790d1d6d3229006100b301475948021b6b2757822e0d6c97", - "sha256:d1a19d6c5098f1f4e11430cd74621699453cbc534dd7ade9167e582f50814b19", - "sha256:d1ee773fb72ba024e7e3bb6ea8907fe52bccafcb5184aaced6bad995bd30ea20", - "sha256:d42eb29ba314adfd9c11234b4b646f61b0448bf9b00f14db4b317e6e4b947e77", - "sha256:d593d50815771f517d3ac4367ff716e3f3c78edae51d98e1e25791459f8848ff", - "sha256:d7910135f5de1c5c3578e61d6f4b087715b15e365f11d4fa51a9cee92988b2bd", - "sha256:d7c91747ec8dde51440dd594603158cc98abb3f7df84b2ed8a836f138285e4fb", - "sha256:db2e11507fe9cc2a722be21ccc62c1b1295398fe9724c1f14900cdc7166fc0d7", - "sha256:db5b4f8ad8607a3d612da1d4c89a84e4cf5c88f98b46365820d9babe5884ba45", - "sha256:e1956f3338c10308e2f99c2c9ff46ae412035cbcd7aaa76c39ccdb806854a247", - "sha256:e22d6cf5802cd09b674c307cc9e03870b8c37c503ebec3d25b86f2ce8c535dc7", - "sha256:e5161167b3840e9c84c80f2534ea6a099f51749d5673b662a3dd248be17c3208", - "sha256:e5e87c0eb774561c546f979342a8ff36ebee153c60a0b6c6b03ba989ceb9538c", - "sha256:e6f8191a282ef77e526f8f8f63753a437e4aa4bc78f5edd8b6b6ed0eaebd5363", - "sha256:e8f6979664ff477cd61b06bf8aba206df7b2334209815ab3b1019931dab643d6", - "sha256:ea8824ebc9a1a5c8269e8f1e3989b5a6bec876726e2f3c33ebd036cb488277f0", - "sha256:f4175fcdddf764d371ee52ec4505a40facee2533e84abf2953cda86d050cfa1f", - "sha256:fe8194f107f0fa3cabd14e9e809f174eca335993c1db72d1e74e0f496e7afe1f" + "sha256:014e7049dd019a6663747ca7dae328943e14f7261f7c1381045dfc26a04fa330", + "sha256:055f5c266e2767a88bb585d01137d9c7f778b0195d3dbf4a487ef0638be9b651", + "sha256:05c30fd35cc97f14f354916b45feea535d59060ef867446b5c3c7f9b609dd5dc", + "sha256:0634994b026336195778e5693583c060418d4ab453eff21530422690a97e1ee8", + "sha256:09c7de516b08c57647176b9fc21d929d628e35bcebc7422220c89ae40b62126a", + "sha256:107a234dc55affc5802acb3b6d83cbb8c87355b38a9457fcd8806bdeb8bce161", + "sha256:10a379fb60f1b2406ae57b8899bacfe20567918c8e9d2d545e1b93628fcf2050", + "sha256:128b1485753106c54af481789cdfea12b90a228afca0b11fb3828309a907e10e", + "sha256:1394c4737b325166a65ae7c145af1ebdb9fb153ebedd37cf91d676313e4a67b8", + "sha256:1c63e3a2e8fb815c4b1f738c284a4579897e37c3cfd95fdb199229a1ccfb638a", + "sha256:1e4ed21029d80c4f62605ab16398fe1ce093fff4b5f22d114055e7d9fbc4adb0", + "sha256:1ec71ac633b126c0775ed4604ca8f56c3540f5c21a1220639f299e7a544b55f9", + "sha256:21812453354b151200034750cd30b0140e82ec2a01fd4357390f67714a1bfbde", + "sha256:256c503a75bd71cf7fb9ebf889e7e222d49c6036a48aad5a619f98a0adf0e0d7", + "sha256:2703a9f8f5767986b4f51c259ff452cc837c5a83c8ed5f5361f6e49933743b2f", + "sha256:288c21ab9531b037f7efa4e467b33176bc73a0c27223c141b822ab4a0e66ff2a", + "sha256:2972dd1f1285866aba027eff2f4a2bbf8aa98563c2ced14cb34ee5602b36afdf", + "sha256:2973f113e079fb98515722cd728e1820282721ec9fd52830e4b73cabdbf1eb28", + "sha256:2ca0ba501898b2ec31e6c3acf90c31910944f01d454ad8e489213a156ccf1bda", + "sha256:2d2be5c9c3488fa8a70f83ed925940f488eac2837a996708d98a0e54a861f212", + "sha256:2f8c04277d879146eacda920476e93d520eff8bec6c022ac108cfa6280d84348", + "sha256:325701ae7b56daa5b0692305b7cb505ca50f80a1288abb32ff420a8a209b01ca", + "sha256:3729b8db02063da50eeb3db88a27670d85953afb9a7f14c213ac9e3dca93034b", + "sha256:3919708594b86d0f5cdc713eb6fccd3f9b9532af09ea7a5d843c933825ef56c4", + "sha256:39a1cd5d383b37285641d5a7a86be85274466ae336a61b51117155936529f9b3", + "sha256:3ec6c20385c5a58e16b1ea60c5e4993ea060540671d7d12664f385f2fb32fe79", + "sha256:47aa128be2e66abd9d1a9b0437c62499d812d291f17b55185cb4aa33a5f710a4", + "sha256:49f2af6cf82509b15093ce3569229e0d53c90ad8ae2eef940652d4cf1f81e045", + "sha256:4a0269811661ba93c472c8a60ea82640e838c2eb148d252720a09b5123f2c2fe", + "sha256:518c90bdd6e842c446d01a766b9136fec5ec6cc94f3b8c3f8b4a332786ee6b64", + "sha256:5717a308a703dda2886a5796a07489c698b442f5e409cf7dc2ac93de8d61d764", + "sha256:5802acc012bbb4bce4dff92973dff76482f30ef35dd4cb8ab5b0e06aa8f08c80", + "sha256:5e63146dbdb1eac207464f6e0cfcdb640c9c5ff0f57b754fa96fe252314a1dc6", + "sha256:6695d7136a435c1305b261a9ddb9b3ecec9863e05aab3935b96038145fd3a977", + "sha256:680fa0fc719e1a3dcb81130858368f51d83667d431924d0bcf249644bce8f303", + "sha256:6b18276f14b4b6d92e707ab6db19b938e112bd2f1dc3f9f1a628df58e4fd3f0d", + "sha256:6bafea6061d63059d8bc2ffc545e2f049221c8a4457d236c5cd6a66678673eab", + "sha256:6d6a1b1361f118e7fefa17ae3114e77f10ee1b228b20d50c47c9f351346180c8", + "sha256:747c84f4e690fbe6999c90ac97246c95d31460d890510e4a3fa61b7d2b87aa34", + "sha256:79f41576b3022c2fe9780ae3e44202b2438128a25284a8ddfa038f0785d87019", + "sha256:7b0e6361754ac596cd16bfc6ed49f69ffcd9b60b7bc4bcd3ea65c6a83475e4ff", + "sha256:7e3b0127b260d4abae7b62203c4c7ef0874c901b55155692353db19de4b18bc4", + "sha256:7fc2bb8a74dcfcdd32f89528e38dcbf70a3a6594963d60dc9595e3b35b66e414", + "sha256:806e094e9e85d8badc978af8c95b69c556077f11844655cb8cd2d1758769e521", + "sha256:81dd1308bd5630d2bb5980f00aa163b986b133f1e9ed66c66ce2a5bc3572e891", + "sha256:82e620842e12e8cb4050d2643a81c8149361cd82c0a920fa5a15dc4ca8a4000f", + "sha256:85f2cdc400ee87f5952ebf2a117488f2525a3fb2e23863a8efe3e4ee9e54e4d1", + "sha256:8ab6bcc8e424e07c1d4ba6df96f7fb963bcb48f590b9456de9ebd03b88084fe8", + "sha256:8adf014f2779992eba3b513e060d06f075f0ab2fb3ad956f413a102312f65cdf", + "sha256:9b0f98481ad5dc4cb430a60bbb8869f05505283b9ae1c62bdb65eb5e020ee8e3", + "sha256:9bea9138b0fc6e2218147e9c6ce1ff76ff8e29dc00bb1b64842bd1ca107aee9f", + "sha256:a09bfb51953930e7e838972ddf646c5d5f984992a66d79da6ba7f6a8d8a890cd", + "sha256:a0be99b599da95b7a90a918dd927b20c434bea5e1c9b3efc6a3c6cd67c23f813", + "sha256:a49aca4d961823b2846b739380c847e8964ff7ae0f0a683992b9d926054f0d6d", + "sha256:a4dc1319d0c162919ee7f4ee6face076becae2abbd351cc14f1fe70af5fb20d9", + "sha256:a8273e1abbcff1d7d29cbbb1ea7e57d38be72f1af3c597c854168508b91516c2", + "sha256:a8f7f9feecae53fa18d6a3ea7c75f9e9a1d4d20e5c3f9ce3fba83f07bcc4eee2", + "sha256:ad4f66fbb893b55f96f03020e67dcab49ffde0177c6565ccf9dec4fdf974eb61", + "sha256:af425f323fce1b07755edd783581e7283557296946212f5b1a934441718e7528", + "sha256:b14dd73f595199f4275bed4fb509277470d9b9059310537e3b3daba12b30c157", + "sha256:b4ad70d7cac4ca0c7b31444a0148bd3af01a2662fa12b1ad6f57cd4a04e21766", + "sha256:b80a4ee19b3442c57c38afa978adca546521a8822d663310b63ae2a7d7b13f3a", + "sha256:ba51129fcc510824b6ca6e2ce1c27e3e4d048b6e35d3ae6f7e517bed1b8b25ce", + "sha256:c011bd5ad03cc096f99ffcfdd18a1817354132c1331bed7a837a25226659845f", + "sha256:cc94f9fea17a5af8cf1a343597711a26b0117c0b812550d99934acb89d526ed2", + "sha256:ccd785fafa1c931deff6a7116e9a0d402d59fabe51644b0d0c268295ff847b25", + "sha256:d16a534da0e39785687b7295e2fcf9a339f4a20689024983d11afaa4657f8507", + "sha256:d3077a31633beef77d057c6523f5de7271ddef7bde5e019285b00c0cc9cac1e3", + "sha256:d603edea1ff7408638b2504905c032193b7dcee7af269802dbb35bc8c3310ed5", + "sha256:db082f728160369d9a6ed2e722438291558fc15ce06d0a7d696a8dad735c236b", + "sha256:ddef295aaf80cefb0c1606f1995899efcb17edc6b327eb6589e234e614b87756", + "sha256:e16ade71c93f6814d095d25cd6d28a90d63511ea396bd96e9ffcb886b278baaa", + "sha256:e3db7d833a7c38c317dc95b54e27f1d27012e031b45a7c24e360b53197d5f6e7", + "sha256:e5e193f89f4f8c1fe273f9a6e6df915092c9f2af6db2d1afb8bd53855025c11f", + "sha256:eb438a8bf6b695bf50d57e6a059ff09652a07968b2041178b3744ea785fcef9b", + "sha256:ebf02c32afa6b67e5861a27183dd98ed88419a94a2ab843cc145fb0bafcc5b28", + "sha256:ecd9e1fa97aa11bf67472220285775fa15e896da108f425e55d23d7540a712ce", + "sha256:ef67fedd863ffffd4adfd46d9d992b0f929c7f61a8307366d664d93517f2c78e", + "sha256:f28ae33dc5a0b9cee06e95fd420e42155d83271ab75964baf747ce959cac5f52", + "sha256:fb1c56d891f9e34303c451998ef62ba52659648bb0d75b03c5e4ac223a3342c2", + "sha256:fe03bf25fae4b95d8afe40004a321df644400fdcba4c8e5e1a19c1085b740888" ], "index": "pypi", - "version": "==3.13.0" + "version": "==4.6.0" }, "python-dateutil": { "hashes": [ @@ -647,19 +709,19 @@ }, "python-dotenv": { "hashes": [ - "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f", - "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938" + "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", + "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a" ], "index": "pypi", - "version": "==0.20.0" + "version": "==1.0.0" }, "requests": { "hashes": [ - "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", - "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", - "version": "==2.28.1" + "version": "==2.31.0" }, "six": { "hashes": [ @@ -679,11 +741,11 @@ }, "urllib3": { "hashes": [ - "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", - "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" + "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", + "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.18" + "markers": "python_full_version >= '3.8.0'", + "version": "==2.1.0" }, "uvloop": { "hashes": [ @@ -814,11 +876,11 @@ "develop": { "astroid": { "hashes": [ - "sha256:3975a0bd5373bdce166e60c851cfcbaf21ee96de80ec518c1f4cb3e94c3fb334", - "sha256:ab7f36e8a78b8e54a62028ba6beef7561db4cdb6f2a5009ecc44a6f42b5697ef" + "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca", + "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e" ], - "markers": "python_version ~= '3.6'", - "version": "==2.6.6" + "markers": "python_version >= '3.8'", + "version": "==3.0.1" }, "bandit": { "hashes": [ @@ -830,32 +892,27 @@ }, "black": { "hashes": [ - "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b", - "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176", - "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09", - "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a", - "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015", - "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79", - "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb", - "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20", - "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464", - "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968", - "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82", - "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21", - "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0", - "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265", - "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b", - "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a", - "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72", - "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce", - "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0", - "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a", - "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163", - "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad", - "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d" + "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4", + "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b", + "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f", + "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07", + "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187", + "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6", + "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05", + "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06", + "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e", + "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5", + "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244", + "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f", + "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221", + "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055", + "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479", + "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394", + "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911", + "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142" ], "index": "pypi", - "version": "==22.3.0" + "version": "==23.11.0" }, "click": { "hashes": [ @@ -865,6 +922,14 @@ "markers": "python_version >= '3.7'", "version": "==8.1.7" }, + "dill": { + "hashes": [ + "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e", + "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03" + ], + "markers": "python_version < '3.11'", + "version": "==0.3.7" + }, "gitdb": { "hashes": [ "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", @@ -889,48 +954,6 @@ "markers": "python_version >= '3.8'", "version": "==5.12.0" }, - "lazy-object-proxy": { - "hashes": [ - "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382", - "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82", - "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9", - "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494", - "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46", - "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30", - "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63", - "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4", - "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae", - "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be", - "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701", - "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd", - "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006", - "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a", - "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586", - "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8", - "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821", - "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07", - "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b", - "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171", - "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b", - "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2", - "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7", - "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4", - "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8", - "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e", - "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f", - "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda", - "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4", - "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e", - "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671", - "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11", - "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455", - "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734", - "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb", - "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59" - ], - "markers": "python_version >= '3.7'", - "version": "==1.9.0" - }, "markdown-it-py": { "hashes": [ "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", @@ -941,10 +964,11 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mdurl": { "hashes": [ @@ -962,6 +986,14 @@ "markers": "python_version >= '3.5'", "version": "==1.0.0" }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, "pathspec": { "hashes": [ "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", @@ -996,11 +1028,11 @@ }, "pylint": { "hashes": [ - "sha256:2e1a0eb2e8ab41d6b5dbada87f066492bb1557b12b76c47c2ee8aa8a11186594", - "sha256:8b838c8983ee1904b2de66cce9d0b96649a91901350e956d78f289c3bc87b48e" + "sha256:0d4c286ef6d2f66c8bfb527a7f8a629009e42c99707dec821a03e1b51a4c1496", + "sha256:60ed5f3a9ff8b61839ff0348b3624ceeb9e6c2a92c514d81c9cc273da3b6bcda" ], "index": "pypi", - "version": "==2.9.6" + "version": "==3.0.2" }, "pyyaml": { "hashes": [ @@ -1066,14 +1098,6 @@ "markers": "python_version >= '3.7'", "version": "==13.7.0" }, - "setuptools": { - "hashes": [ - "sha256:4c65d4f7891e5b046e9146913b87098144de2ca2128fbc10135b8556a6ddd946", - "sha256:eb03b43f23910c5fd0909cb677ad017cd9531f493d27f8b3f5316ff1fb07390e" - ], - "markers": "python_version >= '3.8'", - "version": "==69.0.0" - }, "smmap": { "hashes": [ "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", @@ -1090,14 +1114,6 @@ "markers": "python_version >= '3.8'", "version": "==5.1.0" }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, "tomli": { "hashes": [ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", @@ -1106,19 +1122,21 @@ "markers": "python_version < '3.11'", "version": "==2.0.1" }, - "typing-extensions": { + "tomlkit": { "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4", + "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba" ], - "index": "pypi", - "version": "==4.2.0" + "markers": "python_version >= '3.7'", + "version": "==0.12.3" }, - "wrapt": { + "typing-extensions": { "hashes": [ - "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" ], - "version": "==1.12.1" + "index": "pypi", + "version": "==4.8.0" } } } diff --git a/pyproject.toml b/pyproject.toml index 751cc5a75a..389c24e3d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = "110" -target-version = ['py39'] +target-version = ['py310'] include = '\.pyi?$' extend-exclude = ''' ( From 27a16fe3ca3826ed402f64950e2d81148dac9f18 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:45:09 -0800 Subject: [PATCH 656/705] Bump dpy version to 2.3.2 --- Pipfile | 2 +- Pipfile.lock | 40 ++++++++++++++++++++-------------------- bot.py | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Pipfile b/Pipfile index 95c75285b5..a0c9daa37e 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ typing-extensions = "==4.8.0" [packages] aiohttp = "==3.9.0" colorama = "==0.4.6" -"discord.py" = "==2.0.1" +"discord.py" = "==2.3.2" emoji = "==2.8.0" isodate = "==0.6.1" motor = "==3.3.2" diff --git a/Pipfile.lock b/Pipfile.lock index 640ea61ff6..d420515b19 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e883a9f5e7c62e52df23b5a710713897b06264d3a35fd4af2251ef78e7ddc82e" + "sha256": "c1d663437fd62a76081e36be69c204bef95a30908d9eac1f3df8863ccbd4d383" }, "pipfile-spec": 6, "requires": {}, @@ -199,7 +199,7 @@ "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" ], - "markers": "python_full_version >= '3.8.0'", + "markers": "python_version >= '3.8'", "version": "==1.16.0" }, "charset-normalizer": { @@ -324,18 +324,18 @@ }, "discord.py": { "hashes": [ - "sha256:309146476e986cb8faf038cd5d604d4b3834ef15c2d34df697ce5064bf5cd779", - "sha256:aeb186348bf011708b085b2715cf92bbb72c692eb4f59c4c0b488130cc4c4b7e" + "sha256:4560f70f2eddba7e83370ecebd237ac09fbb4980dc66507482b0c0e5b8f76b9c", + "sha256:9da4679fc3cb10c64b388284700dc998663e0e57328283bbfcfc2525ec5960a6" ], "index": "pypi", - "version": "==2.0.1" + "version": "==2.3.2" }, "dnspython": { "hashes": [ "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8", "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984" ], - "markers": "python_version < '4.0' and python_full_version >= '3.8.0'", + "markers": "python_version >= '3.8' and python_version < '4.0'", "version": "==2.4.2" }, "emoji": { @@ -410,7 +410,7 @@ "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" ], - "markers": "python_full_version >= '3.8.0'", + "markers": "python_version >= '3.8'", "version": "==1.4.0" }, "idna": { @@ -599,7 +599,7 @@ "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" ], - "markers": "python_full_version >= '3.8.0'", + "markers": "python_version >= '3.8'", "version": "==10.1.0" }, "pycparser": { @@ -744,7 +744,7 @@ "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" ], - "markers": "python_full_version >= '3.8.0'", + "markers": "python_version >= '3.8'", "version": "==2.1.0" }, "uvloop": { @@ -919,7 +919,7 @@ "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==8.1.7" }, "dill": { @@ -935,7 +935,7 @@ "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==4.0.11" }, "gitpython": { @@ -943,7 +943,7 @@ "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4", "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==3.1.40" }, "isort": { @@ -975,7 +975,7 @@ "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==0.1.2" }, "mypy-extensions": { @@ -991,7 +991,7 @@ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==23.2" }, "pathspec": { @@ -999,7 +999,7 @@ "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==0.11.2" }, "pbr": { @@ -1015,7 +1015,7 @@ "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b", "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==4.0.0" }, "pygments": { @@ -1023,7 +1023,7 @@ "sha256:1b37f1b1e1bff2af52ecaf28cc601e2ef7077000b227a0675da25aef85784bc4", "sha256:e45a0e74bf9c530f564ca81b8952343be986a29f6afe7f5ad95c5f06b7bdf5e8" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==2.17.1" }, "pylint": { @@ -1095,7 +1095,7 @@ "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==13.7.0" }, "smmap": { @@ -1103,7 +1103,7 @@ "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==5.0.1" }, "stevedore": { @@ -1127,7 +1127,7 @@ "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4", "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==0.12.3" }, "typing-extensions": { diff --git a/bot.py b/bot.py index 4245ce408b..49787f5005 100644 --- a/bot.py +++ b/bot.py @@ -1793,7 +1793,7 @@ def main(): sys.exit(0) # check discord version - discord_version = "2.0.1" + discord_version = "2.3.2" if discord.__version__ != discord_version: logger.error( "Dependencies are not updated, run pipenv install. discord.py version expected %s, received %s", From 9464c5db97c5ce134a86333879d31ac06fe255c6 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:02:21 -0800 Subject: [PATCH 657/705] Fixed compat with MissingRequiredArgument requiring additional param --- bot.py | 7 ++++--- cogs/modmail.py | 7 +++---- cogs/utility.py | 9 ++++----- core/thread.py | 5 +++-- core/utils.py | 10 ++++++++++ 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/bot.py b/bot.py index 49787f5005..3a4cc8a3d8 100644 --- a/bot.py +++ b/bot.py @@ -1746,9 +1746,10 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): if force_null: name = "null" - name = new_name = ( - "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" - ) + f"-{author.discriminator}" + name = "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" + if author.discriminator != "0": + name += f"-{author.discriminator}" + new_name = name counter = 1 existed = set(c.name for c in guild.text_channels if c != exclude_channel) diff --git a/cogs/modmail.py b/cogs/modmail.py index 445015e4de..ac9ab65a58 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -3,7 +3,6 @@ from datetime import datetime, timezone from itertools import zip_longest from typing import Optional, Union, List, Tuple, Literal -from types import SimpleNamespace import discord from discord.ext import commands @@ -1164,7 +1163,7 @@ async def logs(self, ctx, *, user: User = None): if not user: thread = ctx.thread if not thread: - raise commands.MissingRequiredArgument(SimpleNamespace(name="member")) + raise commands.MissingRequiredArgument(DummyParam("user")) user = thread.recipient or await self.bot.get_or_fetch_user(thread.id) default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png" @@ -1839,7 +1838,7 @@ async def block( if thread: user_or_role = thread.recipient elif after is None: - raise commands.MissingRequiredArgument(SimpleNamespace(name="user or role")) + raise commands.MissingRequiredArgument(DummyParam("user or role")) else: raise commands.BadArgument(f'User or role "{after.arg}" not found.') @@ -1919,7 +1918,7 @@ async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): if thread: user_or_role = thread.recipient else: - raise commands.MissingRequiredArgument(SimpleNamespace(name="user")) + raise commands.MissingRequiredArgument(DummyParam("user or role")) mention = getattr(user_or_role, "mention", f"`{user_or_role.id}`") name = getattr(user_or_role, "name", f"`{user_or_role.id}`") diff --git a/cogs/utility.py b/cogs/utility.py index 579c4a7e4e..126b6f785f 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -11,7 +11,6 @@ from json import JSONDecodeError, loads from subprocess import PIPE from textwrap import indent -from types import SimpleNamespace from typing import Union import discord @@ -30,7 +29,7 @@ UnseenFormatter, getLogger, ) -from core.utils import trigger_typing, truncate +from core.utils import trigger_typing, truncate, DummyParam from core.paginator import EmbedPaginatorSession, MessagePaginatorSession @@ -522,12 +521,12 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): return await ctx.send(embed=embed) if not message: - raise commands.MissingRequiredArgument(SimpleNamespace(name="message")) + raise commands.MissingRequiredArgument(DummyParam("message")) try: activity_type = ActivityType[activity_type] except KeyError: - raise commands.MissingRequiredArgument(SimpleNamespace(name="activity")) + raise commands.MissingRequiredArgument(DummyParam("activity")) activity, _ = await self.set_presence(activity_type=activity_type, activity_message=message) @@ -572,7 +571,7 @@ async def status(self, ctx, *, status_type: str.lower): try: status = Status[status_type] except KeyError: - raise commands.MissingRequiredArgument(SimpleNamespace(name="status")) + raise commands.MissingRequiredArgument(DummyParam("status")) _, status = await self.set_presence(status=status) diff --git a/core/thread.py b/core/thread.py index 09c5df46ee..0222eb0102 100644 --- a/core/thread.py +++ b/core/thread.py @@ -32,6 +32,7 @@ AcceptButton, DenyButton, ConfirmThreadCreationView, + DummyParam, ) logger = getLogger(__name__) @@ -800,7 +801,7 @@ async def note( self, message: discord.Message, persistent=False, thread_creation=False ) -> discord.Message: if not message.content and not message.attachments: - raise MissingRequiredArgument(SimpleNamespace(name="msg")) + raise MissingRequiredArgument(DummyParam("msg")) msg = await self.send( message, @@ -821,7 +822,7 @@ async def reply( ) -> typing.Tuple[typing.List[discord.Message], discord.Message]: """Returns List[user_dm_msg] and thread_channel_msg""" if not message.content and not message.attachments: - raise MissingRequiredArgument(SimpleNamespace(name="msg")) + raise MissingRequiredArgument(DummyParam("msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): return await message.channel.send( embed=discord.Embed( diff --git a/core/utils.py b/core/utils.py index 0e9f090d12..d5940d1c2b 100644 --- a/core/utils.py +++ b/core/utils.py @@ -42,6 +42,7 @@ "AcceptButton", "DenyButton", "ConfirmThreadCreationView", + "DummyParam", ] @@ -588,3 +589,12 @@ class ConfirmThreadCreationView(discord.ui.View): def __init__(self): super().__init__(timeout=20) self.value = None + + +class DummyParam: + """ + A dummy parameter that can be used for MissingRequiredArgument. + """ + def __init__(self, name): + self.name = name + self.displayed_name = name From ef349e87e62851881a82fc652110f4ec4d7307ef Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:05:47 -0800 Subject: [PATCH 658/705] black format + update changelog --- CHANGELOG.md | 3 +++ core/utils.py | 1 + 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f79f46c491..03f3e09241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s # [UNRELEASED] +Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only supported versions. + ### Fixed - `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) @@ -29,6 +31,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Changed - Repo moved to https://github.com/modmail-dev/modmail. +- Channel name no longer shows `-0` if the user has migrated to the new username system. - Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) - Discord.py internal logging is now enabled by default. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - The confirm-thread-creation dialog now uses buttons instead of reactions. ([PR #3273](https://github.com/modmail-dev/Modmail/pull/3273)) diff --git a/core/utils.py b/core/utils.py index d5940d1c2b..b50ed3d0fc 100644 --- a/core/utils.py +++ b/core/utils.py @@ -595,6 +595,7 @@ class DummyParam: """ A dummy parameter that can be used for MissingRequiredArgument. """ + def __init__(self, name): self.name = name self.displayed_name = name From 7231a5d48aa8273f063b50a1b2bd1bf8f4c547d1 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:06:25 -0800 Subject: [PATCH 659/705] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03f3e09241..d0ca324a29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only suppo ### Internal - Renamed `Bot.log_file_name` to `Bot.log_file_path`. Log files are now created at `temp/logs/modmail.log`. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - `ConfigManager.get` no longer accepts two positional arguments: the `convert` argument is now keyword-only. +- Various dependencies have been updated to their latest versions. # v4.0.2 From 55f9ba89049506cf21abace145d869422234caea Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:13:35 -0800 Subject: [PATCH 660/705] Remove some more discriminator references --- cogs/modmail.py | 12 +++++++----- core/utils.py | 6 +++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index ac9ab65a58..ee27806177 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -729,8 +729,9 @@ def format_log_embeds(self, logs, avatar_url): f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{entry['key']}" ) - username = entry["recipient"]["name"] + "#" - username += entry["recipient"]["discriminator"] + username = entry["recipient"]["name"] + if entry["recipient"]["discriminator"] != "0": + username += "#" + entry["recipient"]["discriminator"] embed = discord.Embed(color=self.bot.main_color, timestamp=created_at) embed.set_author(name=f"{title} - {username}", icon_url=avatar_url, url=log_url) @@ -1855,7 +1856,7 @@ async def block( ) return await ctx.send(embed=embed) - reason = f"by {escape_markdown(ctx.author.name)}#{ctx.author.discriminator}" + reason = f"by {escape_markdown(str(ctx.author))}" if after is not None: if "%" in reason: @@ -2054,11 +2055,12 @@ async def repair(self, ctx): # match username from channel name # username-1234, username-1234_1, username-1234_2 - m = re.match(r"^(.+)-(\d{4})(?:_\d+)?$", ctx.channel.name) + m = re.match(r"^(.+?)(?:-(\d{4}))?(?:_\d+)?$", ctx.channel.name) if m is not None: users = set( filter( - lambda member: member.name == m.group(1) and member.discriminator == m.group(2), + lambda member: member.name == m.group(1) + and (member.discriminator == "0" or member.discriminator == m.group(2)), ctx.guild.members, ) ) diff --git a/core/utils.py b/core/utils.py index b50ed3d0fc..e25bbf2009 100644 --- a/core/utils.py +++ b/core/utils.py @@ -127,7 +127,11 @@ def format_preview(messages: typing.List[typing.Dict[str, typing.Any]]): continue author = message["author"] content = str(message["content"]).replace("\n", " ") - name = author["name"] + "#" + str(author["discriminator"]) + + name = author["name"] + discriminator = str(author["discriminator"]) + if discriminator != "0": + name += "#" + discriminator prefix = "[M]" if author["mod"] else "[R]" out += truncate(f"`{prefix} {name}:` {content}", max=75) + "\n" From 5482e94374da73161b3ba33df25de089f2950cc3 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:19:31 -0800 Subject: [PATCH 661/705] Remove pkg_resources and replaced with packaging, updated requirements.txt --- Pipfile | 1 + Pipfile.lock | 198 ++++++++++++++++++++++++++--------------------- bot.py | 6 +- cogs/plugins.py | 6 +- cogs/utility.py | 11 +-- requirements.txt | 59 +++++++------- 6 files changed, 152 insertions(+), 129 deletions(-) diff --git a/Pipfile b/Pipfile index a0c9daa37e..98e60935be 100644 --- a/Pipfile +++ b/Pipfile @@ -17,6 +17,7 @@ emoji = "==2.8.0" isodate = "==0.6.1" motor = "==3.3.2" natural = "==0.2.0" # Why is this needed? +packaging = "==23.2" parsedatetime = "==2.6" pymongo = {extras = ["srv"], version = "*"} # Required by motor python-dateutil = "==2.8.2" diff --git a/Pipfile.lock b/Pipfile.lock index d420515b19..2892217178 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c1d663437fd62a76081e36be69c204bef95a30908d9eac1f3df8863ccbd4d383" + "sha256": "2744146f249e9fd303c9cba7df1fff03a597cf8a141075c2d4d51ff80efbee7b" }, "pipfile-spec": 6, "requires": {}, @@ -534,6 +534,14 @@ "index": "pypi", "version": "==0.2.0" }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "index": "pypi", + "version": "==23.2" + }, "parsedatetime": { "hashes": [ "sha256:4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455", @@ -794,83 +802,99 @@ }, "yarl": { "hashes": [ - "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571", - "sha256:066c163aec9d3d073dc9ffe5dd3ad05069bcb03fcaab8d221290ba99f9f69ee3", - "sha256:13414591ff516e04fcdee8dc051c13fd3db13b673c7a4cb1350e6b2ad9639ad3", - "sha256:149ddea5abf329752ea5051b61bd6c1d979e13fbf122d3a1f9f0c8be6cb6f63c", - "sha256:159d81f22d7a43e6eabc36d7194cb53f2f15f498dbbfa8edc8a3239350f59fe7", - "sha256:1b1bba902cba32cdec51fca038fd53f8beee88b77efc373968d1ed021024cc04", - "sha256:22a94666751778629f1ec4280b08eb11815783c63f52092a5953faf73be24191", - "sha256:2a96c19c52ff442a808c105901d0bdfd2e28575b3d5f82e2f5fd67e20dc5f4ea", - "sha256:2b0738fb871812722a0ac2154be1f049c6223b9f6f22eec352996b69775b36d4", - "sha256:2c315df3293cd521033533d242d15eab26583360b58f7ee5d9565f15fee1bef4", - "sha256:32f1d071b3f362c80f1a7d322bfd7b2d11e33d2adf395cc1dd4df36c9c243095", - "sha256:3458a24e4ea3fd8930e934c129b676c27452e4ebda80fbe47b56d8c6c7a63a9e", - "sha256:38a3928ae37558bc1b559f67410df446d1fbfa87318b124bf5032c31e3447b74", - "sha256:3da8a678ca8b96c8606bbb8bfacd99a12ad5dd288bc6f7979baddd62f71c63ef", - "sha256:494053246b119b041960ddcd20fd76224149cfea8ed8777b687358727911dd33", - "sha256:50f33040f3836e912ed16d212f6cc1efb3231a8a60526a407aeb66c1c1956dde", - "sha256:52a25809fcbecfc63ac9ba0c0fb586f90837f5425edfd1ec9f3372b119585e45", - "sha256:53338749febd28935d55b41bf0bcc79d634881195a39f6b2f767870b72514caf", - "sha256:5415d5a4b080dc9612b1b63cba008db84e908b95848369aa1da3686ae27b6d2b", - "sha256:5610f80cf43b6202e2c33ba3ec2ee0a2884f8f423c8f4f62906731d876ef4fac", - "sha256:566185e8ebc0898b11f8026447eacd02e46226716229cea8db37496c8cdd26e0", - "sha256:56ff08ab5df8429901ebdc5d15941b59f6253393cb5da07b4170beefcf1b2528", - "sha256:59723a029760079b7d991a401386390c4be5bfec1e7dd83e25a6a0881859e716", - "sha256:5fcd436ea16fee7d4207c045b1e340020e58a2597301cfbcfdbe5abd2356c2fb", - "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18", - "sha256:63c48f6cef34e6319a74c727376e95626f84ea091f92c0250a98e53e62c77c72", - "sha256:646d663eb2232d7909e6601f1a9107e66f9791f290a1b3dc7057818fe44fc2b6", - "sha256:662e6016409828ee910f5d9602a2729a8a57d74b163c89a837de3fea050c7582", - "sha256:674ca19cbee4a82c9f54e0d1eee28116e63bc6fd1e96c43031d11cbab8b2afd5", - "sha256:6a5883464143ab3ae9ba68daae8e7c5c95b969462bbe42e2464d60e7e2698368", - "sha256:6e7221580dc1db478464cfeef9b03b95c5852cc22894e418562997df0d074ccc", - "sha256:75df5ef94c3fdc393c6b19d80e6ef1ecc9ae2f4263c09cacb178d871c02a5ba9", - "sha256:783185c75c12a017cc345015ea359cc801c3b29a2966c2655cd12b233bf5a2be", - "sha256:822b30a0f22e588b32d3120f6d41e4ed021806418b4c9f0bc3048b8c8cb3f92a", - "sha256:8288d7cd28f8119b07dd49b7230d6b4562f9b61ee9a4ab02221060d21136be80", - "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8", - "sha256:832b7e711027c114d79dffb92576acd1bd2decc467dec60e1cac96912602d0e6", - "sha256:838162460b3a08987546e881a2bfa573960bb559dfa739e7800ceeec92e64417", - "sha256:83fcc480d7549ccebe9415d96d9263e2d4226798c37ebd18c930fce43dfb9574", - "sha256:84e0b1599334b1e1478db01b756e55937d4614f8654311eb26012091be109d59", - "sha256:891c0e3ec5ec881541f6c5113d8df0315ce5440e244a716b95f2525b7b9f3608", - "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82", - "sha256:8c56986609b057b4839968ba901944af91b8e92f1725d1a2d77cbac6972b9ed1", - "sha256:8ea48e0a2f931064469bdabca50c2f578b565fc446f302a79ba6cc0ee7f384d3", - "sha256:8ec53a0ea2a80c5cd1ab397925f94bff59222aa3cf9c6da938ce05c9ec20428d", - "sha256:95d2ecefbcf4e744ea952d073c6922e72ee650ffc79028eb1e320e732898d7e8", - "sha256:9b3152f2f5677b997ae6c804b73da05a39daa6a9e85a512e0e6823d81cdad7cc", - "sha256:9bf345c3a4f5ba7f766430f97f9cc1320786f19584acc7086491f45524a551ac", - "sha256:a60347f234c2212a9f0361955007fcf4033a75bf600a33c88a0a8e91af77c0e8", - "sha256:a74dcbfe780e62f4b5a062714576f16c2f3493a0394e555ab141bf0d746bb955", - "sha256:a83503934c6273806aed765035716216cc9ab4e0364f7f066227e1aaea90b8d0", - "sha256:ac9bb4c5ce3975aeac288cfcb5061ce60e0d14d92209e780c93954076c7c4367", - "sha256:aff634b15beff8902d1f918012fc2a42e0dbae6f469fce134c8a0dc51ca423bb", - "sha256:b03917871bf859a81ccb180c9a2e6c1e04d2f6a51d953e6a5cdd70c93d4e5a2a", - "sha256:b124e2a6d223b65ba8768d5706d103280914d61f5cae3afbc50fc3dfcc016623", - "sha256:b25322201585c69abc7b0e89e72790469f7dad90d26754717f3310bfe30331c2", - "sha256:b7232f8dfbd225d57340e441d8caf8652a6acd06b389ea2d3222b8bc89cbfca6", - "sha256:b8cc1863402472f16c600e3e93d542b7e7542a540f95c30afd472e8e549fc3f7", - "sha256:b9a4e67ad7b646cd6f0938c7ebfd60e481b7410f574c560e455e938d2da8e0f4", - "sha256:be6b3fdec5c62f2a67cb3f8c6dbf56bbf3f61c0f046f84645cd1ca73532ea051", - "sha256:bf74d08542c3a9ea97bb8f343d4fcbd4d8f91bba5ec9d5d7f792dbe727f88938", - "sha256:c027a6e96ef77d401d8d5a5c8d6bc478e8042f1e448272e8d9752cb0aff8b5c8", - "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9", - "sha256:c1012fa63eb6c032f3ce5d2171c267992ae0c00b9e164efe4d73db818465fac3", - "sha256:c3a53ba34a636a256d767c086ceb111358876e1fb6b50dfc4d3f4951d40133d5", - "sha256:d4e2c6d555e77b37288eaf45b8f60f0737c9efa3452c6c44626a5455aeb250b9", - "sha256:de119f56f3c5f0e2fb4dee508531a32b069a5f2c6e827b272d1e0ff5ac040333", - "sha256:e65610c5792870d45d7b68c677681376fcf9cc1c289f23e8e8b39c1485384185", - "sha256:e9fdc7ac0d42bc3ea78818557fab03af6181e076a2944f43c38684b4b6bed8e3", - "sha256:ee4afac41415d52d53a9833ebae7e32b344be72835bbb589018c9e938045a560", - "sha256:f364d3480bffd3aa566e886587eaca7c8c04d74f6e8933f3f2c996b7f09bee1b", - "sha256:f3b078dbe227f79be488ffcfc7a9edb3409d018e0952cf13f15fd6512847f3f7", - "sha256:f4e2d08f07a3d7d3e12549052eb5ad3eab1c349c53ac51c209a0e5991bbada78", - "sha256:f7a3d8146575e08c29ed1cd287068e6d02f1c7bdff8970db96683b9591b86ee7" + "sha256:09c19e5f4404574fcfb736efecf75844ffe8610606f3fccc35a1515b8b6712c4", + "sha256:0ab5baaea8450f4a3e241ef17e3d129b2143e38a685036b075976b9c415ea3eb", + "sha256:0d155a092bf0ebf4a9f6f3b7a650dc5d9a5bbb585ef83a52ed36ba46f55cc39d", + "sha256:126638ab961633f0940a06e1c9d59919003ef212a15869708dcb7305f91a6732", + "sha256:1a0a4f3aaa18580038cfa52a7183c8ffbbe7d727fe581300817efc1e96d1b0e9", + "sha256:1d93461e2cf76c4796355494f15ffcb50a3c198cc2d601ad8d6a96219a10c363", + "sha256:26a1a8443091c7fbc17b84a0d9f38de34b8423b459fb853e6c8cdfab0eacf613", + "sha256:271d63396460b6607b588555ea27a1a02b717ca2e3f2cf53bdde4013d7790929", + "sha256:28a108cb92ce6cf867690a962372996ca332d8cda0210c5ad487fe996e76b8bb", + "sha256:29beac86f33d6c7ab1d79bd0213aa7aed2d2f555386856bb3056d5fdd9dab279", + "sha256:2c757f64afe53a422e45e3e399e1e3cf82b7a2f244796ce80d8ca53e16a49b9f", + "sha256:2dad8166d41ebd1f76ce107cf6a31e39801aee3844a54a90af23278b072f1ccf", + "sha256:2dc72e891672343b99db6d497024bf8b985537ad6c393359dc5227ef653b2f17", + "sha256:2f3c8822bc8fb4a347a192dd6a28a25d7f0ea3262e826d7d4ef9cc99cd06d07e", + "sha256:32435d134414e01d937cd9d6cc56e8413a8d4741dea36af5840c7750f04d16ab", + "sha256:3cfa4dbe17b2e6fca1414e9c3bcc216f6930cb18ea7646e7d0d52792ac196808", + "sha256:3d5434b34100b504aabae75f0622ebb85defffe7b64ad8f52b8b30ec6ef6e4b9", + "sha256:4003f380dac50328c85e85416aca6985536812c082387255c35292cb4b41707e", + "sha256:44e91a669c43f03964f672c5a234ae0d7a4d49c9b85d1baa93dec28afa28ffbd", + "sha256:4a14907b597ec55740f63e52d7fee0e9ee09d5b9d57a4f399a7423268e457b57", + "sha256:4ce77d289f8d40905c054b63f29851ecbfd026ef4ba5c371a158cfe6f623663e", + "sha256:4d6d74a97e898c1c2df80339aa423234ad9ea2052f66366cef1e80448798c13d", + "sha256:51382c72dd5377861b573bd55dcf680df54cea84147c8648b15ac507fbef984d", + "sha256:525cd69eff44833b01f8ef39aa33a9cc53a99ff7f9d76a6ef6a9fb758f54d0ff", + "sha256:53ec65f7eee8655bebb1f6f1607760d123c3c115a324b443df4f916383482a67", + "sha256:5f74b015c99a5eac5ae589de27a1201418a5d9d460e89ccb3366015c6153e60a", + "sha256:6280353940f7e5e2efaaabd686193e61351e966cc02f401761c4d87f48c89ea4", + "sha256:632c7aeb99df718765adf58eacb9acb9cbc555e075da849c1378ef4d18bf536a", + "sha256:6465d36381af057d0fab4e0f24ef0e80ba61f03fe43e6eeccbe0056e74aadc70", + "sha256:66a6dbf6ca7d2db03cc61cafe1ee6be838ce0fbc97781881a22a58a7c5efef42", + "sha256:6d350388ba1129bc867c6af1cd17da2b197dff0d2801036d2d7d83c2d771a682", + "sha256:7217234b10c64b52cc39a8d82550342ae2e45be34f5bff02b890b8c452eb48d7", + "sha256:721ee3fc292f0d069a04016ef2c3a25595d48c5b8ddc6029be46f6158d129c92", + "sha256:72a57b41a0920b9a220125081c1e191b88a4cdec13bf9d0649e382a822705c65", + "sha256:73cc83f918b69110813a7d95024266072d987b903a623ecae673d1e71579d566", + "sha256:778df71c8d0c8c9f1b378624b26431ca80041660d7be7c3f724b2c7a6e65d0d6", + "sha256:79e1df60f7c2b148722fb6cafebffe1acd95fd8b5fd77795f56247edaf326752", + "sha256:7c86d0d0919952d05df880a1889a4f0aeb6868e98961c090e335671dea5c0361", + "sha256:7eaf13af79950142ab2bbb8362f8d8d935be9aaf8df1df89c86c3231e4ff238a", + "sha256:828235a2a169160ee73a2fcfb8a000709edf09d7511fccf203465c3d5acc59e4", + "sha256:8535e111a064f3bdd94c0ed443105934d6f005adad68dd13ce50a488a0ad1bf3", + "sha256:88d2c3cc4b2f46d1ba73d81c51ec0e486f59cc51165ea4f789677f91a303a9a7", + "sha256:8a2538806be846ea25e90c28786136932ec385c7ff3bc1148e45125984783dc6", + "sha256:8dab30b21bd6fb17c3f4684868c7e6a9e8468078db00f599fb1c14e324b10fca", + "sha256:8f18a7832ff85dfcd77871fe677b169b1bc60c021978c90c3bb14f727596e0ae", + "sha256:946db4511b2d815979d733ac6a961f47e20a29c297be0d55b6d4b77ee4b298f6", + "sha256:96758e56dceb8a70f8a5cff1e452daaeff07d1cc9f11e9b0c951330f0a2396a7", + "sha256:9a172c3d5447b7da1680a1a2d6ecdf6f87a319d21d52729f45ec938a7006d5d8", + "sha256:9a5211de242754b5e612557bca701f39f8b1a9408dff73c6db623f22d20f470e", + "sha256:9df9a0d4c5624790a0dea2e02e3b1b3c69aed14bcb8650e19606d9df3719e87d", + "sha256:aa4643635f26052401750bd54db911b6342eb1a9ac3e74f0f8b58a25d61dfe41", + "sha256:aed37db837ecb5962469fad448aaae0f0ee94ffce2062cf2eb9aed13328b5196", + "sha256:af52725c7c39b0ee655befbbab5b9a1b209e01bb39128dce0db226a10014aacc", + "sha256:b0b8c06afcf2bac5a50b37f64efbde978b7f9dc88842ce9729c020dc71fae4ce", + "sha256:b61e64b06c3640feab73fa4ff9cb64bd8182de52e5dc13038e01cfe674ebc321", + "sha256:b7831566595fe88ba17ea80e4b61c0eb599f84c85acaa14bf04dd90319a45b90", + "sha256:b8bc5b87a65a4e64bc83385c05145ea901b613d0d3a434d434b55511b6ab0067", + "sha256:b8d51817cf4b8d545963ec65ff06c1b92e5765aa98831678d0e2240b6e9fd281", + "sha256:b9f9cafaf031c34d95c1528c16b2fa07b710e6056b3c4e2e34e9317072da5d1a", + "sha256:bb72d2a94481e7dc7a0c522673db288f31849800d6ce2435317376a345728225", + "sha256:c25ec06e4241e162f5d1f57c370f4078797ade95c9208bd0c60f484834f09c96", + "sha256:c405d482c320a88ab53dcbd98d6d6f32ada074f2d965d6e9bf2d823158fa97de", + "sha256:c4472fe53ebf541113e533971bd8c32728debc4c6d8cc177f2bff31d011ec17e", + "sha256:c4b1efb11a8acd13246ffb0bee888dd0e8eb057f8bf30112e3e21e421eb82d4a", + "sha256:c5f3faeb8100a43adf3e7925d556801d14b5816a0ac9e75e22948e787feec642", + "sha256:c6f034386e5550b5dc8ded90b5e2ff7db21f0f5c7de37b6efc5dac046eb19c10", + "sha256:c99ddaddb2fbe04953b84d1651149a0d85214780e4d0ee824e610ab549d98d92", + "sha256:ca6b66f69e30f6e180d52f14d91ac854b8119553b524e0e28d5291a724f0f423", + "sha256:cccdc02e46d2bd7cb5f38f8cc3d9db0d24951abd082b2f242c9e9f59c0ab2af3", + "sha256:cd49a908cb6d387fc26acee8b7d9fcc9bbf8e1aca890c0b2fdfd706057546080", + "sha256:cf7a4e8de7f1092829caef66fd90eaf3710bc5efd322a816d5677b7664893c93", + "sha256:cfd77e8e5cafba3fb584e0f4b935a59216f352b73d4987be3af51f43a862c403", + "sha256:d34c4f80956227f2686ddea5b3585e109c2733e2d4ef12eb1b8b4e84f09a2ab6", + "sha256:d61a0ca95503867d4d627517bcfdc28a8468c3f1b0b06c626f30dd759d3999fd", + "sha256:d81657b23e0edb84b37167e98aefb04ae16cbc5352770057893bd222cdc6e45f", + "sha256:d92d897cb4b4bf915fbeb5e604c7911021a8456f0964f3b8ebbe7f9188b9eabb", + "sha256:dd318e6b75ca80bff0b22b302f83a8ee41c62b8ac662ddb49f67ec97e799885d", + "sha256:dd952b9c64f3b21aedd09b8fe958e4931864dba69926d8a90c90d36ac4e28c9a", + "sha256:e0e7e83f31e23c5d00ff618045ddc5e916f9e613d33c5a5823bc0b0a0feb522f", + "sha256:e0f17d1df951336a02afc8270c03c0c6e60d1f9996fcbd43a4ce6be81de0bd9d", + "sha256:e2a16ef5fa2382af83bef4a18c1b3bcb4284c4732906aa69422cf09df9c59f1f", + "sha256:e36021db54b8a0475805acc1d6c4bca5d9f52c3825ad29ae2d398a9d530ddb88", + "sha256:e73db54c967eb75037c178a54445c5a4e7461b5203b27c45ef656a81787c0c1b", + "sha256:e741bd48e6a417bdfbae02e088f60018286d6c141639359fb8df017a3b69415a", + "sha256:f7271d6bd8838c49ba8ae647fc06469137e1c161a7ef97d778b72904d9b68696", + "sha256:fc391e3941045fd0987c77484b2799adffd08e4b6735c4ee5f054366a2e1551d", + "sha256:fc94441bcf9cb8c59f51f23193316afefbf3ff858460cb47b5758bf66a14d130", + "sha256:fe34befb8c765b8ce562f0200afda3578f8abb159c76de3ab354c80b72244c41", + "sha256:fe8080b4f25dfc44a86bedd14bc4f9d469dfc6456e6f3c5d9077e81a5fedfba7", + "sha256:ff34cb09a332832d1cf38acd0f604c068665192c6107a439a92abfd8acf90fe2" ], "markers": "python_version >= '3.7'", - "version": "==1.9.2" + "version": "==1.9.3" } }, "develop": { @@ -919,7 +943,7 @@ "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==8.1.7" }, "dill": { @@ -935,7 +959,7 @@ "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==4.0.11" }, "gitpython": { @@ -943,7 +967,7 @@ "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4", "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==3.1.40" }, "isort": { @@ -975,7 +999,7 @@ "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==0.1.2" }, "mypy-extensions": { @@ -991,7 +1015,7 @@ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" ], - "markers": "python_full_version >= '3.7.0'", + "index": "pypi", "version": "==23.2" }, "pathspec": { @@ -999,7 +1023,7 @@ "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==0.11.2" }, "pbr": { @@ -1015,7 +1039,7 @@ "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b", "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==4.0.0" }, "pygments": { @@ -1023,7 +1047,7 @@ "sha256:1b37f1b1e1bff2af52ecaf28cc601e2ef7077000b227a0675da25aef85784bc4", "sha256:e45a0e74bf9c530f564ca81b8952343be986a29f6afe7f5ad95c5f06b7bdf5e8" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==2.17.1" }, "pylint": { @@ -1095,7 +1119,7 @@ "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==13.7.0" }, "smmap": { @@ -1103,7 +1127,7 @@ "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==5.0.1" }, "stevedore": { @@ -1127,7 +1151,7 @@ "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4", "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==0.12.3" }, "typing-extensions": { diff --git a/bot.py b/bot.py index 3a4cc8a3d8..84ddf653a2 100644 --- a/bot.py +++ b/bot.py @@ -22,7 +22,7 @@ from discord.ext import commands, tasks from discord.ext.commands.view import StringView from emoji import is_emoji -from pkg_resources import parse_version +from packaging.version import Version try: @@ -186,7 +186,7 @@ async def load_extensions(self): @property def version(self): - return parse_version(__version__) + return Version(__version__) @property def api(self) -> ApiClient: @@ -1586,7 +1586,7 @@ async def autoupdate(self): changelog = await Changelog.from_url(self) latest = changelog.latest_version - if self.version < parse_version(latest.version): + if self.version < Version(latest.version): error = None data = {} try: diff --git a/cogs/plugins.py b/cogs/plugins.py index d5787956f1..fc6e09f05d 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -16,7 +16,7 @@ import discord from discord.ext import commands -from pkg_resources import parse_version +from packaging.version import Version from core import checks from core.models import PermissionLevel, getLogger @@ -300,7 +300,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if check_version: required_version = details.get("bot_version", False) - if required_version and self.bot.version < parse_version(required_version): + if required_version and self.bot.version < Version(required_version): embed = discord.Embed( description="Your bot's version is too low. " f"This plugin requires version `{required_version}`.", @@ -688,7 +688,7 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N embed.set_footer(text="This plugin is currently loaded.") else: required_version = details.get("bot_version", False) - if required_version and self.bot.version < parse_version(required_version): + if required_version and self.bot.version < Version(required_version): embed.set_footer( text="Your bot is unable to install this plugin, " f"minimum required version is v{required_version}." diff --git a/cogs/utility.py b/cogs/utility.py index 126b6f785f..b892ffc01b 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -14,11 +14,12 @@ from typing import Union import discord -from aiohttp import ClientResponseError from discord.enums import ActivityType, Status from discord.ext import commands, tasks from discord.ext.commands.view import StringView -from pkg_resources import parse_version + +from aiohttp import ClientResponseError +from packaging.version import Version from core import checks, utils from core.changelog import Changelog @@ -341,9 +342,9 @@ async def about(self, ctx): latest = changelog.latest_version if self.bot.version.is_prerelease: - stable = next(filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions)) + stable = next(filter(lambda v: not Version(v.version).is_prerelease, changelog.versions)) footer = f"You are on the prerelease version • the latest version is v{stable.version}." - elif self.bot.version < parse_version(latest.version): + elif self.bot.version < Version(latest.version): footer = f"A newer version is available v{latest.version}." else: footer = "You are up to date with the latest version." @@ -1930,7 +1931,7 @@ async def update(self, ctx, *, flag: str = ""): "(https://github.com/modmail-dev/modmail/blob/master/bot.py#L1)" ) - if self.bot.version >= parse_version(latest.version) and flag.lower() != "force": + if self.bot.version >= Version(latest.version) and flag.lower() != "force": embed = discord.Embed(title="Already up to date", description=desc, color=self.bot.main_color) data = await self.bot.api.get_user_info() diff --git a/requirements.txt b/requirements.txt index 313426315e..3c712a43a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,40 +1,37 @@ -# -# These requirements were autogenerated by pipenv -# To regenerate from the project's Pipfile, run: -# -# pipenv lock --requirements -# - -i https://pypi.org/simple -aiohttp==3.8.1 -aiosignal==1.2.0; python_version >= '3.6' -async-timeout==4.0.2; python_version >= '3.6' -attrs==21.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -cairocffi==1.3.0; python_version >= '3.7' -cairosvg==2.5.2 -cffi==1.15.0 -charset-normalizer==2.0.12; python_version >= '3.5' -colorama==0.4.4 -cssselect2==0.6.0; python_version >= '3.7' +aiohttp==3.9.0 +aiosignal==1.3.1; python_version >= '3.7' +async-timeout==4.0.3; python_version < '3.11' +attrs==23.1.0; python_version >= '3.7' +cairocffi==1.6.1; python_version >= '3.7' +cairosvg==2.7.1; python_version >= '3.5' +certifi==2023.11.17; python_version >= '3.6' +cffi==1.16.0; python_version >= '3.8' +charset-normalizer==3.3.2; python_version >= '3.7' +colorama==0.4.6 +cssselect2==0.7.0; python_version >= '3.7' defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -emoji==1.7.0 -frozenlist==1.3.0; python_version >= '3.7' -discord.py==2.0.1 -idna==3.3; python_version >= '3.5' +discord.py==2.3.2 +dnspython==2.4.2; python_version >= '3.8' and python_version < '4.0' +emoji==2.8.0 +frozenlist==1.4.0; python_version >= '3.8' +idna==3.4; python_version >= '3.5' isodate==0.6.1 -lottie[pdf]==0.6.11 -motor==2.5.1 -multidict==6.0.2; python_version >= '3.7' +lottie[pdf]==0.7.0 +motor==3.3.2 +multidict==6.0.4; python_version >= '3.7' natural==0.2.0 +packaging==23.2 parsedatetime==2.6 -pillow==9.1.0; python_version >= '3.7' +pillow==10.1.0; python_version >= '3.8' pycparser==2.21 -pymongo==3.12.3 +pymongo[srv]==4.6.0 python-dateutil==2.8.2 -python-dotenv==0.20.0 +python-dotenv==1.0.0 +requests==2.31.0 six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -tinycss2==1.1.1; python_version >= '3.6' -uvloop==0.16.0; sys_platform != 'win32' +tinycss2==1.2.1; python_version >= '3.7' +urllib3==2.1.0; python_version >= '3.8' +uvloop==0.19.0; sys_platform != 'win32' webencodings==0.5.1 -yarl==1.7.2; python_version >= '3.6' +yarl==1.9.3; python_version >= '3.7' From 71e6e8737673b8c9d9aa45fa313a6b23e2c381cd Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:28:01 -0800 Subject: [PATCH 662/705] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0ca324a29..6512a29f5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only suppo - `STREAM_LOG_FORMAT` and `FILE_LOG_FORMAT` environment variable to set the log format of the stream and file handlers respectively. Possible options are `json` and `plain` (default). ([PR #3305](https://github.com/modmail-dev/Modmail/pull/3305)) - `LOG_EXPIRATION` environment variable to set the expiration time of logs. ([PR #3257](https://github.com/modmail-dev/Modmail/pull/3257)) - New registry plugins: [`autoreact`](https://github.com/martinbndr/kyb3r-modmail-plugins/tree/master/autoreact) and [`rename`](https://github.com/Nicklaus-s/modmail-plugins/tree/main/rename). +- Improved join/leave message for multiple servers. ### Changed - Repo moved to https://github.com/modmail-dev/modmail. From 048a9d2b823591729ff4e1ed4e3fad9368ee9064 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:30:36 -0800 Subject: [PATCH 663/705] Black reformat code --- core/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/utils.py b/core/utils.py index 8cc91d8130..9f9f572f5a 100644 --- a/core/utils.py +++ b/core/utils.py @@ -154,7 +154,7 @@ def is_image_url(url: str, **kwargs) -> str: """ try: result = parse.urlparse(url) - if result.netloc == 'gyazo.com' and result.scheme in ['http', 'https']: + if result.netloc == "gyazo.com" and result.scheme in ["http", "https"]: # gyazo support url = re.sub( r"(https?://)((?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|%[0-9a-fA-F][0-9a-fA-F])+)", From 3af8dfa4722871b1a20b565fbd92d6669e7fc386 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 21 Nov 2023 07:16:16 -0800 Subject: [PATCH 664/705] Fixed #3315: gif stickers are now rendered correctly, allow bare sticker reply/note --- CHANGELOG.md | 2 ++ core/thread.py | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6512a29f5f..01a03b35b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only supported versions. ### Fixed +- GIF stickers causes the bot to crash. - `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) - Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) @@ -33,6 +34,7 @@ Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only suppo ### Changed - Repo moved to https://github.com/modmail-dev/modmail. - Channel name no longer shows `-0` if the user has migrated to the new username system. +- `?note` and `?reply` now allows you to send a sticker without any message. - Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) - Discord.py internal logging is now enabled by default. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - The confirm-thread-creation dialog now uses buttons instead of reactions. ([PR #3273](https://github.com/modmail-dev/Modmail/pull/3273)) diff --git a/core/thread.py b/core/thread.py index 0222eb0102..646c98a604 100644 --- a/core/thread.py +++ b/core/thread.py @@ -800,7 +800,7 @@ async def edit_dm_message(self, message: discord.Message, content: str) -> None: async def note( self, message: discord.Message, persistent=False, thread_creation=False ) -> discord.Message: - if not message.content and not message.attachments: + if not message.content and not message.attachments and not message.stickers: raise MissingRequiredArgument(DummyParam("msg")) msg = await self.send( @@ -821,7 +821,7 @@ async def reply( self, message: discord.Message, anonymous: bool = False, plain: bool = False ) -> typing.Tuple[typing.List[discord.Message], discord.Message]: """Returns List[user_dm_msg] and thread_channel_msg""" - if not message.content and not message.attachments: + if not message.content and not message.attachments and not message.stickers: raise MissingRequiredArgument(DummyParam("msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): return await message.channel.send( @@ -1020,8 +1020,14 @@ def lottie_to_png(data): return stream.read() for i in message.stickers: - if i.format in (discord.StickerFormatType.png, discord.StickerFormatType.apng): - images.append((i.url, i.name, True)) + if i.format in ( + discord.StickerFormatType.png, + discord.StickerFormatType.apng, + discord.StickerFormatType.gif, + ): + images.append( + (f"https://media.discordapp.net/stickers/{i.id}.{i.format.file_extension}", i.name, True) + ) elif i.format == discord.StickerFormatType.lottie: # save the json lottie representation try: From 35194d81b18883f5d03a8a6098a6aac1e592bba9 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 21 Nov 2023 07:18:31 -0800 Subject: [PATCH 665/705] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01a03b35b5..0ef7e87d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only supported versions. ### Fixed -- GIF stickers causes the bot to crash. +- GIF stickers no longer cause the bot to crash. - `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) - Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) From 62ae63761f492f59300d6694b5ea202bdc71edc3 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:09:03 -0800 Subject: [PATCH 666/705] Use discord[speed] extra --- Pipfile | 2 +- Pipfile.lock | 246 ++++++++++++++++++++++++++++++++++++++++++++--- requirements.txt | 28 +++--- 3 files changed, 251 insertions(+), 25 deletions(-) diff --git a/Pipfile b/Pipfile index 98e60935be..21205b36f5 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ typing-extensions = "==4.8.0" [packages] aiohttp = "==3.9.0" colorama = "==0.4.6" -"discord.py" = "==2.3.2" +"discord.py" = {version = "==2.3.2", extras = ["speed"]} emoji = "==2.8.0" isodate = "==0.6.1" motor = "==3.3.2" diff --git a/Pipfile.lock b/Pipfile.lock index 2892217178..5f07c7b131 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2744146f249e9fd303c9cba7df1fff03a597cf8a141075c2d4d51ff80efbee7b" + "sha256": "7fee393ea9ea4c0b923033f0da0fdc590ba3f75c6072812062cdc458b84bf9ae" }, "pipfile-spec": 6, "requires": {}, @@ -14,6 +14,13 @@ ] }, "default": { + "aiodns": { + "hashes": [ + "sha256:1073eac48185f7a4150cad7f96a5192d6911f12b4fb894de80a088508c9b3a99", + "sha256:a387b63da4ced6aad35b1dda2d09620ad608a1c7c0fb71efa07ebb4cd511928d" + ], + "version": "==3.1.1" + }, "aiohttp": { "hashes": [ "sha256:05857848da443c8c12110d99285d499b4e84d59918a21132e45c3f0804876994", @@ -94,6 +101,7 @@ "sha256:f9e09a1c83521d770d170b3801eea19b89f41ccaa61d53026ed111cb6f088887" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==3.9.0" }, "aiosignal": { @@ -120,6 +128,94 @@ "markers": "python_version >= '3.7'", "version": "==23.1.0" }, + "brotli": { + "hashes": [ + "sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208", + "sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48", + "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354", + "sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a", + "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128", + "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c", + "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088", + "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9", + "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a", + "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3", + "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438", + "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578", + "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b", + "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b", + "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68", + "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d", + "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd", + "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409", + "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da", + "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50", + "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0", + "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180", + "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d", + "sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112", + "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc", + "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265", + "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327", + "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95", + "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd", + "sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914", + "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0", + "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a", + "sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7", + "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0", + "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451", + "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f", + "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e", + "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248", + "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91", + "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", + "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966", + "sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97", + "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d", + "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf", + "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac", + "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951", + "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74", + "sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60", + "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c", + "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1", + "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8", + "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d", + "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc", + "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61", + "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460", + "sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751", + "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9", + "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1", + "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474", + "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2", + "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6", + "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9", + "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2", + "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467", + "sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619", + "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf", + "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408", + "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579", + "sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84", + "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b", + "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59", + "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752", + "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80", + "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0", + "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2", + "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3", + "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64", + "sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643", + "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e", + "sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985", + "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596", + "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2", + "sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064" + ], + "version": "==1.1.0" + }, "cairocffi": { "hashes": [ "sha256:78e6bbe47357640c453d0be929fa49cd05cce2e1286f3d2a1ca9cbda7efdb8b7", @@ -295,7 +391,7 @@ "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==3.3.2" }, "colorama": { @@ -304,6 +400,7 @@ "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", "version": "==0.4.6" }, "cssselect2": { @@ -323,11 +420,14 @@ "version": "==0.7.1" }, "discord.py": { + "extras": [ + "speed" + ], "hashes": [ "sha256:4560f70f2eddba7e83370ecebd237ac09fbb4980dc66507482b0c0e5b8f76b9c", "sha256:9da4679fc3cb10c64b388284700dc998663e0e57328283bbfcfc2525ec5960a6" ], - "index": "pypi", + "markers": "python_full_version >= '3.8.0'", "version": "==2.3.2" }, "dnspython": { @@ -344,6 +444,7 @@ "sha256:a8468fd836b7ecb6d1eac054c9a591701ce0ccd6c6f7779ad71b66f76664df90" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.8.0" }, "frozenlist": { @@ -436,7 +537,7 @@ "hashes": [ "sha256:a3242f8ba37051fbdd7503ecd168203a08e4af26f17be2ecca08a64af1e7d3c1" ], - "index": "pypi", + "markers": "python_version >= '3'", "version": "==0.7.0" }, "motor": { @@ -445,6 +546,7 @@ "sha256:d2fc38de15f1c8058f389c1a44a4d4105c0405c48c061cd492a654496f7bc26a" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==3.3.2" }, "multidict": { @@ -534,12 +636,68 @@ "index": "pypi", "version": "==0.2.0" }, + "orjson": { + "hashes": [ + "sha256:06ad5543217e0e46fd7ab7ea45d506c76f878b87b1b4e369006bdb01acc05a83", + "sha256:0a73160e823151f33cdc05fe2cea557c5ef12fdf276ce29bb4f1c571c8368a60", + "sha256:1234dc92d011d3554d929b6cf058ac4a24d188d97be5e04355f1b9223e98bbe9", + "sha256:1d0dc4310da8b5f6415949bd5ef937e60aeb0eb6b16f95041b5e43e6200821fb", + "sha256:2a11b4b1a8415f105d989876a19b173f6cdc89ca13855ccc67c18efbd7cbd1f8", + "sha256:2e2ecd1d349e62e3960695214f40939bbfdcaeaaa62ccc638f8e651cf0970e5f", + "sha256:3a2ce5ea4f71681623f04e2b7dadede3c7435dfb5e5e2d1d0ec25b35530e277b", + "sha256:3e892621434392199efb54e69edfff9f699f6cc36dd9553c5bf796058b14b20d", + "sha256:3fb205ab52a2e30354640780ce4587157a9563a68c9beaf52153e1cea9aa0921", + "sha256:4689270c35d4bb3102e103ac43c3f0b76b169760aff8bcf2d401a3e0e58cdb7f", + "sha256:49f8ad582da6e8d2cf663c4ba5bf9f83cc052570a3a767487fec6af839b0e777", + "sha256:4bd176f528a8151a6efc5359b853ba3cc0e82d4cd1fab9c1300c5d957dc8f48c", + "sha256:4cf7837c3b11a2dfb589f8530b3cff2bd0307ace4c301e8997e95c7468c1378e", + "sha256:4fd72fab7bddce46c6826994ce1e7de145ae1e9e106ebb8eb9ce1393ca01444d", + "sha256:5148bab4d71f58948c7c39d12b14a9005b6ab35a0bdf317a8ade9a9e4d9d0bd5", + "sha256:5869e8e130e99687d9e4be835116c4ebd83ca92e52e55810962446d841aba8de", + "sha256:602a8001bdf60e1a7d544be29c82560a7b49319a0b31d62586548835bbe2c862", + "sha256:61804231099214e2f84998316f3238c4c2c4aaec302df12b21a64d72e2a135c7", + "sha256:666c6fdcaac1f13eb982b649e1c311c08d7097cbda24f32612dae43648d8db8d", + "sha256:674eb520f02422546c40401f4efaf8207b5e29e420c17051cddf6c02783ff5ca", + "sha256:7ec960b1b942ee3c69323b8721df2a3ce28ff40e7ca47873ae35bfafeb4555ca", + "sha256:7f433be3b3f4c66016d5a20e5b4444ef833a1f802ced13a2d852c637f69729c1", + "sha256:7f8fb7f5ecf4f6355683ac6881fd64b5bb2b8a60e3ccde6ff799e48791d8f864", + "sha256:81a3a3a72c9811b56adf8bcc829b010163bb2fc308877e50e9910c9357e78521", + "sha256:858379cbb08d84fe7583231077d9a36a1a20eb72f8c9076a45df8b083724ad1d", + "sha256:8b9ba0ccd5a7f4219e67fbbe25e6b4a46ceef783c42af7dbc1da548eb28b6531", + "sha256:92af0d00091e744587221e79f68d617b432425a7e59328ca4c496f774a356071", + "sha256:9ebbdbd6a046c304b1845e96fbcc5559cd296b4dfd3ad2509e33c4d9ce07d6a1", + "sha256:9edd2856611e5050004f4722922b7b1cd6268da34102667bd49d2a2b18bafb81", + "sha256:a353bf1f565ed27ba71a419b2cd3db9d6151da426b61b289b6ba1422a702e643", + "sha256:b5b7d4a44cc0e6ff98da5d56cde794385bdd212a86563ac321ca64d7f80c80d1", + "sha256:b90f340cb6397ec7a854157fac03f0c82b744abdd1c0941a024c3c29d1340aff", + "sha256:c18a4da2f50050a03d1da5317388ef84a16013302a5281d6f64e4a3f406aabc4", + "sha256:c338ed69ad0b8f8f8920c13f529889fe0771abbb46550013e3c3d01e5174deef", + "sha256:c5a02360e73e7208a872bf65a7554c9f15df5fe063dc047f79738998b0506a14", + "sha256:c62b6fa2961a1dcc51ebe88771be5319a93fd89bd247c9ddf732bc250507bc2b", + "sha256:c812312847867b6335cfb264772f2a7e85b3b502d3a6b0586aa35e1858528ab1", + "sha256:c943b35ecdf7123b2d81d225397efddf0bce2e81db2f3ae633ead38e85cd5ade", + "sha256:ce0a29c28dfb8eccd0f16219360530bc3cfdf6bf70ca384dacd36e6c650ef8e8", + "sha256:cf80b550092cc480a0cbd0750e8189247ff45457e5a023305f7ef1bcec811616", + "sha256:cff7570d492bcf4b64cc862a6e2fb77edd5e5748ad715f487628f102815165e9", + "sha256:d2c1e559d96a7f94a4f581e2a32d6d610df5840881a8cba8f25e446f4d792df3", + "sha256:deeb3922a7a804755bbe6b5be9b312e746137a03600f488290318936c1a2d4dc", + "sha256:e28a50b5be854e18d54f75ef1bb13e1abf4bc650ab9d635e4258c58e71eb6ad5", + "sha256:e99c625b8c95d7741fe057585176b1b8783d46ed4b8932cf98ee145c4facf499", + "sha256:ec6f18f96b47299c11203edfbdc34e1b69085070d9a3d1f302810cc23ad36bf3", + "sha256:ed8bc367f725dfc5cabeed1ae079d00369900231fbb5a5280cf0736c30e2adf7", + "sha256:ee5926746232f627a3be1cc175b2cfad24d0170d520361f4ce3fa2fd83f09e1d", + "sha256:f295efcd47b6124b01255d1491f9e46f17ef40d3d7eabf7364099e463fb45f0f", + "sha256:fb0b361d73f6b8eeceba47cd37070b5e6c9de5beaeaa63a1cb35c7e1a73ef088" + ], + "version": "==3.9.10" + }, "packaging": { "hashes": [ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==23.2" }, "parsedatetime": { @@ -610,6 +768,63 @@ "markers": "python_version >= '3.8'", "version": "==10.1.0" }, + "pycares": { + "hashes": [ + "sha256:112a4979c695b1c86f6782163d7dec58d57a3b9510536dcf4826550f9053dd9a", + "sha256:1168a48a834813aa80f412be2df4abaf630528a58d15c704857448b20b1675c0", + "sha256:21a5a0468861ec7df7befa69050f952da13db5427ae41ffe4713bc96291d1d95", + "sha256:229a1675eb33bc9afb1fc463e73ee334950ccc485bc83a43f6ae5839fb4d5fa3", + "sha256:22c00bf659a9fa44d7b405cf1cd69b68b9d37537899898d8cbe5dffa4016b273", + "sha256:23aa3993a352491a47fcf17867f61472f32f874df4adcbb486294bd9fbe8abee", + "sha256:24da119850841d16996713d9c3374ca28a21deee056d609fbbed29065d17e1f6", + "sha256:2eeec144bcf6a7b6f2d74d6e70cbba7886a84dd373c886f06cb137a07de4954c", + "sha256:34736a2ffaa9c08ca9c707011a2d7b69074bbf82d645d8138bba771479b2362f", + "sha256:3aebc73e5ad70464f998f77f2da2063aa617cbd8d3e8174dd7c5b4518f967153", + "sha256:3eaa6681c0a3e3f3868c77aca14b7760fed35fdfda2fe587e15c701950e7bc69", + "sha256:4afc2644423f4eef97857a9fd61be9758ce5e336b4b0bd3d591238bb4b8b03e0", + "sha256:52084961262232ec04bd75f5043aed7e5d8d9695e542ff691dfef0110209f2d4", + "sha256:56cf3349fa3a2e67ed387a7974c11d233734636fe19facfcda261b411af14d80", + "sha256:5ed4e04af4012f875b78219d34434a6d08a67175150ac1b79eb70ab585d4ba8c", + "sha256:64965dc19c578a683ea73487a215a8897276224e004d50eeb21f0bc7a0b63c88", + "sha256:6ef64649eba56448f65e26546d85c860709844d2fc22ef14d324fe0b27f761a9", + "sha256:77cf5a2fd5583c670de41a7f4a7b46e5cbabe7180d8029f728571f4d2e864084", + "sha256:7bddc6adba8f699728f7fc1c9ce8cef359817ad78e2ed52b9502cb5f8dc7f741", + "sha256:813d661cbe2e37d87da2d16b7110a6860e93ddb11735c6919c8a3545c7b9c8d8", + "sha256:82bba2ab77eb5addbf9758d514d9bdef3c1bfe7d1649a47bd9a0d55a23ef478b", + "sha256:8bf2eaa83a5987e48fa63302f0fe7ce3275cfda87b34d40fef9ce703fb3ac002", + "sha256:8d186dafccdaa3409194c0f94db93c1a5d191145a275f19da6591f9499b8e7b8", + "sha256:8f64cb58729689d4d0e78f0bfb4c25ce2f851d0274c0273ac751795c04b8798a", + "sha256:902461a92b6a80fd5041a2ec5235680c7cc35e43615639ec2a40e63fca2dfb51", + "sha256:917f08f0b5d9324e9a34211e68d27447c552b50ab967044776bbab7e42a553a2", + "sha256:94d6962db81541eb0396d2f0dfcbb18cdb8c8b251d165efc2d974ae652c547d4", + "sha256:97892cced5794d721fb4ff8765764aa4ea48fe8b2c3820677505b96b83d4ef47", + "sha256:9a0303428d013ccf5c51de59c83f9127aba6200adb7fd4be57eddb432a1edd2a", + "sha256:9dc04c54c6ea615210c1b9e803d0e2d2255f87a3d5d119b6482c8f0dfa15b26b", + "sha256:a0c5368206057884cde18602580083aeaad9b860e2eac14fd253543158ce1e93", + "sha256:ad58e284a658a8a6a84af2e0b62f2f961f303cedfe551854d7bd40c3cbb61912", + "sha256:afb91792f1556f97be7f7acb57dc7756d89c5a87bd8b90363a77dbf9ea653817", + "sha256:b61579cecf1f4d616e5ea31a6e423a16680ab0d3a24a2ffe7bb1d4ee162477ff", + "sha256:b7af06968cbf6851566e806bf3e72825b0e6671832a2cbe840be1d2d65350710", + "sha256:bce8db2fc6f3174bd39b81405210b9b88d7b607d33e56a970c34a0c190da0490", + "sha256:bfb89ca9e3d0a9b5332deeb666b2ede9d3469107742158f4aeda5ce032d003f4", + "sha256:c680fef1b502ee680f8f0b95a41af4ec2c234e50e16c0af5bbda31999d3584bd", + "sha256:c6a8bde63106f162fca736e842a916853cad3c8d9d137e11c9ffa37efa818b02", + "sha256:cb49d5805cd347c404f928c5ae7c35e86ba0c58ffa701dbe905365e77ce7d641", + "sha256:ceb12974367b0a68a05d52f4162b29f575d241bd53de155efe632bf2c943c7f6", + "sha256:d33e2a1120887e89075f7f814ec144f66a6ce06a54f5722ccefc62fbeda83cff", + "sha256:db24c4e7fea4a052c6e869cbf387dd85d53b9736cfe1ef5d8d568d1ca925e977", + "sha256:e3a6f7cfdfd11eb5493d6d632e582408c8f3b429f295f8799c584c108b28db6f", + "sha256:eb66c30eb11e877976b7ead13632082a8621df648c408b8e15cdb91a452dd502", + "sha256:ed2a38e34bec6f2586435f6ff0bc5fe11d14bebd7ed492cf739a424e81681540", + "sha256:f36bdc1562142e3695555d2f4ac0cb69af165eddcefa98efc1c79495b533481f", + "sha256:f47579d508f2f56eddd16ce72045782ad3b1b3b678098699e2b6a1b30733e1c2", + "sha256:f5f646eec041db6ffdbcaf3e0756fb92018f7af3266138c756bb09d2b5baadec", + "sha256:fd644505a8cfd7f6584d33a9066d4e3d47700f050ef1490230c962de5dfb28c6", + "sha256:fff16b09042ba077f7b8aa5868d1d22456f0002574d0ba43462b10a009331677" + ], + "markers": "python_version >= '3.8'", + "version": "==4.4.0" + }, "pycparser": { "hashes": [ "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", @@ -704,7 +919,7 @@ "sha256:fb1c56d891f9e34303c451998ef62ba52659648bb0d75b03c5e4ac223a3342c2", "sha256:fe03bf25fae4b95d8afe40004a321df644400fdcba4c8e5e1a19c1085b740888" ], - "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==4.6.0" }, "python-dateutil": { @@ -713,6 +928,7 @@ "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.8.2" }, "python-dotenv": { @@ -721,6 +937,7 @@ "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==1.0.0" }, "requests": { @@ -729,6 +946,7 @@ "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.31.0" }, "six": { @@ -789,7 +1007,6 @@ "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7", "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256" ], - "index": "pypi", "markers": "sys_platform != 'win32'", "version": "==0.19.0" }, @@ -903,7 +1120,7 @@ "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca", "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e" ], - "markers": "python_version >= '3.8'", + "markers": "python_full_version >= '3.8.0'", "version": "==3.0.1" }, "bandit": { @@ -912,6 +1129,7 @@ "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.7.5" }, "black": { @@ -936,6 +1154,7 @@ "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==23.11.0" }, "click": { @@ -975,7 +1194,7 @@ "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" ], - "markers": "python_version >= '3.8'", + "markers": "python_full_version >= '3.8.0'", "version": "==5.12.0" }, "markdown-it-py": { @@ -1016,6 +1235,7 @@ "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==23.2" }, "pathspec": { @@ -1044,11 +1264,11 @@ }, "pygments": { "hashes": [ - "sha256:1b37f1b1e1bff2af52ecaf28cc601e2ef7077000b227a0675da25aef85784bc4", - "sha256:e45a0e74bf9c530f564ca81b8952343be986a29f6afe7f5ad95c5f06b7bdf5e8" + "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", + "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" ], "markers": "python_version >= '3.7'", - "version": "==2.17.1" + "version": "==2.17.2" }, "pylint": { "hashes": [ @@ -1056,6 +1276,7 @@ "sha256:60ed5f3a9ff8b61839ff0348b3624ceeb9e6c2a92c514d81c9cc273da3b6bcda" ], "index": "pypi", + "markers": "python_full_version >= '3.8.0'", "version": "==3.0.2" }, "pyyaml": { @@ -1119,7 +1340,7 @@ "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==13.7.0" }, "smmap": { @@ -1160,6 +1381,7 @@ "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==4.8.0" } } diff --git a/requirements.txt b/requirements.txt index 3c712a43a0..2c7bdb7880 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,34 +1,38 @@ -i https://pypi.org/simple -aiohttp==3.9.0 +aiodns==3.1.1 +aiohttp==3.9.0; python_version >= '3.8' aiosignal==1.3.1; python_version >= '3.7' async-timeout==4.0.3; python_version < '3.11' attrs==23.1.0; python_version >= '3.7' +brotli==1.1.0 cairocffi==1.6.1; python_version >= '3.7' cairosvg==2.7.1; python_version >= '3.5' certifi==2023.11.17; python_version >= '3.6' cffi==1.16.0; python_version >= '3.8' -charset-normalizer==3.3.2; python_version >= '3.7' -colorama==0.4.6 +charset-normalizer==3.3.2; python_full_version >= '3.7.0' +colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' cssselect2==0.7.0; python_version >= '3.7' defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -discord.py==2.3.2 +discord.py[speed]==2.3.2; python_full_version >= '3.8.0' dnspython==2.4.2; python_version >= '3.8' and python_version < '4.0' -emoji==2.8.0 +emoji==2.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' frozenlist==1.4.0; python_version >= '3.8' idna==3.4; python_version >= '3.5' isodate==0.6.1 -lottie[pdf]==0.7.0 -motor==3.3.2 +lottie[pdf]==0.7.0; python_version >= '3' +motor==3.3.2; python_version >= '3.7' multidict==6.0.4; python_version >= '3.7' natural==0.2.0 -packaging==23.2 +orjson==3.9.10 +packaging==23.2; python_version >= '3.7' parsedatetime==2.6 pillow==10.1.0; python_version >= '3.8' +pycares==4.4.0; python_version >= '3.8' pycparser==2.21 -pymongo[srv]==4.6.0 -python-dateutil==2.8.2 -python-dotenv==1.0.0 -requests==2.31.0 +pymongo[srv]==4.6.0; python_version >= '3.7' +python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +python-dotenv==1.0.0; python_version >= '3.8' +requests==2.31.0; python_version >= '3.7' six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' tinycss2==1.2.1; python_version >= '3.7' urllib3==2.1.0; python_version >= '3.8' From 768d4daf81f826015420f2d5d3da770e4e7924e7 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 26 Nov 2023 13:51:47 -0800 Subject: [PATCH 667/705] Bump version to 4.1.0 --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ef7e87d6d..cb334e4e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# [UNRELEASED] +# v4.1.0 Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only supported versions. diff --git a/README.md b/README.md index 319a9742cf..ea6cb3eae0 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.0.2-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.1.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index 3c24681d12..bb47c75283 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.2" +__version__ = "4.1.0" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 389c24e3d5..cc43b4a54c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.2' +version = '4.1.0' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 285e336cece0c87f43cb19959b6da28b0ea91ac7 Mon Sep 17 00:00:00 2001 From: Raiden <raidensakurajima@gmail.com> Date: Wed, 15 May 2024 19:48:26 +0800 Subject: [PATCH 668/705] Fix Docker file permission issue (#3323) * Update Dockerfile * Use the slim-bookworm image, refactored some steps * Disable user login * Capitalize comment --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- Dockerfile | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 96a398fad4..246d3cf7a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,38 @@ -FROM python:3.10 as py +FROM python:3.11-slim-bookworm as base -FROM py as build +RUN apt-get update && \ + apt-get install --no-install-recommends -y \ + # Install CairoSVG dependencies. + libcairo2 && \ + # Cleanup APT. + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + # Create a non-root user. + useradd --shell /usr/sbin/nologin --create-home -d /opt/modmail modmail -RUN apt update && apt install -y g++ git +FROM base as builder -COPY requirements.txt / -RUN pip install --prefix=/inst -U -r /requirements.txt +COPY requirements.txt . -FROM py +RUN pip install --root-user-action=ignore --no-cache-dir --upgrade pip wheel && \ + python -m venv /opt/modmail/.venv && \ + . /opt/modmail/.venv/bin/activate && \ + pip install --no-cache-dir --upgrade -r requirements.txt -COPY --from=build /inst /usr/local +FROM base -ENV USING_DOCKER yes -RUN useradd --system --no-create-home modmail -USER modmail +# Copy the entire venv. +COPY --from=builder --chown=modmail:modmail /opt/modmail/.venv /opt/modmail/.venv + +# Copy repository files. +WORKDIR /opt/modmail +USER modmail:modmail +COPY --chown=modmail:modmail . . + +# This sets some Python runtime variables and disables the internal auto-update. +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + PATH=/opt/modmail/.venv/bin:$PATH \ + USING_DOCKER=yes -WORKDIR /modmailbot CMD ["python", "bot.py"] -COPY --chown=modmail:modmail . /modmailbot From 30bd95843ff5950790645141883f6f194f2a3c74 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 26 May 2024 03:18:21 -0700 Subject: [PATCH 669/705] Updated sponsors --- README.md | 7 +++++++ SPONSORS.json | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/README.md b/README.md index ea6cb3eae0..980066ca7e 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,13 @@ Advertise Your Server: </a> <br> <br> +Help Us • Help Other's: +<br> +<a href='https://discord.gg/5yQCFzY6HU'> + <img height=100 src='https://i.imgur.com/Gi3jxeH.gif' style='margin:5px'> +</a> +<br> +<br> Discord Advice Center: <br> <a href='https://discord.gg/zmwZy5fd9v'> diff --git a/SPONSORS.json b/SPONSORS.json index ce34dc3f9d..3a964dc3cf 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -128,5 +128,32 @@ "url": "https://discord.gg/uncommon", "title": "uncommon community" } + }, + { + "embed": { + "author": { + "name": "Help us • Help Others" + }, + "title": "Join Today", + "url": "https://discord.gg/5yQCFzY6HU", + "description": "At Help Us • Help Others, we accept as true with inside the transformative electricity of cooperation and kindness. Each one people has the capability to make a meaningful impact by means of helping and caring for others. Whether you want assistance or want to offer it, this is the right region for you!", + "fields": [ + { + "name": "What we offer:", + "value": "`🎬` - Active community\n`👮` - Active staff around the globe! \n`🛜` - 40+ Advertising channels to grow your socials!\n`💎` - Boosting Perks\n`🎉` - Event's monthly especially bank holiday roles!!\n`🔢` - Unique levelling systems\n`📞` - Multiple voice channels including gaming!\n`🎁` - Exclusive giveaways!" + }, + { + "name": "We Are Hiring", + "value": "`🔵` - Moderators\n`🔵` - Human Resources\n`🔵` - Community Team\n`🔵` - Partnership Manager\n`🔵` - Growth Manager\n`🚀` Much more to come!\n\n\nJoin Today!" + } + ], + "image": { + "url": "https://cdn.discordapp.com/attachments/1218338794416246874/1243635366326567002/AD_animated.gif" + }, + "color": 45300, + "footer": { + "text": "Help Us • Help Others" + } + } } ] From 8c04d25c917916f65a536687a6b8dc9398904c4e Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 23 Jun 2024 09:14:20 -0700 Subject: [PATCH 670/705] Update sponsors --- SPONSORS.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/SPONSORS.json b/SPONSORS.json index 3a964dc3cf..80e3539f87 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -81,7 +81,7 @@ "icon_url": "https://i.imgur.com/cjVtRw5.jpg" }, "image": { - "url": "https://i.imgur.com/1hrjcHd.png" + "url": "https://i.imgur.com/1hrjcHd.png" }, "fields": [ { @@ -155,5 +155,18 @@ "text": "Help Us • Help Others" } } + }, + { + "embed": { + "description": "> Be apart of our community as we start to grow! and embark on a long journey.\n——————————————————-\n**What we offer?**\n\n➺〚🖌️〛Custom Liveries \n➺〚❤️〛Friendly and Growing community.\n➺〚🤝〛Partnerships.\n➺〚🎮〛Daily SSUs. \n➺〚🚨〛Great roleplays.\n➺〚💬〛Kind and Professional staff\n➺〚🎉〛Giveaways!!! \n——————————————————-\n**Emergency Services**\n\n➺〚🚔〛NY Police Force\n➺〚🚒〛Fire & Emergency NY\n➺〚🚧〛NY department of transportation \n\n——————————————————-\n**Whitelisted**\nComing soon!\n——————————————————-\n**What are we looking for!**\n\n➺〚💬〛More members\n➺〚⭐〛Staff Members - **WE'RE HIRING!**\n➺〚🤝〛Partnerships\n➺〚💎〛Boosters\n——————————————————\n\n**[Join now](https://discord.com/invite/qt62qSnKVa)**", + "author": { + "name": "New York Roleplay", + "icon_url": "https://cdn.discordapp.com/icons/1172553254882775111/648d5bc50393a21216527a1aaa61286d.webp" + }, + "color": 431075, + "thumbnail": { + "url": "https://cdn.discordapp.com/icons/1172553254882775111/648d5bc50393a21216527a1aaa61286d.webp" + } + } } ] From 19ff5a035cd05cc639aae91036581ee485649ed6 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 26 Aug 2024 00:07:16 +0200 Subject: [PATCH 671/705] Update sponsorship info --- SPONSORS.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SPONSORS.json b/SPONSORS.json index 80e3539f87..eb43227f6b 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -168,5 +168,15 @@ "url": "https://cdn.discordapp.com/icons/1172553254882775111/648d5bc50393a21216527a1aaa61286d.webp" } } + }, + { + "embeds": { + "title": "Pixelmark TM PLC", + "description": "Hi there! Welcome to PixelMark PLC! \nI'm so glad you're here. I started PixelMark PLC on May 24, 2023. Our team is dedicated to providing top-quality products and a great shopping experience. But more than that, PixelMark PLC is a community. We're here to share, create, and have fun together. Thanks for joining us on this exciting journey! Our current Goal is to reach 100 Human Members, you can help us achieve that Goal by joining or/and inviting your Friends!\n\nBest regards, \n*Felixpro202110 / Chief Executive Officer (Founder)* \n-----------------------------------------------------------------------\n> https://discord.gg/RVzNVRaFeE\n> https://www.roblox.com/groups/16031525/PixelMark-PLC", + "color": 10634504, + "image": { + "url": "https://imgur.com/iTl1dXm.png" + } + } } ] From 041c4fdc78b2391d481ddeee50d0883b645557e7 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 26 Aug 2024 00:07:51 +0200 Subject: [PATCH 672/705] Update sponsorship info --- SPONSORS.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SPONSORS.json b/SPONSORS.json index eb43227f6b..22cf0d44f1 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -170,7 +170,7 @@ } }, { - "embeds": { + "embed": { "title": "Pixelmark TM PLC", "description": "Hi there! Welcome to PixelMark PLC! \nI'm so glad you're here. I started PixelMark PLC on May 24, 2023. Our team is dedicated to providing top-quality products and a great shopping experience. But more than that, PixelMark PLC is a community. We're here to share, create, and have fun together. Thanks for joining us on this exciting journey! Our current Goal is to reach 100 Human Members, you can help us achieve that Goal by joining or/and inviting your Friends!\n\nBest regards, \n*Felixpro202110 / Chief Executive Officer (Founder)* \n-----------------------------------------------------------------------\n> https://discord.gg/RVzNVRaFeE\n> https://www.roblox.com/groups/16031525/PixelMark-PLC", "color": 10634504, From 26d73f5fa8a2c13ec9a8793658357f088a42da55 Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:24:20 +0100 Subject: [PATCH 673/705] Add support for custom activities (#3352) --- cogs/utility.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index b892ffc01b..31cb065a28 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -499,6 +499,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): - `listening` - `watching` - `competing` + - `custom` When activity type is set to `listening`, it must be followed by a "to": "listening to..." @@ -510,6 +511,9 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): the linked twitch page: - `{prefix}config set twitch_url https://www.twitch.tv/somechannel/` + When activity type is set to `custom`, you can set + any custom text as the activity message. + To remove the current activity status: - `{prefix}activity clear` """ @@ -609,7 +613,9 @@ async def set_presence(self, *, status=None, activity_type=None, activity_messag elif activity_type == ActivityType.streaming: url = self.bot.config["twitch_url"] - if activity_type is not None: + if activity_type == ActivityType.custom: + activity = discord.CustomActivity(name=activity_message) + elif activity_type is not None: activity = discord.Activity(type=activity_type, name=activity_message, url=url) else: activity = None From fa6ad6388af2bb399615de3ede2c7569e7bcd8e5 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 27 Oct 2024 06:26:54 -0700 Subject: [PATCH 674/705] Updated changelog for custom activities #3352 --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb334e4e8e..d32485205c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.1.1 + +### Added +- Support for custom activities with `?activity custom <text>` ([PR #3352](https://github.com/modmail-dev/Modmail/pull/3352)) + # v4.1.0 Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only supported versions. @@ -14,7 +19,7 @@ Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only suppo - GIF stickers no longer cause the bot to crash. - `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) - Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) -- Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) +- Reply not being forwarded from DM. ([PR #3239](https://github.com/modmail-dev/modmail/pull/3239)) - Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226)) - Fixed a syntactic error in the close message when a thread is closed after a certain duration. ([PR #3233](https://github.com/modmail-dev/Modmail/pull/3233)) - Removed an extra space in the help command title when the command has no parameters. ([PR #3271](https://github.com/modmail-dev/Modmail/pull/3271)) From 2400ceb74ba968665ac555fb657214ec690e9f49 Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:30:40 +0100 Subject: [PATCH 675/705] msglink command now scans all recipients (#3341) * msglink command now scans all recipients * Run black formatting --- cogs/modmail.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index ee27806177..e2a0039384 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -696,9 +696,15 @@ async def sfw(self, ctx): @checks.thread_only() async def msglink(self, ctx, message_id: int): """Retrieves the link to a message in the current thread.""" - try: - message = await ctx.thread.recipient.fetch_message(message_id) - except discord.NotFound: + found = False + for recipient in ctx.thread.recipients: + try: + message = await recipient.fetch_message(message_id) + found = True + break + except discord.NotFound: + continue + if not found: embed = discord.Embed( color=self.bot.error_color, description="Message not found or no longer exists." ) From 5de513ca18a9f36091ad8ee75364e74f0352df72 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 27 Oct 2024 06:36:05 -0700 Subject: [PATCH 676/705] Updated changelog for msglink multiple recipients fix #3341 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d32485205c..e2a5a52241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v4.1.1 +### Fixed +- `?msglink` now supports threads with multiple recipients. ([PR #3341](https://github.com/modmail-dev/Modmail/pull/3341)) + ### Added - Support for custom activities with `?activity custom <text>` ([PR #3352](https://github.com/modmail-dev/Modmail/pull/3352)) From 3c422c8f550b1eac6eb88f9b6f754cdc1db12af5 Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:56:13 +0100 Subject: [PATCH 677/705] Error-handle a timeout error when loading plugins (#3330) * Fix registry loading errors * Fix black formatting * Repo consistency * Change code cleanness as requested by taku --------- Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- cogs/plugins.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index fc6e09f05d..78bc0aa544 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -6,8 +6,8 @@ import sys import typing import zipfile -from importlib import invalidate_caches from difflib import get_close_matches +from importlib import invalidate_caches from pathlib import Path, PurePath from re import match from site import USER_SITE @@ -15,13 +15,12 @@ import discord from discord.ext import commands - from packaging.version import Version from core import checks from core.models import PermissionLevel, getLogger from core.paginator import EmbedPaginatorSession -from core.utils import truncate, trigger_typing +from core.utils import trigger_typing, truncate logger = getLogger(__name__) @@ -132,8 +131,11 @@ async def cog_load(self): async def populate_registry(self): url = "https://raw.githubusercontent.com/modmail-dev/modmail/master/plugins/registry.json" - async with self.bot.session.get(url) as resp: - self.registry = json.loads(await resp.text()) + try: + async with self.bot.session.get(url) as resp: + self.registry = json.loads(await resp.text()) + except asyncio.TimeoutError: + logger.warning("Failed to fetch registry. Loading with empty registry") async def initial_load_plugins(self): for plugin_name in list(self.bot.config["plugins"]): @@ -638,6 +640,14 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N registry = sorted(self.registry.items(), key=lambda elem: elem[0]) + if not registry: + embed = discord.Embed( + color=self.bot.error_color, + description="Registry is empty. This could be because it failed to load.", + ) + await ctx.send(embed=embed) + return + if isinstance(plugin_name, int): index = plugin_name - 1 if index < 0: From 7c1574ff81887f2907ab53b968083c97f797e862 Mon Sep 17 00:00:00 2001 From: Martin <box152535@gmail.com> Date: Sun, 27 Oct 2024 14:59:18 +0100 Subject: [PATCH 678/705] fixes persistent note (#3324) This fixes persistent note not sending on thread creation. Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 646c98a604..81dc03f44d 100644 --- a/core/thread.py +++ b/core/thread.py @@ -250,7 +250,7 @@ async def send_persistent_notes(): ids = {} class State: - def store_user(self, user): + def store_user(self, user, cache): return user for note in notes: From eee764ebc368b2a165aff1204aa272e8f2a72a99 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 27 Oct 2024 07:00:48 -0700 Subject: [PATCH 679/705] Updated changelog for persistent notes fix #3324 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2a5a52241..688462f439 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed - `?msglink` now supports threads with multiple recipients. ([PR #3341](https://github.com/modmail-dev/Modmail/pull/3341)) +- Fixed persistent notes not working due to discord.py internal change. ([PR #3324](https://github.com/modmail-dev/Modmail/pull/3324)) ### Added - Support for custom activities with `?activity custom <text>` ([PR #3352](https://github.com/modmail-dev/Modmail/pull/3352)) From da97bdc0c78daaf6a3b052346c5a5eb4a4062744 Mon Sep 17 00:00:00 2001 From: andy <andy@ondrya.com> Date: Sun, 27 Oct 2024 10:02:56 -0400 Subject: [PATCH 680/705] Update SPONSORS.json (#3348) Removal of Advertise Your Server. Company has been closed. Signed-off-by: andy <andy@ondrya.com> --- SPONSORS.json | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/SPONSORS.json b/SPONSORS.json index 22cf0d44f1..491b30eb9f 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -91,23 +91,6 @@ ] } }, - { - "embed": { - "title": "Advertise Your Server", - "description": "Advertise Your Server is the leading advertising and growth Discord Server. With over 60,000 members we can help grow your community with our range of services.\n\n__**Advertise Your Server offers everything you need to grow and find servers:**__\n\n:chart_with_upwards_trend: **Discord Growth Experts** to give you advice on how to __grow your server.__ (server/advert reviews, growth tips)\n:dividers: Over 40 different channels for **different server categories.**\n:robot: Our own __custom__ **bump bot.** (Liam)\n:bar_chart: Currently the __BIGGEST__ advertising server on Discord.\n:computer: Our own server __Listing Site__!\n:ticket: Small Servers Program for servers with less than 300 members.\n:dvd: Weekly Podcast, Blog, Email Newsletter and YouTube Tutorials. \n\nhttps://discord.gg/zP8KcF4VQz\nhttps://aysdiscord.com", - "author": { - "name": "Advertise Your Server", - "icon_url": "https://cdn.discordapp.com/attachments/563522692418895872/907067815486427176/logo4.png" - }, - "color": 431075, - "footer": { - "text": "Grow Your Discord Server" - }, - "image": { - "url": "https://cdn.discordapp.com/attachments/472811257913933834/907068966311166043/unknown_2.png" - } - } - }, { "embed": { "footer": { From 464b64c36abbef91316bf017b3542ae64540297f Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 14 Jan 2025 05:08:34 +0000 Subject: [PATCH 681/705] Update SPONSORS.json Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --- SPONSORS.json | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/SPONSORS.json b/SPONSORS.json index 491b30eb9f..feb822ee21 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -154,12 +154,8 @@ }, { "embed": { - "title": "Pixelmark TM PLC", - "description": "Hi there! Welcome to PixelMark PLC! \nI'm so glad you're here. I started PixelMark PLC on May 24, 2023. Our team is dedicated to providing top-quality products and a great shopping experience. But more than that, PixelMark PLC is a community. We're here to share, create, and have fun together. Thanks for joining us on this exciting journey! Our current Goal is to reach 100 Human Members, you can help us achieve that Goal by joining or/and inviting your Friends!\n\nBest regards, \n*Felixpro202110 / Chief Executive Officer (Founder)* \n-----------------------------------------------------------------------\n> https://discord.gg/RVzNVRaFeE\n> https://www.roblox.com/groups/16031525/PixelMark-PLC", - "color": 10634504, - "image": { - "url": "https://imgur.com/iTl1dXm.png" - } + "description": "**__CityStore PLC__**\n*Your Retail Journey*\n*\"Better choice and better value in food, fashion & homewares.\"*\n\n\n**------------------------------------------**\n*__About us__*\nSupermarket, CityStore PLC! Attend a training to become staff!\n\nThis game is currently in V3\n\nWe have a training Centre and applications center!\n\n**------------------------------------------**\n\n> *❤️ Don't hesitate! Dive into the excitement today by joining our vibrant community on Discord. Experience our unique perspective and become an integral part of our group. Your **journey** with us promises to be unforgettable no regrets, only great memories await! ❤️*\n\n*We hope to see you. *\n\n*Signed,*\n**CityStore PLC**\n> Discord: https://discord.gg/yjFQb5mrSk\n> Roblox Group: https://www.roblox.com/groups/32819373/CityStore-PLC#!/about\n\nJoin us now and become apart of Citystore PLC community! 🎉", + "color": 15523550 } } ] From bb2892f5aebf1d335d612cf03d25e34553276fdc Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 16 Jan 2025 00:13:09 -0800 Subject: [PATCH 682/705] Update sponsors --- SPONSORS.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SPONSORS.json b/SPONSORS.json index feb822ee21..b6212b8ed7 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -154,7 +154,8 @@ }, { "embed": { - "description": "**__CityStore PLC__**\n*Your Retail Journey*\n*\"Better choice and better value in food, fashion & homewares.\"*\n\n\n**------------------------------------------**\n*__About us__*\nSupermarket, CityStore PLC! Attend a training to become staff!\n\nThis game is currently in V3\n\nWe have a training Centre and applications center!\n\n**------------------------------------------**\n\n> *❤️ Don't hesitate! Dive into the excitement today by joining our vibrant community on Discord. Experience our unique perspective and become an integral part of our group. Your **journey** with us promises to be unforgettable no regrets, only great memories await! ❤️*\n\n*We hope to see you. *\n\n*Signed,*\n**CityStore PLC**\n> Discord: https://discord.gg/yjFQb5mrSk\n> Roblox Group: https://www.roblox.com/groups/32819373/CityStore-PLC#!/about\n\nJoin us now and become apart of Citystore PLC community! 🎉", + "title": "CityStore PLC", + "description": "*Your Retail Journey*\n*\"Better choice and better value in food, fashion & homewares.\"*\n\n\n**------------------------------------------**\n*__About us__*\nSupermarket, CityStore PLC! Attend a training to become staff!\n\nThis game is currently in V3\n\nWe have a training Centre and applications center!\n\n**------------------------------------------**\n\n> *❤️ Don't hesitate! Dive into the excitement today by joining our vibrant community on Discord. Experience our unique perspective and become an integral part of our group. Your **journey** with us promises to be unforgettable no regrets, only great memories await! ❤️*\n\n*We hope to see you. *\n\n*Signed,*\n**CityStore PLC**\n> Discord: https://discord.gg/yjFQb5mrSk\n> Roblox Group: https://www.roblox.com/groups/32819373/CityStore-PLC#!/about\n\nJoin us now and become apart of Citystore PLC community! 🎉", "color": 15523550 } } From 792a3727ce1317e0dfad46e243959856c4bc0d9f Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 16 Jan 2025 00:16:18 -0800 Subject: [PATCH 683/705] Bump version to v4.1.1 --- bot.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index bb47c75283..3c6ebe7911 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.1.0" +__version__ = "4.1.1" import asyncio diff --git a/pyproject.toml b/pyproject.toml index cc43b4a54c..1a5ed16a3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.1.0' +version = '4.1.1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 89afed5793221d8d55792c50f8dd30b28db4885d Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Thu, 16 Jan 2025 08:28:36 +0000 Subject: [PATCH 684/705] Update README.md Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 980066ca7e..500978a1f9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.1.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.1.1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> @@ -24,7 +24,7 @@ </a> <a href="https://patreon.com/kyber"> - <img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Python 3.8"> + <img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Patreon"> </a> <a href="https://www.python.org/downloads/"> From 6c820bfeca3f42d9e9e0bc4fd5d6ddfb8a1e18ad Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:59:47 +0000 Subject: [PATCH 685/705] Update README.md Update sponsors Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 500978a1f9..eef9e3f940 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,13 @@ Discord Advice Center: <a href='https://discord.gg/zmwZy5fd9v'> <img height=100 src='https://i.imgur.com/1hrjcHd.png' style='margin:5px'> </a> +<br> +<br> +Blacklight Promotions: +<br> +<a href='https://blacklightpromotions.online'> + <img height=100 src='https://i.imgur.com/yLgE6h6.png' style='margin:5px'> +</a> Become a sponsor on [Patreon](https://patreon.com/kyber). From 1a3bda800d500c2c8be42f44403bbfe73b4ab2a8 Mon Sep 17 00:00:00 2001 From: Sebastian Kuipers <61157793+sebkuip@users.noreply.github.com> Date: Wed, 12 Mar 2025 04:37:06 +0100 Subject: [PATCH 686/705] Merge the pydis changes to the bot (#3365) * Update README.md Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Update README.md Update sponsors Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Escape hyphen in regex string Unescaped this was permitting any character between $ (index 36) and _ (index 95), which aren't all valid in urls. * Get or fetch member when trying to reply This fixes an issue where the member may not be in the cache --------- Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Chris Lovering <chris.lovering.95@gmail.com> --- README.md | 11 +++++++++-- bot.py | 10 ++++++++++ core/thread.py | 10 ++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 980066ca7e..eef9e3f940 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.1.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.1.1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> @@ -24,7 +24,7 @@ </a> <a href="https://patreon.com/kyber"> - <img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Python 3.8"> + <img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Patreon"> </a> <a href="https://www.python.org/downloads/"> @@ -159,6 +159,13 @@ Discord Advice Center: <a href='https://discord.gg/zmwZy5fd9v'> <img height=100 src='https://i.imgur.com/1hrjcHd.png' style='margin:5px'> </a> +<br> +<br> +Blacklight Promotions: +<br> +<a href='https://blacklightpromotions.online'> + <img height=100 src='https://i.imgur.com/yLgE6h6.png' style='margin:5px'> +</a> Become a sponsor on [Patreon](https://patreon.com/kyber). diff --git a/bot.py b/bot.py index 3c6ebe7911..bcf67e5f9a 100644 --- a/bot.py +++ b/bot.py @@ -640,6 +640,16 @@ async def get_or_fetch_user(self, id: int) -> discord.User: """ return self.get_user(id) or await self.fetch_user(id) + @staticmethod + async def get_or_fetch_member(guild: discord.Guild, member_id: int) -> typing.Optional[discord.Member]: + """ + Attempt to get a member from cache; on failure fetch from the API. + + Returns: + The :obj:`discord.Member` or :obj:`None` to indicate the member could not be found. + """ + return guild.get_member(member_id) or await guild.fetch_member(member_id) + async def retrieve_emoji(self) -> typing.Tuple[str, str]: sent_emoji = self.config["sent_emoji"] blocked_emoji = self.config["blocked_emoji"] diff --git a/core/thread.py b/core/thread.py index 81dc03f44d..00060ab7f5 100644 --- a/core/thread.py +++ b/core/thread.py @@ -823,7 +823,13 @@ async def reply( """Returns List[user_dm_msg] and thread_channel_msg""" if not message.content and not message.attachments and not message.stickers: raise MissingRequiredArgument(DummyParam("msg")) - if not any(g.get_member(self.id) for g in self.bot.guilds): + for guild in self.bot.guilds: + try: + if await self.bot.get_or_fetch_member(guild, self.id): + break + except discord.NotFound: + pass + else: return await message.channel.send( embed=discord.Embed( color=self.bot.error_color, @@ -995,7 +1001,7 @@ async def send( attachments.append(attachment) image_urls = re.findall( - r"http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", + r"http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$\-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message.content, ) From 297aa0c7ee292af29fbcecb55e65d8f8e2f62edc Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Fri, 14 Mar 2025 04:14:26 -0700 Subject: [PATCH 687/705] Bump version to 4.1.2 --- CHANGELOG.md | 5 +++++ README.md | 2 +- bot.py | 2 +- pyproject.toml | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 688462f439..4ec54e0f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.1.2 + +### Fixed +- Members not caching correctly for large servers. ([PR #3365](https://github.com/modmail-dev/Modmail/pull/3365)) + # v4.1.1 ### Fixed diff --git a/README.md b/README.md index eef9e3f940..2e3d32e344 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.1.1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.1.2-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> diff --git a/bot.py b/bot.py index bcf67e5f9a..3f13ef7ced 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.1.1" +__version__ = "4.1.2" import asyncio diff --git a/pyproject.toml b/pyproject.toml index 1a5ed16a3b..7e29a4d4ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.1.1' +version = '4.1.2' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 21f4766b010d06b6d0afe78e1da7c59a8209dc90 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 11 Nov 2025 06:30:52 +0000 Subject: [PATCH 688/705] Merge development v4.2.0 (#3390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add (truncated) preview to snippets command (#3342) * Add (truncated) preview to snippets command * Add old view as option with "compact" * Fix black formatting * Fix: Image url regex in thread send method (#3378) * feat minimum character requirement for thread creation. (#3380) * update: dpy, snoozing. This pull request updated discord.py to 2.5.2. This also brings a new few features. - snooze - snoozed - unsnooze - clearsnoozed Aswell as a few new config options. - max_snooze_time - snooze_title - snooze_text - unsnooze_tex - unsnooze_notify_channel Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * remove: unneeded import Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Formatting black Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix?: internal messages on restoration Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * formatting Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: internal messages. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: internals Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: use same logkey after restoration Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Add files via upload Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: show who send which internal message. * Black formatting. * Update Pipfile Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update Pipfile.lock Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: unsnooze bug * feat: CV2 * update: black * fix: duplicates in logs, notes. * feat: dpy 2.6.3, forwarded messages, bug fixes. * Fix jump_url not being displayed * Update pipfile for new dpy version * fix: bug in note title/color * Update snooze arg * Update Pipfile to include tomli package Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * auto detect dpy version Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Remove crlf terminators * fix: ignore typing failures (#3389) * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * Lock pipenv * Fix: closing with timed words/ command in reply. (#3391) * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * Fix: closing with timed words/ command in reply. * Fix: typing in changelog command. * Fix: closing with timed words (additional)) * Fix changelog entry for command reply issue Corrected wording in the changelog entry regarding command inclusion in replies. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update CHANGELOG for v4.2.0 enhancements Forwarded messages now display correctly in threads. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Remove disutil, undo lowercasing escape seq * Add back uvloop * Add config help for snooze configs Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Update sponsors and bmac links --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Sebastian <61157793+sebkuip@users.noreply.github.com> Co-authored-by: Zallom <Yg75nWkHX7jBHcqRPUbb783c54xSa9+github63384893@gmail.com> Co-authored-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Co-authored-by: “lorenzo132” <lhoorn4@gmail.com> Co-authored-by: Martin <box152535@gmail.com> --- .env.example | 1 + .gitattributes | 1 + .github/FUNDING.yml | 2 +- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- CHANGELOG.md | 33 + Pipfile | 3 +- Pipfile.lock | 2353 ++++++++++++++++--------- README.md | 32 +- SPONSORS.json | 27 - bot.py | 216 ++- cogs/modmail.py | 345 +++- cogs/plugins.py | 9 +- cogs/utility.py | 101 +- core/_color_data.py | 1 - core/changelog.py | 4 +- core/clients.py | 10 +- core/config.py | 11 + core/config_help.json | 102 +- core/paginator.py | 29 +- core/thread.py | 415 ++++- core/time.py | 64 +- core/utils.py | 165 +- pyproject.toml | 2 +- requirements.txt | 54 +- 24 files changed, 2914 insertions(+), 1068 deletions(-) create mode 100644 .gitattributes diff --git a/.env.example b/.env.example index 14bdf060bf..972eca4517 100644 --- a/.env.example +++ b/.env.example @@ -3,3 +3,4 @@ LOG_URL=https://logviewername.herokuapp.com/ GUILD_ID=1234567890 OWNERS=Owner1ID,Owner2ID,Owner3ID CONNECTION_URI=mongodb+srv://mongodburi +DISABLE_AUTOUPDATES=true \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..176a458f94 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index fbcb038e69..8125c1756a 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -patreon: kyber +buy_me_a_coffee: modmaildev diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 99779ab4f3..35fc2bedb1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -20,7 +20,7 @@ body: - Heroku - Systemd - PM2 - - Patreon + - Buy Me A Coffee / Patreon - Other validations: required: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ec54e0f8a..83c4f1bdd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,39 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.2.0 + +Upgraded discord.py to version 2.6.3, added support for CV2. +Forwarded messages now properly show in threads, rather than showing as an empty embed. + +### Fixed +- Make Modmail keep working when typing is disabled due to an outage caused by Discord. +- Resolved an issue where forwarded messages appeared as empty embeds. +- Fixed internal message handling and restoration processes. +- Eliminated duplicate logs and notes. +- Addressed inconsistent use of `logkey` after ticket restoration. +- Fixed issues with identifying the user who sent internal messages. +- Solved an ancient bug where closing with words like `evening` wouldn't work. +- Fixed the command from being included in the reply in rare conditions. + +### Added +Commands: +* `snooze`: Initiates a snooze action. +* `snoozed`: Displays snoozed items. +* `unsnooze`: Reverses the snooze action. +* `clearsnoozed`: Clears all snoozed items. + +Configuration Options: +* `max_snooze_time`: Sets the maximum duration for snooze. +* `snooze_title`: Customizes the title for snooze notifications. +* `snooze_text`: Customizes the text for snooze notifications. +* `unsnooze_text`: Customizes the text for unsnooze notifications. +* `unsnooze_notify_channel`: Specifies the channel for unsnooze notifications. +* `thread_min_characters`: Minimum number of characters required. +* `thread_min_characters_title`: Title shown when the message is too short. +* `thread_min_characters_response`: Response shown to the user if their message is too short. +* `thread_min_characters_footer`: Footer displaying the minimum required characters. + # v4.1.2 ### Fixed diff --git a/Pipfile b/Pipfile index 21205b36f5..8fe5bd40c8 100644 --- a/Pipfile +++ b/Pipfile @@ -8,11 +8,12 @@ bandit = ">=1.7.5" black = "==23.11.0" pylint = "==3.0.2" typing-extensions = "==4.8.0" +tomli = "==2.2.1" # Needed for black on Python < 3.11 [packages] aiohttp = "==3.9.0" colorama = "==0.4.6" -"discord.py" = {version = "==2.3.2", extras = ["speed"]} +"discord.py" = {version = "==2.6.3", extras = ["speed"]} emoji = "==2.8.0" isodate = "==0.6.1" motor = "==3.3.2" diff --git a/Pipfile.lock b/Pipfile.lock index 5f07c7b131..ae2da5ae76 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7fee393ea9ea4c0b923033f0da0fdc590ba3f75c6072812062cdc458b84bf9ae" + "sha256": "93bdedec9b82ac210253d3424e48f3af9e79dca6c44b5b941ec446709de27409" }, "pipfile-spec": 6, "requires": {}, @@ -16,10 +16,11 @@ "default": { "aiodns": { "hashes": [ - "sha256:1073eac48185f7a4150cad7f96a5192d6911f12b4fb894de80a088508c9b3a99", - "sha256:a387b63da4ced6aad35b1dda2d09620ad608a1c7c0fb71efa07ebb4cd511928d" + "sha256:11264edbab51896ecf546c18eb0dd56dff0428c6aa6d2cd87e643e07300eb310", + "sha256:6d0404f7d5215849233f6ee44854f2bb2481adf71b336b2279016ea5990ca5c5" ], - "version": "==3.1.1" + "markers": "python_version >= '3.9'", + "version": "==3.5.0" }, "aiohttp": { "hashes": [ @@ -106,33 +107,81 @@ }, "aiosignal": { "hashes": [ - "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", - "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" + "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", + "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7" ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" - }, - "async-timeout": { - "hashes": [ - "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", - "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" - ], - "markers": "python_version < '3.11'", - "version": "==4.0.3" + "markers": "python_version >= '3.9'", + "version": "==1.4.0" }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", + "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b" ], - "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "markers": "python_version >= '3.8'", + "version": "==25.3.0" + }, + "audioop-lts": { + "hashes": [ + "sha256:0337d658f9b81f4cd0fdb1f47635070cc084871a3d4646d9de74fdf4e7c3d24a", + "sha256:03f061a1915538fd96272bac9551841859dbb2e3bf73ebe4a23ef043766f5449", + "sha256:068aa17a38b4e0e7de771c62c60bbca2455924b67a8814f3b0dee92b5820c0b3", + "sha256:088327f00488cdeed296edd9215ca159f3a5a5034741465789cad403fcf4bec0", + "sha256:0d9385e96f9f6da847f4d571ce3cb15b5091140edf3db97276872647ce37efd7", + "sha256:106753a83a25ee4d6f473f2be6b0966fc1c9af7e0017192f5531a3e7463dce58", + "sha256:143fad0311e8209ece30a8dbddab3b65ab419cbe8c0dde6e8828da25999be911", + "sha256:15ab25dd3e620790f40e9ead897f91e79c0d3ce65fe193c8ed6c26cffdd24be7", + "sha256:167d3b62586faef8b6b2275c3218796b12621a60e43f7e9d5845d627b9c9b80e", + "sha256:2b267b70747d82125f1a021506565bdc5609a2b24bcb4773c16d79d2bb260bbd", + "sha256:3bcddaaf6cc5935a300a8387c99f7a7fbbe212a11568ec6cf6e4bc458c048636", + "sha256:3fc38008969796f0f689f1453722a0f463da1b8a6fbee11987830bfbb664f623", + "sha256:47eba38322370347b1c47024defbd36374a211e8dd5b0dcbce7b34fdb6f8847b", + "sha256:48159d96962674eccdca9a3df280e864e8ac75e40a577cc97c5c42667ffabfc5", + "sha256:49ee1a41738a23e98d98b937a0638357a2477bc99e61b0f768a8f654f45d9b7a", + "sha256:4a53aa7c16a60a6857e6b0b165261436396ef7293f8b5c9c828a3a203147ed4a", + "sha256:4b4cd51a57b698b2d06cb9993b7ac8dfe89a3b2878e96bc7948e9f19ff51dba6", + "sha256:51c916108c56aa6e426ce611946f901badac950ee2ddaf302b7ed35d9958970d", + "sha256:550c114a8df0aafe9a05442a1162dfc8fec37e9af1d625ae6060fed6e756f303", + "sha256:58cf54380c3884fb49fdd37dfb7a772632b6701d28edd3e2904743c5e1773602", + "sha256:5b00be98ccd0fc123dcfad31d50030d25fcf31488cde9e61692029cd7394733b", + "sha256:5f93a5db13927a37d2d09637ccca4b2b6b48c19cd9eda7b17a2e9f77edee6a6f", + "sha256:64d0c62d88e67b98a1a5e71987b7aa7b5bcffc7dcee65b635823dbdd0a8dbbd0", + "sha256:73f80bf4cd5d2ca7814da30a120de1f9408ee0619cc75da87d0641273d202a09", + "sha256:752d76472d9804ac60f0078c79cdae8b956f293177acd2316cd1e15149aee132", + "sha256:83c381767e2cc10e93e40281a04852facc4cd9334550e0f392f72d1c0a9c5753", + "sha256:8fefe5868cd082db1186f2837d64cfbfa78b548ea0d0543e9b28935ccce81ce9", + "sha256:9191d68659eda01e448188f60364c7763a7ca6653ed3f87ebb165822153a8547", + "sha256:96f19de485a2925314f5020e85911fb447ff5fbef56e8c7c6927851b95533a1c", + "sha256:9a13dc409f2564de15dd68be65b462ba0dde01b19663720c68c1140c782d1d75", + "sha256:a2c2a947fae7d1062ef08c4e369e0ba2086049a5e598fda41122535557012e9e", + "sha256:a2d4f1513d63c795e82948e1305f31a6d530626e5f9f2605408b300ae6095093", + "sha256:a5bf613e96f49712073de86f20dbdd4014ca18efd4d34ed18c75bd808337851b", + "sha256:a6d2e0f9f7a69403e388894d4ca5ada5c47230716a03f2847cfc7bd1ecb589d6", + "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", + "sha256:ba7c3a7e5f23e215cb271516197030c32aef2e754252c4c70a50aaff7031a2c8", + "sha256:c0022283e9556e0f3643b7c3c03f05063ca72b3063291834cca43234f20c60bb", + "sha256:c174e322bb5783c099aaf87faeb240c8d210686b04bd61dfd05a8e5a83d88969", + "sha256:c9c8e68d8b4a56fda8c025e538e639f8c5953f5073886b596c93ec9b620055e7", + "sha256:cfcac6aa6f42397471e4943e0feb2244549db5c5d01efcd02725b96af417f3fe", + "sha256:d5e73fa573e273e4f2e5ff96f9043858a5e9311e94ffefd88a3186a910c70917", + "sha256:def246fe9e180626731b26e89816e79aae2276f825420a07b4a647abaa84becc", + "sha256:dfbbc74ec68a0fd08cfec1f4b5e8cca3d3cd7de5501b01c4b5d209995033cde9", + "sha256:e160bf9df356d841bb6c180eeeea1834085464626dc1b68fa4e1d59070affdc3", + "sha256:e541c3ef484852ef36545f66209444c48b28661e864ccadb29daddb6a4b8e5f5", + "sha256:f9b0b8a03ef474f56d1a842af1a2e01398b8f7654009823c6d9e0ecff4d5cfbf", + "sha256:f9ee9b52f5f857fbaf9d605a360884f034c92c1c23021fb90b2e39b8e64bede6", + "sha256:fbdd522624141e40948ab3e8cdae6e04c748d78710e9f0f8d4dae2750831de19", + "sha256:fd3d4602dc64914d462924a08c1a9816435a2155d74f325853c1f1ac3b2d9800" + ], + "markers": "python_version >= '3.13'", + "version": "==0.2.2" }, "brotli": { "hashes": [ "sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208", "sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48", "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354", + "sha256:0737ddb3068957cf1b054899b0883830bb1fec522ec76b1098f9b6e0f02d9419", "sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a", "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128", "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c", @@ -140,43 +189,67 @@ "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9", "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a", "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3", + "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757", + "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2", "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438", "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578", "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b", "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b", "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68", + "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0", "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d", + "sha256:2feb1d960f760a575dbc5ab3b1c00504b24caaf6986e2dc2b01c09c87866a943", "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd", "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409", + "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28", "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da", "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50", + "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f", "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0", + "sha256:3ee8a80d67a4334482d9712b8e83ca6b1d9bc7e351931252ebef5d8f7335a547", "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180", + "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0", "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d", + "sha256:4410f84b33374409552ac9b6903507cdb31cd30d2501fc5ca13d18f73548444a", + "sha256:494994f807ba0b92092a163a0a283961369a65f6cbe01e8891132b7a320e61eb", "sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112", "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc", + "sha256:4f3607b129417e111e30637af1b56f24f7a49e64763253bbc275c75fa887d4b2", "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265", "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327", "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95", + "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec", "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd", + "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c", + "sha256:5e55da2c8724191e5b557f8e18943b1b4839b8efc3ef60d65985bcf6f587dd38", "sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914", "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0", "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a", "sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7", + "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368", + "sha256:6974f52a02321b36847cd19d1b8e381bf39939c21efd6ee2fc13a28b0d99348c", "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0", + "sha256:6c6e0c425f22c1c719c42670d561ad682f7bfeeef918edea971a79ac5252437f", "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451", "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f", + "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8", "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e", "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248", + "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c", "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91", "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", + "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7", "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966", + "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9", "sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97", "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d", + "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5", "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf", "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac", + "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b", "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951", "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74", + "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648", "sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60", "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c", "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1", @@ -187,27 +260,44 @@ "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460", "sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751", "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9", + "sha256:a7e53012d2853a07a4a79c00643832161a910674a893d296c9f1259859a289d2", + "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0", "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1", "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474", + "sha256:aea440a510e14e818e67bfc4027880e2fb500c2ccb20ab21c7a7c8b5b4703d75", + "sha256:af6fa6817889314555aede9a919612b23739395ce767fe7fcbea9a80bf140fe5", + "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f", "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2", + "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f", + "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb", "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6", "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9", + "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111", "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2", + "sha256:cb1dac1770878ade83f2ccdf7d25e494f05c9165f5246b46a621cc849341dc01", "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467", "sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619", "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf", "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408", "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579", "sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84", + "sha256:d2b35ca2c7f81d173d2fadc2f4f31e88cc5f7a39ae5b6db5513cf3383b0e0ec7", + "sha256:d342778ef319e1026af243ed0a07c97acf3bad33b9f29e7ae6a1f68fd083e90c", + "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284", + "sha256:d7702622a8b40c49bffb46e1e3ba2e81268d5c04a34f460978c6b5517a34dd52", "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b", "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59", "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752", + "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1", "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80", + "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839", "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0", "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2", "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3", "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64", + "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089", "sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643", + "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b", "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e", "sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985", "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596", @@ -218,181 +308,202 @@ }, "cairocffi": { "hashes": [ - "sha256:78e6bbe47357640c453d0be929fa49cd05cce2e1286f3d2a1ca9cbda7efdb8b7", - "sha256:aa78ee52b9069d7475eeac457389b6275aa92111895d78fbaa2202a52dac112e" + "sha256:2e48ee864884ec4a3a34bfa8c9ab9999f688286eb714a15a43ec9d068c36557b", + "sha256:9803a0e11f6c962f3b0ae2ec8ba6ae45e957a146a004697a1ac1bbf16b073b3f" ], - "markers": "python_version >= '3.7'", - "version": "==1.6.1" + "markers": "python_version >= '3.8'", + "version": "==1.7.1" }, "cairosvg": { "hashes": [ - "sha256:432531d72347291b9a9ebfb6777026b607563fd8719c46ee742db0aef7271ba0", - "sha256:8a5222d4e6c3f86f1f7046b63246877a63b49923a1cd202184c3a634ef546b3b" + "sha256:07cbf4e86317b27a92318a4cac2a4bb37a5e9c1b8a27355d06874b22f85bef9f", + "sha256:eab46dad4674f33267a671dce39b64be245911c901c70d65d2b7b0821e852bf5" ], - "markers": "python_version >= '3.5'", - "version": "==2.7.1" + "markers": "python_version >= '3.9'", + "version": "==2.8.2" }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", + "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43" ], - "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "markers": "python_version >= '3.7'", + "version": "==2025.10.5" }, "cffi": { "hashes": [ - "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", - "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", - "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", - "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", - "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", - "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", - "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", - "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", - "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", - "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", - "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", - "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", - "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", - "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", - "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", - "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", - "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", - "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", - "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", - "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", - "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", - "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", - "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", - "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", - "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", - "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", - "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", - "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", - "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", - "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", - "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", - "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", - "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", - "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", - "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", - "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", - "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", - "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", - "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", - "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", - "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", - "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", - "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", - "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", - "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", - "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", - "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", - "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", - "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", - "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", - "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", - "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" - ], - "markers": "python_version >= '3.8'", - "version": "==1.16.0" + "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", + "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", + "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", + "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", + "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", + "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2", + "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", + "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", + "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65", + "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", + "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", + "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", + "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", + "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a", + "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", + "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", + "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", + "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", + "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", + "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", + "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", + "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", + "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", + "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", + "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165", + "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", + "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", + "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c", + "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", + "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", + "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", + "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", + "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63", + "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", + "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", + "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", + "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", + "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", + "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", + "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", + "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", + "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", + "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", + "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", + "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", + "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", + "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322", + "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", + "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", + "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", + "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", + "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", + "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", + "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", + "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", + "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", + "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", + "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", + "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", + "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", + "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9", + "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", + "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", + "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", + "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", + "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", + "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f", + "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", + "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", + "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", + "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", + "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", + "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", + "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", + "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", + "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", + "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7", + "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", + "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534", + "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", + "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", + "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", + "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", + "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf" + ], + "markers": "python_version >= '3.9'", + "version": "==2.0.0" }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", + "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", + "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", + "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", + "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", + "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", + "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c", + "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", + "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", + "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", + "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", + "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", + "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", + "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", + "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", + "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", + "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", + "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", + "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4", + "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", + "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", + "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", + "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", + "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", + "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", + "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", + "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b", + "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", + "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", + "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", + "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", + "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", + "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", + "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", + "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", + "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", + "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a", + "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40", + "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", + "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", + "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", + "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", + "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", + "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", + "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", + "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", + "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", + "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", + "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9", + "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", + "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", + "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", + "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b", + "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", + "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942", + "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", + "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", + "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b", + "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", + "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", + "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", + "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", + "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", + "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", + "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", + "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", + "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", + "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", + "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", + "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", + "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", + "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb", + "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", + "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557", + "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", + "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", + "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", + "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", + "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.3" }, "colorama": { "hashes": [ @@ -405,11 +516,11 @@ }, "cssselect2": { "hashes": [ - "sha256:1ccd984dab89fc68955043aca4e1b03e0cf29cad9880f6e28e3ba7a74b14aa5a", - "sha256:fd23a65bfd444595913f02fc71f6b286c29261e354c41d722ca7a261a49b5969" + "sha256:46fc70ebc41ced7a32cd42d58b1884d72ade23d21e5a4eaaf022401c13f0e76e", + "sha256:7674ffb954a3b46162392aee2a3a0aedb2e14ecf99fcc28644900f4e6e3e9d3a" ], - "markers": "python_version >= '3.7'", - "version": "==0.7.0" + "markers": "python_version >= '3.9'", + "version": "==0.8.0" }, "defusedxml": { "hashes": [ @@ -424,19 +535,19 @@ "speed" ], "hashes": [ - "sha256:4560f70f2eddba7e83370ecebd237ac09fbb4980dc66507482b0c0e5b8f76b9c", - "sha256:9da4679fc3cb10c64b388284700dc998663e0e57328283bbfcfc2525ec5960a6" + "sha256:69835269d73d9889a2f0efff4c91264a18998db0fdc4295a3c886fe9196dea4e", + "sha256:92bb3ef9dbe08525803be1e357bc0191f59ae16956690fc96c34f40bcd02c649" ], - "markers": "python_full_version >= '3.8.0'", - "version": "==2.3.2" + "markers": "python_version >= '3.8'", + "version": "==2.6.3" }, "dnspython": { "hashes": [ - "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8", - "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984" + "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", + "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f" ], - "markers": "python_version >= '3.8' and python_version < '4.0'", - "version": "==2.4.2" + "markers": "python_version >= '3.10'", + "version": "==2.8.0" }, "emoji": { "hashes": [ @@ -449,78 +560,147 @@ }, "frozenlist": { "hashes": [ - "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6", - "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01", - "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251", - "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9", - "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b", - "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87", - "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf", - "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f", - "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0", - "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2", - "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b", - "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc", - "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c", - "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467", - "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9", - "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1", - "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a", - "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79", - "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167", - "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300", - "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf", - "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea", - "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2", - "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab", - "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3", - "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb", - "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087", - "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc", - "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8", - "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62", - "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f", - "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326", - "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c", - "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431", - "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963", - "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7", - "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef", - "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3", - "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956", - "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781", - "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472", - "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc", - "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839", - "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672", - "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3", - "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503", - "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d", - "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8", - "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b", - "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc", - "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f", - "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559", - "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b", - "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95", - "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb", - "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963", - "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919", - "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f", - "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3", - "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", - "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" - ], - "markers": "python_version >= '3.8'", - "version": "==1.4.0" + "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", + "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", + "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", + "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", + "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", + "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", + "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", + "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", + "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", + "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", + "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", + "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", + "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4", + "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", + "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", + "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", + "sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3", + "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", + "sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087", + "sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068", + "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7", + "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", + "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", + "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", + "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", + "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", + "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", + "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", + "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", + "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", + "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", + "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", + "sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675", + "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", + "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", + "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", + "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", + "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", + "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", + "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", + "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", + "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", + "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c", + "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", + "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", + "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", + "sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5", + "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", + "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", + "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", + "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", + "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", + "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", + "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", + "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", + "sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95", + "sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1", + "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", + "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", + "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6", + "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", + "sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459", + "sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a", + "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", + "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", + "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", + "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", + "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186", + "sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6", + "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", + "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e", + "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", + "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", + "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450", + "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", + "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", + "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", + "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", + "sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178", + "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", + "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", + "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", + "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", + "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", + "sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61", + "sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca", + "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad", + "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", + "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a", + "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", + "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", + "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011", + "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", + "sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103", + "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", + "sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda", + "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", + "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", + "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e", + "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", + "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef", + "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", + "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", + "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", + "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", + "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", + "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", + "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", + "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", + "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", + "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", + "sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47", + "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", + "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", + "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f", + "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff", + "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", + "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", + "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", + "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", + "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", + "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565", + "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", + "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", + "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2", + "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", + "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", + "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", + "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", + "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd" + ], + "markers": "python_version >= '3.9'", + "version": "==1.8.0" }, "idna": { "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], - "markers": "python_version >= '3.5'", - "version": "==3.4" + "markers": "python_version >= '3.6'", + "version": "==3.10" }, "isodate": { "hashes": [ @@ -551,83 +731,119 @@ }, "multidict": { "hashes": [ - "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", - "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", - "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", - "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", - "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", - "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", - "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", - "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", - "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", - "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", - "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", - "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", - "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", - "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", - "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", - "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", - "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", - "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", - "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", - "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", - "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", - "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", - "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", - "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", - "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", - "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", - "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", - "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", - "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", - "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", - "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", - "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", - "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", - "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", - "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", - "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", - "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", - "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", - "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", - "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", - "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", - "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", - "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", - "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", - "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", - "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", - "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", - "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", - "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", - "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", - "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", - "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", - "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", - "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", - "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", - "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", - "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", - "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", - "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", - "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", - "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", - "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", - "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", - "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", - "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", - "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", - "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", - "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", - "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", - "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", - "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", - "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", - "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", - "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" - ], - "markers": "python_version >= '3.7'", - "version": "==6.0.4" + "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9", + "sha256:01d0959807a451fe9fdd4da3e139cb5b77f7328baf2140feeaf233e1d777b729", + "sha256:024ce601f92d780ca1617ad4be5ac15b501cc2414970ffa2bb2bbc2bd5a68fa5", + "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e", + "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138", + "sha256:0af5f9dee472371e36d6ae38bde009bd8ce65ac7335f55dcc240379d7bed1495", + "sha256:0b2e886624be5773e69cf32bcb8534aecdeb38943520b240fed3d5596a430f2f", + "sha256:0c5cbac6b55ad69cb6aa17ee9343dfbba903118fd530348c330211dc7aa756d1", + "sha256:0e0558693063c75f3d952abf645c78f3c5dfdd825a41d8c4d8156fc0b0da6e7e", + "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6", + "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8", + "sha256:105245cc6b76f51e408451a844a54e6823bbd5a490ebfe5bdfc79798511ceded", + "sha256:10a68a9191f284fe9d501fef4efe93226e74df92ce7a24e301371293bd4918ae", + "sha256:14616a30fe6d0a48d0a48d1a633ab3b8bec4cf293aac65f32ed116f620adfd69", + "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364", + "sha256:163c7ea522ea9365a8a57832dea7618e6cbdc3cd75f8c627663587459a4e328f", + "sha256:17d2cbbfa6ff20821396b25890f155f40c986f9cfbce5667759696d83504954f", + "sha256:190766dac95aab54cae5b152a56520fd99298f32a1266d66d27fdd1b5ac00f4e", + "sha256:1a0ccbfe93ca114c5d65a2471d52d8829e56d467c97b0e341cf5ee45410033b3", + "sha256:21f216669109e02ef3e2415ede07f4f8987f00de8cdfa0cc0b3440d42534f9f0", + "sha256:22e38b2bc176c5eb9c0a0e379f9d188ae4cd8b28c0f53b52bce7ab0a9e534657", + "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", + "sha256:2a4c6875c37aae9794308ec43e3530e4aa0d36579ce38d89979bbf89582002bb", + "sha256:34d8f2a5ffdceab9dcd97c7a016deb2308531d5f0fced2bb0c9e1df45b3363d7", + "sha256:350f6b0fe1ced61e778037fdc7613f4051c8baf64b1ee19371b42a3acdb016a0", + "sha256:37b7187197da6af3ee0b044dbc9625afd0c885f2800815b228a0e70f9a7f473d", + "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b", + "sha256:3ba5aaf600edaf2a868a391779f7a85d93bed147854925f34edd24cc70a3e141", + "sha256:3bb0eae408fa1996d87247ca0d6a57b7fc1dcf83e8a5c47ab82c558c250d4adf", + "sha256:3f8e2384cb83ebd23fd07e9eada8ba64afc4c759cd94817433ab8c81ee4b403f", + "sha256:40cd05eaeb39e2bc8939451f033e57feaa2ac99e07dbca8afe2be450a4a3b6cf", + "sha256:43868297a5759a845fa3a483fb4392973a95fb1de891605a3728130c52b8f40f", + "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24", + "sha256:467fe64138cfac771f0e949b938c2e1ada2b5af22f39692aa9258715e9ea613a", + "sha256:49517449b58d043023720aa58e62b2f74ce9b28f740a0b5d33971149553d72aa", + "sha256:497a2954adc25c08daff36f795077f63ad33e13f19bfff7736e72c785391534f", + "sha256:4a1fb393a2c9d202cb766c76208bd7945bc194eba8ac920ce98c6e458f0b524b", + "sha256:4bb7627fd7a968f41905a4d6343b0d63244a0623f006e9ed989fa2b78f4438a0", + "sha256:4d09384e75788861e046330308e7af54dd306aaf20eb760eb1d0de26b2bea2cb", + "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d", + "sha256:52e3c8d43cdfff587ceedce9deb25e6ae77daba560b626e97a56ddcad3756879", + "sha256:55624b3f321d84c403cb7d8e6e982f41ae233d85f85db54ba6286f7295dc8a9c", + "sha256:56c6b3652f945c9bc3ac6c8178cd93132b8d82dd581fcbc3a00676c51302bc1a", + "sha256:580b643b7fd2c295d83cad90d78419081f53fd532d1f1eb67ceb7060f61cff0d", + "sha256:59e8d40ab1f5a8597abcef00d04845155a5693b5da00d2c93dbe88f2050f2812", + "sha256:5df8afd26f162da59e218ac0eefaa01b01b2e6cd606cffa46608f699539246da", + "sha256:630f70c32b8066ddfd920350bc236225814ad94dfa493fe1910ee17fe4365cbb", + "sha256:66247d72ed62d5dd29752ffc1d3b88f135c6a8de8b5f63b7c14e973ef5bda19e", + "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287", + "sha256:6bf2f10f70acc7a2446965ffbc726e5fc0b272c97a90b485857e5c70022213eb", + "sha256:6c84378acd4f37d1b507dfa0d459b449e2321b3ba5f2338f9b085cf7a7ba95eb", + "sha256:6d46a180acdf6e87cc41dc15d8f5c2986e1e8739dc25dbb7dac826731ef381a4", + "sha256:756989334015e3335d087a27331659820d53ba432befdef6a718398b0a8493ad", + "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f", + "sha256:7dd57515bebffd8ebd714d101d4c434063322e4fe24042e90ced41f18b6d3395", + "sha256:7f683a551e92bdb7fac545b9c6f9fa2aebdeefa61d607510b3533286fcab67f5", + "sha256:87a32d20759dc52a9e850fe1061b6e41ab28e2998d44168a8a341b99ded1dba0", + "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793", + "sha256:8c91cdb30809a96d9ecf442ec9bc45e8cfaa0f7f8bdf534e082c2443a196727e", + "sha256:8c9854df0eaa610a23494c32a6f44a3a550fb398b6b51a56e8c6b9b3689578db", + "sha256:8e42332cf8276bb7645d310cdecca93a16920256a5b01bebf747365f86a1675b", + "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c", + "sha256:967af5f238ebc2eb1da4e77af5492219fbd9b4b812347da39a7b5f5c72c0fa45", + "sha256:9a950b7cf54099c1209f455ac5970b1ea81410f2af60ed9eb3c3f14f0bfcf987", + "sha256:a1b20a9d56b2d81e2ff52ecc0670d583eaabaa55f402e8d16dd062373dbbe796", + "sha256:a506a77ddee1efcca81ecbeae27ade3e09cdf21a8ae854d766c2bb4f14053f92", + "sha256:a59c63061f1a07b861c004e53869eb1211ffd1a4acbca330e3322efa6dd02978", + "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802", + "sha256:a693fc5ed9bdd1c9e898013e0da4dcc640de7963a371c0bd458e50e046bf6438", + "sha256:aaea28ba20a9026dfa77f4b80369e51cb767c61e33a2d4043399c67bd95fb7c6", + "sha256:ad8850921d3a8d8ff6fbef790e773cecfc260bbfa0566998980d3fa8f520bc4a", + "sha256:ad887a8250eb47d3ab083d2f98db7f48098d13d42eb7a3b67d8a5c795f224ace", + "sha256:ae9408439537c5afdca05edd128a63f56a62680f4b3c234301055d7a2000220f", + "sha256:af7618b591bae552b40dbb6f93f5518328a949dac626ee75927bba1ecdeea9f4", + "sha256:b6819f83aef06f560cb15482d619d0e623ce9bf155115150a85ab11b8342a665", + "sha256:b8aa6f0bd8125ddd04a6593437bad6a7e70f300ff4180a531654aa2ab3f6d58f", + "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402", + "sha256:b95494daf857602eccf4c18ca33337dd2be705bccdb6dddbfc9d513e6addb9d9", + "sha256:b9e5853bbd7264baca42ffc53391b490d65fe62849bf2c690fa3f6273dbcd0cb", + "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7", + "sha256:be5bf4b3224948032a845d12ab0f69f208293742df96dc14c4ff9b09e508fc17", + "sha256:c5c97aa666cf70e667dfa5af945424ba1329af5dd988a437efeb3a09430389fb", + "sha256:c7a0e9b561e6460484318a7612e725df1145d46b0ef57c6b9866441bf6e27e0c", + "sha256:caebafea30ed049c57c673d0b36238b1748683be2593965614d7b0e99125c877", + "sha256:cbbc54e58b34c3bae389ef00046be0961f30fef7cb0dd9c7756aee376a4f7683", + "sha256:cc356250cffd6e78416cf5b40dc6a74f1edf3be8e834cf8862d9ed5265cf9b0e", + "sha256:ce9a40fbe52e57e7edf20113a4eaddfacac0561a0879734e636aa6d4bb5e3fb0", + "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3", + "sha256:d24f351e4d759f5054b641c81e8291e5d122af0fca5c72454ff77f7cbe492de8", + "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd", + "sha256:d8c112f7a90d8ca5d20213aa41eac690bb50a76da153e3afb3886418e61cb22e", + "sha256:d9890d68c45d1aeac5178ded1d1cccf3bc8d7accf1f976f79bf63099fb16e4bd", + "sha256:dadf95aa862714ea468a49ad1e09fe00fcc9ec67d122f6596a8d40caf6cec7d0", + "sha256:db6a3810eec08280a172a6cd541ff4a5f6a97b161d93ec94e6c4018917deb6b7", + "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7", + "sha256:e167bf899c3d724f9662ef00b4f7fef87a19c22b2fead198a6f68b263618df52", + "sha256:e1b93790ed0bc26feb72e2f08299691ceb6da5e9e14a0d13cc74f1869af327a0", + "sha256:e5b1413361cef15340ab9dc61523e653d25723e82d488ef7d60a12878227ed50", + "sha256:ecab51ad2462197a4c000b6d5701fc8585b80eecb90583635d7e327b7b6923eb", + "sha256:ed3b94c5e362a8a84d69642dbeac615452e8af9b8eb825b7bc9f31a53a1051e2", + "sha256:ed8358ae7d94ffb7c397cecb62cbac9578a83ecefc1eba27b9090ee910e2efb6", + "sha256:edfdcae97cdc5d1a89477c436b61f472c4d40971774ac4729c613b4b133163cb", + "sha256:ee25f82f53262f9ac93bd7e58e47ea1bdcc3393cef815847e397cba17e284210", + "sha256:f3be27440f7644ab9a13a6fc86f09cdd90b347c3c5e30c6d6d860de822d7cb53", + "sha256:f46a6e8597f9bd71b31cc708195d42b634c8527fecbcf93febf1052cacc1f16e", + "sha256:f6eb37d511bfae9e13e82cb4d1af36b91150466f24d9b2b8a9785816deb16605", + "sha256:f8d4916a81697faec6cb724a273bd5457e4c6c43d82b29f9dc02c5542fd21fc9", + "sha256:f93b2b2279883d1d0a9e1bd01f312d6fc315c5e4c1f09e112e4736e2f650bc4e", + "sha256:f9867e55590e0855bcec60d4f9a092b69476db64573c9fe17e92b0c50614c16a", + "sha256:f996b87b420995a9174b2a7c1a8daf7db4750be6848b03eb5e639674f7963773" + ], + "markers": "python_version >= '3.9'", + "version": "==6.6.4" }, "natural": { "hashes": [ @@ -638,58 +854,92 @@ }, "orjson": { "hashes": [ - "sha256:06ad5543217e0e46fd7ab7ea45d506c76f878b87b1b4e369006bdb01acc05a83", - "sha256:0a73160e823151f33cdc05fe2cea557c5ef12fdf276ce29bb4f1c571c8368a60", - "sha256:1234dc92d011d3554d929b6cf058ac4a24d188d97be5e04355f1b9223e98bbe9", - "sha256:1d0dc4310da8b5f6415949bd5ef937e60aeb0eb6b16f95041b5e43e6200821fb", - "sha256:2a11b4b1a8415f105d989876a19b173f6cdc89ca13855ccc67c18efbd7cbd1f8", - "sha256:2e2ecd1d349e62e3960695214f40939bbfdcaeaaa62ccc638f8e651cf0970e5f", - "sha256:3a2ce5ea4f71681623f04e2b7dadede3c7435dfb5e5e2d1d0ec25b35530e277b", - "sha256:3e892621434392199efb54e69edfff9f699f6cc36dd9553c5bf796058b14b20d", - "sha256:3fb205ab52a2e30354640780ce4587157a9563a68c9beaf52153e1cea9aa0921", - "sha256:4689270c35d4bb3102e103ac43c3f0b76b169760aff8bcf2d401a3e0e58cdb7f", - "sha256:49f8ad582da6e8d2cf663c4ba5bf9f83cc052570a3a767487fec6af839b0e777", - "sha256:4bd176f528a8151a6efc5359b853ba3cc0e82d4cd1fab9c1300c5d957dc8f48c", - "sha256:4cf7837c3b11a2dfb589f8530b3cff2bd0307ace4c301e8997e95c7468c1378e", - "sha256:4fd72fab7bddce46c6826994ce1e7de145ae1e9e106ebb8eb9ce1393ca01444d", - "sha256:5148bab4d71f58948c7c39d12b14a9005b6ab35a0bdf317a8ade9a9e4d9d0bd5", - "sha256:5869e8e130e99687d9e4be835116c4ebd83ca92e52e55810962446d841aba8de", - "sha256:602a8001bdf60e1a7d544be29c82560a7b49319a0b31d62586548835bbe2c862", - "sha256:61804231099214e2f84998316f3238c4c2c4aaec302df12b21a64d72e2a135c7", - "sha256:666c6fdcaac1f13eb982b649e1c311c08d7097cbda24f32612dae43648d8db8d", - "sha256:674eb520f02422546c40401f4efaf8207b5e29e420c17051cddf6c02783ff5ca", - "sha256:7ec960b1b942ee3c69323b8721df2a3ce28ff40e7ca47873ae35bfafeb4555ca", - "sha256:7f433be3b3f4c66016d5a20e5b4444ef833a1f802ced13a2d852c637f69729c1", - "sha256:7f8fb7f5ecf4f6355683ac6881fd64b5bb2b8a60e3ccde6ff799e48791d8f864", - "sha256:81a3a3a72c9811b56adf8bcc829b010163bb2fc308877e50e9910c9357e78521", - "sha256:858379cbb08d84fe7583231077d9a36a1a20eb72f8c9076a45df8b083724ad1d", - "sha256:8b9ba0ccd5a7f4219e67fbbe25e6b4a46ceef783c42af7dbc1da548eb28b6531", - "sha256:92af0d00091e744587221e79f68d617b432425a7e59328ca4c496f774a356071", - "sha256:9ebbdbd6a046c304b1845e96fbcc5559cd296b4dfd3ad2509e33c4d9ce07d6a1", - "sha256:9edd2856611e5050004f4722922b7b1cd6268da34102667bd49d2a2b18bafb81", - "sha256:a353bf1f565ed27ba71a419b2cd3db9d6151da426b61b289b6ba1422a702e643", - "sha256:b5b7d4a44cc0e6ff98da5d56cde794385bdd212a86563ac321ca64d7f80c80d1", - "sha256:b90f340cb6397ec7a854157fac03f0c82b744abdd1c0941a024c3c29d1340aff", - "sha256:c18a4da2f50050a03d1da5317388ef84a16013302a5281d6f64e4a3f406aabc4", - "sha256:c338ed69ad0b8f8f8920c13f529889fe0771abbb46550013e3c3d01e5174deef", - "sha256:c5a02360e73e7208a872bf65a7554c9f15df5fe063dc047f79738998b0506a14", - "sha256:c62b6fa2961a1dcc51ebe88771be5319a93fd89bd247c9ddf732bc250507bc2b", - "sha256:c812312847867b6335cfb264772f2a7e85b3b502d3a6b0586aa35e1858528ab1", - "sha256:c943b35ecdf7123b2d81d225397efddf0bce2e81db2f3ae633ead38e85cd5ade", - "sha256:ce0a29c28dfb8eccd0f16219360530bc3cfdf6bf70ca384dacd36e6c650ef8e8", - "sha256:cf80b550092cc480a0cbd0750e8189247ff45457e5a023305f7ef1bcec811616", - "sha256:cff7570d492bcf4b64cc862a6e2fb77edd5e5748ad715f487628f102815165e9", - "sha256:d2c1e559d96a7f94a4f581e2a32d6d610df5840881a8cba8f25e446f4d792df3", - "sha256:deeb3922a7a804755bbe6b5be9b312e746137a03600f488290318936c1a2d4dc", - "sha256:e28a50b5be854e18d54f75ef1bb13e1abf4bc650ab9d635e4258c58e71eb6ad5", - "sha256:e99c625b8c95d7741fe057585176b1b8783d46ed4b8932cf98ee145c4facf499", - "sha256:ec6f18f96b47299c11203edfbdc34e1b69085070d9a3d1f302810cc23ad36bf3", - "sha256:ed8bc367f725dfc5cabeed1ae079d00369900231fbb5a5280cf0736c30e2adf7", - "sha256:ee5926746232f627a3be1cc175b2cfad24d0170d520361f4ce3fa2fd83f09e1d", - "sha256:f295efcd47b6124b01255d1491f9e46f17ef40d3d7eabf7364099e463fb45f0f", - "sha256:fb0b361d73f6b8eeceba47cd37070b5e6c9de5beaeaa63a1cb35c7e1a73ef088" - ], - "version": "==3.9.10" + "sha256:00f1a271e56d511d1569937c0447d7dce5a99a33ea0dec76673706360a051904", + "sha256:0c212cfdd90512fe722fa9bd620de4d46cda691415be86b2e02243242ae81873", + "sha256:0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d", + "sha256:0e92a4e83341ef79d835ca21b8bd13e27c859e4e9e4d7b63defc6e58462a3710", + "sha256:11c6d71478e2cbea0a709e8a06365fa63da81da6498a53e4c4f065881d21ae8f", + "sha256:124d5ba71fee9c9902c4a7baa9425e663f7f0aecf73d31d54fe3dd357d62c1a7", + "sha256:18bd1435cb1f2857ceb59cfb7de6f92593ef7b831ccd1b9bfb28ca530e539dce", + "sha256:1c0603b1d2ffcd43a411d64797a19556ef76958aef1c182f22dc30860152a98a", + "sha256:2030c01cbf77bc67bee7eef1e7e31ecf28649353987775e3583062c752da0077", + "sha256:2039b7847ba3eec1f5886e75e6763a16e18c68a63efc4b029ddf994821e2e66b", + "sha256:212e67806525d2561efbfe9e799633b17eb668b8964abed6b5319b2f1cfbae1f", + "sha256:215c595c792a87d4407cb72dd5e0f6ee8e694ceeb7f9102b533c5a9bf2a916bb", + "sha256:22724d80ee5a815a44fc76274bb7ba2e7464f5564aacb6ecddaa9970a83e3225", + "sha256:29be5ac4164aa8bdcba5fa0700a3c9c316b411d8ed9d39ef8a882541bd452fae", + "sha256:29cb1f1b008d936803e2da3d7cba726fc47232c45df531b29edf0b232dd737e7", + "sha256:2b7b153ed90ababadbef5c3eb39549f9476890d339cf47af563aea7e07db2451", + "sha256:2d68bf97a771836687107abfca089743885fb664b90138d8761cce61d5625d55", + "sha256:317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804", + "sha256:3782d2c60b8116772aea8d9b7905221437fdf53e7277282e8d8b07c220f96cca", + "sha256:3d721fee37380a44f9d9ce6c701b3960239f4fb3d5ceea7f31cbd43882edaa2f", + "sha256:414f71e3bdd5573893bf5ecdf35c32b213ed20aa15536fe2f588f946c318824f", + "sha256:524b765ad888dc5518bbce12c77c2e83dee1ed6b0992c1790cc5fb49bb4b6667", + "sha256:56afaf1e9b02302ba636151cfc49929c1bb66b98794291afd0e5f20fecaf757c", + "sha256:58533f9e8266cb0ac298e259ed7b4d42ed3fa0b78ce76860626164de49e0d467", + "sha256:5ff835b5d3e67d9207343effb03760c00335f8b5285bfceefd4dc967b0e48f6a", + "sha256:61dcdad16da5bb486d7227a37a2e789c429397793a6955227cedbd7252eb5a27", + "sha256:6890ace0809627b0dff19cfad92d69d0fa3f089d3e359a2a532507bb6ba34efb", + "sha256:6be2f1b5d3dc99a5ce5ce162fc741c22ba9f3443d3dd586e6a1211b7bc87bc7b", + "sha256:6e8e0c3b85575a32f2ffa59de455f85ce002b8bdc0662d6b9c2ed6d80ab5d204", + "sha256:73b92a5b69f31b1a58c0c7e31080aeaec49c6e01b9522e71ff38d08f15aa56de", + "sha256:7909ae2460f5f494fecbcd10613beafe40381fd0316e35d6acb5f3a05bfda167", + "sha256:79b44319268af2eaa3e315b92298de9a0067ade6e6003ddaef72f8e0bedb94f1", + "sha256:828e3149ad8815dc14468f36ab2a4b819237c155ee1370341b91ea4c8672d2ee", + "sha256:84fd82870b97ae3cdcea9d8746e592b6d40e1e4d4527835fc520c588d2ded04f", + "sha256:88dcfc514cfd1b0de038443c7b3e6a9797ffb1b3674ef1fd14f701a13397f82d", + "sha256:8ab962931015f170b97a3dd7bd933399c1bae8ed8ad0fb2a7151a5654b6941c7", + "sha256:8b13974dc8ac6ba22feaa867fc19135a3e01a134b4f7c9c28162fed4d615008a", + "sha256:8c752089db84333e36d754c4baf19c0e1437012242048439c7e80eb0e6426e3b", + "sha256:8e531abd745f51f8035e207e75e049553a86823d189a51809c078412cefb399a", + "sha256:90368277087d4af32d38bd55f9da2ff466d25325bf6167c8f382d8ee40cb2bbc", + "sha256:913f629adef31d2d350d41c051ce7e33cf0fd06a5d1cb28d49b1899b23b903aa", + "sha256:976c6f1975032cc327161c65d4194c549f2589d88b105a5e3499429a54479770", + "sha256:97dceed87ed9139884a55db8722428e27bd8452817fbf1869c58b49fecab1120", + "sha256:9b8761b6cf04a856eb544acdd82fc594b978f12ac3602d6374a7edb9d86fd2c2", + "sha256:9d2ae0cc6aeb669633e0124531f342a17d8e97ea999e42f12a5ad4adaa304c5f", + "sha256:9d8787bdfbb65a85ea76d0e96a3b1bed7bf0fbcb16d40408dc1172ad784a49d2", + "sha256:9dba358d55aee552bd868de348f4736ca5a4086d9a62e2bfbbeeb5629fe8b0cc", + "sha256:9f1587f26c235894c09e8b5b7636a38091a9e6e7fe4531937534749c04face43", + "sha256:a0169ebd1cbd94b26c7a7ad282cf5c2744fce054133f959e02eb5265deae1872", + "sha256:ac9e05f25627ffc714c21f8dfe3a579445a5c392a9c8ae7ba1d0e9fb5333f56e", + "sha256:ae8b756575aaa2a855a75192f356bbda11a89169830e1439cfb1a3e1a6dde7be", + "sha256:af40c6612fd2a4b00de648aa26d18186cd1322330bd3a3cc52f87c699e995810", + "sha256:b67e71e47caa6680d1b6f075a396d04fa6ca8ca09aafb428731da9b3ea32a5a6", + "sha256:b822caf5b9752bc6f246eb08124c3d12bf2175b66ab74bac2ef3bbf9221ce1b2", + "sha256:ba21dbb2493e9c653eaffdc38819b004b7b1b246fb77bfc93dc016fe664eac91", + "sha256:bb93562146120bb51e6b154962d3dadc678ed0fce96513fa6bc06599bb6f6edc", + "sha256:bc779b4f4bba2847d0d2940081a7b6f7b5877e05408ffbb74fa1faf4a136c424", + "sha256:bc8bc85b81b6ac9fc4dae393a8c159b817f4c2c9dee5d12b773bddb3b95fc07e", + "sha256:bd4b909ce4c50faa2192da6bb684d9848d4510b736b0611b6ab4020ea6fd2d23", + "sha256:bfc27516ec46f4520b18ef645864cee168d2a027dbf32c5537cb1f3e3c22dac1", + "sha256:c5189a5dab8b0312eadaf9d58d3049b6a52c454256493a557405e77a3d67ab7f", + "sha256:c9416cc19a349c167ef76135b2fe40d03cea93680428efee8771f3e9fb66079d", + "sha256:cf4b81227ec86935568c7edd78352a92e97af8da7bd70bdfdaa0d2e0011a1ab4", + "sha256:d2489b241c19582b3f1430cc5d732caefc1aaf378d97e7fb95b9e56bed11725f", + "sha256:d61cd543d69715d5fc0a690c7c6f8dcc307bc23abef9738957981885f5f38229", + "sha256:d7d012ebddffcce8c85734a6d9e5f08180cd3857c5f5a3ac70185b43775d043d", + "sha256:d7d18dd34ea2e860553a579df02041845dee0af8985dff7f8661306f95504ddf", + "sha256:d8b11701bc43be92ea42bd454910437b355dfb63696c06fe953ffb40b5f763b4", + "sha256:dd759f75d6b8d1b62012b7f5ef9461d03c804f94d539a5515b454ba3a6588038", + "sha256:e0a23b41f8f98b4e61150a03f83e4f0d566880fe53519d445a962929a4d21045", + "sha256:e44fbe4000bd321d9f3b648ae46e0196d21577cf66ae684a96ff90b1f7c93633", + "sha256:e6fbaf48a744b94091a56c62897b27c31ee2da93d826aa5b207131a1e13d4064", + "sha256:e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc", + "sha256:eabcf2e84f1d7105f84580e03012270c7e97ecb1fb1618bda395061b2a84a049", + "sha256:f5aa4682912a450c2db89cbd92d356fef47e115dffba07992555542f344d301b", + "sha256:f66b001332a017d7945e177e282a40b6997056394e3ed7ddb41fb1813b83e824", + "sha256:f83abab5bacb76d9c821fd5c07728ff224ed0e52d7a71b7b3de822f3df04e15c", + "sha256:f8d902867b699bcd09c176a280b1acdab57f924489033e53d0afe79817da37e6", + "sha256:f9d4a5e041ae435b815e568537755773d05dac031fee6a57b4ba70897a44d9d2", + "sha256:fafb1a99d740523d964b15c8db4eabbfc86ff29f84898262bf6e3e4c9e97e43e", + "sha256:fbecb9709111be913ae6879b07bafd4b0785b44c1eb5cac8ac76da048b3885a1", + "sha256:fd7ff459fb393358d3a155d25b275c60b07a2c83dcd7ea962b1923f5a1134569", + "sha256:ff94112e0098470b665cb0ed06efb187154b63649403b8d5e9aedeb482b4548c" + ], + "markers": "python_version >= '3.9'", + "version": "==3.11.3" }, "packaging": { "hashes": [ @@ -710,217 +960,429 @@ }, "pillow": { "hashes": [ - "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d", - "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de", - "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616", - "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839", - "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099", - "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a", - "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219", - "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106", - "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b", - "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412", - "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b", - "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7", - "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2", - "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7", - "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14", - "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f", - "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27", - "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57", - "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262", - "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28", - "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610", - "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172", - "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273", - "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e", - "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d", - "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818", - "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f", - "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9", - "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01", - "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7", - "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651", - "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312", - "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80", - "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666", - "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061", - "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b", - "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992", - "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593", - "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4", - "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db", - "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba", - "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd", - "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e", - "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212", - "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb", - "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2", - "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34", - "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256", - "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f", - "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2", - "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38", - "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996", - "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", - "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" - ], - "markers": "python_version >= '3.8'", - "version": "==10.1.0" + "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", + "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", + "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e", + "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", + "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", + "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", + "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06", + "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", + "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", + "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", + "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", + "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", + "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", + "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", + "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", + "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f", + "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", + "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860", + "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", + "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", + "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", + "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4", + "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", + "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", + "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", + "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", + "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", + "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", + "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", + "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967", + "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", + "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", + "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", + "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae", + "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", + "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", + "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f", + "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", + "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", + "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", + "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27", + "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", + "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", + "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", + "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc", + "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", + "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad", + "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", + "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", + "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978", + "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb", + "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", + "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0", + "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9", + "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", + "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", + "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", + "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081", + "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", + "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", + "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", + "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", + "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f", + "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", + "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", + "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", + "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", + "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6", + "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f", + "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", + "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", + "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", + "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", + "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d", + "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", + "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", + "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", + "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", + "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", + "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", + "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", + "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", + "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", + "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", + "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe", + "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a", + "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", + "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", + "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", + "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a", + "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b", + "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", + "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25", + "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", + "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada", + "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c", + "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71", + "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", + "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", + "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", + "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", + "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50", + "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", + "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", + "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", + "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3" + ], + "markers": "python_version >= '3.9'", + "version": "==11.3.0" + }, + "propcache": { + "hashes": [ + "sha256:009093c9b5dbae114a5958e6a649f8a5d94dd6866b0f82b60395eb92c58002d4", + "sha256:015b2ca2f98ea9e08ac06eecc409d5d988f78c5fd5821b2ad42bc9afcd6b1557", + "sha256:01c0ebc172ca28e9d62876832befbf7f36080eee6ed9c9e00243de2a8089ad57", + "sha256:02e071548b6a376e173b0102c3f55dc16e7d055b5307d487e844c320e38cacf2", + "sha256:0363a696a9f24b37a04ed5e34c2e07ccbe92798c998d37729551120a1bb744c4", + "sha256:0596d2ae99d74ca436553eb9ce11fe4163dc742fcf8724ebe07d7cb0db679bb1", + "sha256:075ca32384294434344760fdcb95f7833e1d7cf7c4e55f0e726358140179da35", + "sha256:077a32977399dc05299b16e793210341a0b511eb0a86d1796873e83ce47334cc", + "sha256:082a643479f49a6778dcd68a80262fc324b14fd8e9b1a5380331fe41adde1738", + "sha256:087e2d3d7613e1b59b2ffca0daabd500c1a032d189c65625ee05ea114afcad0b", + "sha256:0964c55c95625193defeb4fd85f8f28a9a754ed012cab71127d10e3dc66b1373", + "sha256:0b04ac2120c161416c866d0b6a4259e47e92231ff166b518cc0efb95777367c3", + "sha256:0b12df77eb19266efd146627a65b8ad414f9d15672d253699a50c8205661a820", + "sha256:0cd30341142c68377cf3c4e2d9f0581e6e528694b2d57c62c786be441053d2fc", + "sha256:0ea11fceb31fa95b0fa2007037f19e922e2caceb7dc6c6cac4cb56e2d291f1a2", + "sha256:184c779363740d6664982ad05699f378f7694220e2041996f12b7c2a4acdcad0", + "sha256:1927b78dd75fc31a7fdc76cc7039e39f3170cb1d0d9a271e60f0566ecb25211a", + "sha256:1cdabd60e109506462e6a7b37008e57979e737dc6e7dfbe1437adcfe354d1a0a", + "sha256:1e7fa29c71ffa8d6a37324258737d09475f84715a6e8c350f67f0bc8e5e44993", + "sha256:1e7fd82d4a5b7583588f103b0771e43948532f1292105f13ee6f3b300933c4ca", + "sha256:2015218812ee8f13bbaebc9f52b1e424cc130b68d4857bef018e65e3834e1c4d", + "sha256:213eb0d3bc695a70cffffe11a1c2e1c2698d89ffd8dba35a49bc44a035d45c93", + "sha256:2166466a666a5bebc332cd209cad77d996fad925ca7e8a2a6310ba9e851ae641", + "sha256:227892597953611fce2601d49f1d1f39786a6aebc2f253c2de775407f725a3f6", + "sha256:22f589652ee38de96aa58dd219335604e09666092bc250c1d9c26a55bcef9932", + "sha256:236c8da353ea7c22a8e963ab78cddb1126f700ae9538e2c4c6ef471e5545494b", + "sha256:24403152e41abf09488d3ae9c0c3bf7ff93e2fb12b435390718f21810353db28", + "sha256:26692850120241a99bb4a4eec675cd7b4fdc431144f0d15ef69f7f8599f6165f", + "sha256:2a4bf309d057327f1f227a22ac6baf34a66f9af75e08c613e47c4d775b06d6c7", + "sha256:2af6de831a26f42a3f94592964becd8d7f238551786d7525807f02e53defbd13", + "sha256:2c46d37955820dd883cf9156ceb7825b8903e910bdd869902e20a5ac4ecd2c8b", + "sha256:33ad7d37b9a386f97582f5d042cc7b8d4b3591bb384cf50866b749a17e4dba90", + "sha256:34000e31795bdcda9826e0e70e783847a42e3dcd0d6416c5d3cb717905ebaec0", + "sha256:381c84a445efb8c9168f1393a5a7c566de22edc42bfe207a142fff919b37f5d9", + "sha256:399c73201d88c856a994916200d7cba41d7687096f8eb5139eb68f02785dc3f7", + "sha256:39f0f6a3b56e82dc91d84c763b783c5c33720a33c70ee48a1c13ba800ac1fa69", + "sha256:4596c12aa7e3bb2abf158ea8f79eb0fb4851606695d04ab846b2bb386f5690a1", + "sha256:4a52c25a51d5894ba60c567b0dbcf73de2f3cd642cf5343679e07ca3a768b085", + "sha256:4bf95be277fbb51513895c2cecc81ab12a421cdbd8837f159828a919a0167f96", + "sha256:4c2735d3305e6cecab6e53546909edf407ad3da5b9eeaf483f4cf80142bb21be", + "sha256:4c491462e1dc80f9deb93f428aad8d83bb286de212837f58eb48e75606e7726c", + "sha256:515b610a364c8cdd2b72c734cc97dece85c416892ea8d5c305624ac8734e81db", + "sha256:545987971b2aded25ba4698135ea0ae128836e7deb6e18c29a581076aaef44aa", + "sha256:55a54de5266bc44aa274915cdf388584fa052db8748a869e5500ab5993bac3f4", + "sha256:566552ed9b003030745e5bc7b402b83cf3cecae1bade95262d78543741786db5", + "sha256:5710b1c01472542bb024366803812ca13e8774d21381bcfc1f7ae738eeb38acc", + "sha256:5a531d29d7b873b12730972237c48b1a4e5980b98cf21b3f09fa4710abd3a8c3", + "sha256:5b113feeda47f908562d9a6d0e05798ad2f83d4473c0777dafa2bc7756473218", + "sha256:5e0a5bc019014531308fb67d86066d235daa7551baf2e00e1ea7b00531f6ea85", + "sha256:626ec13592928b677f48ff5861040b604b635e93d8e2162fb638397ea83d07e8", + "sha256:659a0ea6d9017558ed7af00fb4028186f64d0ba9adfc70a4d2c85fcd3d026321", + "sha256:65ff56a31f25925ef030b494fe63289bf07ef0febe6da181b8219146c590e185", + "sha256:681a168d06284602d56e97f09978057aa88bcc4177352b875b3d781df4efd4cb", + "sha256:6a6a36b94c09711d6397d79006ca47901539fbc602c853d794c39abd6a326549", + "sha256:6d1f67dad8cc36e8abc2207a77f3f952ac80be7404177830a7af4635a34cbc16", + "sha256:6ebc6e2e65c31356310ddb6519420eaa6bb8c30fbd809d0919129c89dcd70f4c", + "sha256:71a400b2f0b079438cc24f9a27f02eff24d8ef78f2943f949abc518b844ade3d", + "sha256:71c45f02ffbb8a21040ae816ceff7f6cd749ffac29fc0f9daa42dc1a9652d577", + "sha256:728d98179e92d77096937fdfecd2c555a3d613abe56c9909165c24196a3b5012", + "sha256:72b51340047ac43b3cf388eebd362d052632260c9f73a50882edbb66e589fd44", + "sha256:779aaae64089e2f4992e993faea801925395d26bb5de4a47df7ef7f942c14f80", + "sha256:783e91595cf9b66c2deda17f2e8748ae8591aa9f7c65dcab038872bfe83c5bb1", + "sha256:790286d3d542c0ef9f6d0280d1049378e5e776dcba780d169298f664c39394db", + "sha256:7aa8cc5c94e682dce91cb4d12d7b81c01641f4ef5b3b3dc53325d43f0e3b9f2e", + "sha256:7d51f70f77950f8efafed4383865d3533eeee52d8a0dd1c35b65f24de41de4e0", + "sha256:7da5c4c72ae40fd3ce87213ab057db66df53e55600d0b9e72e2b7f5a470a2cc4", + "sha256:7dfa60953169d2531dd8ae306e9c27c5d4e5efe7a2ba77049e8afdaece062937", + "sha256:7ea86eb32e74f9902df57e8608e8ac66f1e1e1d24d1ed2ddeb849888413b924d", + "sha256:7f088e21d15b3abdb9047e4b7b7a0acd79bf166893ac2b34a72ab1062feb219e", + "sha256:83ae2f5343f6f06f4c91ae530d95f56b415f768f9c401a5ee2a10459cf74370b", + "sha256:84f847e64f4d1a232e50460eebc1196642ee9b4c983612f41cd2d44fd2fe7c71", + "sha256:858eaabd2191dd0da5272993ad08a748b5d3ae1aefabea8aee619b45c2af4a64", + "sha256:8659f995b19185179474b18de8755689e1f71e1334d05c14e1895caa4e409cf7", + "sha256:88d50d662c917ec2c9d3858920aa7b9d5bfb74ab9c51424b775ccbe683cb1b4e", + "sha256:892a072e5b19c3f324a4f8543c9f7e8fc2b0aa08579e46f69bdf0cfc1b440454", + "sha256:8d18d796ffecdc8253742fd53a94ceee2e77ad149eb9ed5960c2856b5f692f71", + "sha256:92bc43a1ab852310721ce856f40a3a352254aa6f5e26f0fad870b31be45bba2e", + "sha256:944de70384c62d16d4a00c686b422aa75efbc67c4addaebefbb56475d1c16034", + "sha256:94a278c45e6463031b5a8278e40a07edf2bcc3b5379510e22b6c1a6e6498c194", + "sha256:94b0f7407d18001dbdcbb239512e753b1b36725a6e08a4983be1c948f5435f79", + "sha256:96153e037ae065bb71cae889f23c933190d81ae183f3696a030b47352fd8655d", + "sha256:9ba68c57cde9c667f6b65b98bc342dfa7240b1272ffb2c24b32172ee61b6d281", + "sha256:a1d5e474d43c238035b74ecf997f655afa67f979bae591ac838bb3fbe3076392", + "sha256:a4efbaf10793fd574c76a5732c75452f19d93df6e0f758c67dd60552ebd8614b", + "sha256:a60634a9de41f363923c6adfb83105d39e49f7a3058511563ed3de6748661af6", + "sha256:a7f06f077fc4ef37e8a37ca6bbb491b29e29db9fb28e29cf3896aad10dbd4137", + "sha256:a8ef2ea819549ae2e8698d2ec229ae948d7272feea1cb2878289f767b6c585a4", + "sha256:a9725d96a81e17e48a0fe82d0c3de2f5e623d7163fec70a6c7df90753edd1bec", + "sha256:ab9c1bd95ebd1689f0e24f2946c495808777e9e8df7bb3c1dfe3e9eb7f47fe0d", + "sha256:abe04e7aa5ab2e4056fcf3255ebee2071e4a427681f76d4729519e292c46ecc1", + "sha256:ae3adf88a66f5863cf79394bc359da523bb27a2ed6ba9898525a6a02b723bfc5", + "sha256:b2f29697d1110e8cdf7a39cc630498df0082d7898b79b731c1c863f77c6e8cfc", + "sha256:b730048ae8b875e2c0af1a09ca31b303fc7b5ed27652beec03fa22b29545aec9", + "sha256:bcb5bfac5b9635e6fc520c8af6efc7a0a56f12a1fe9e9d3eb4328537e316dd6a", + "sha256:bd6c6dba1a3b8949e08c4280071c86e38cb602f02e0ed6659234108c7a7cd710", + "sha256:c0e1c218fff95a66ad9f2f83ad41a67cf4d0a3f527efe820f57bde5fda616de4", + "sha256:c1443fa4bb306461a3a8a52b7de0932a2515b100ecb0ebc630cc3f87d451e0a9", + "sha256:c1ad731253eb738f9cadd9fa1844e019576c70bca6a534252e97cf33a57da529", + "sha256:c20d796210720455086ef3f85adc413d1e41d374742f9b439354f122bbc3b528", + "sha256:c2e274f3d1cbb2ddcc7a55ce3739af0f8510edc68a7f37981b2258fa1eedc833", + "sha256:c3f4b125285d354a627eb37f3ea7c13b8842c7c0d47783581d0df0e272dbf5f0", + "sha256:c9b8119244d122241a9c4566bce49bb20408a6827044155856735cf14189a7da", + "sha256:cd6e22255ed73efeaaeb1765505a66a48a9ec9ebc919fce5ad490fe5e33b1555", + "sha256:cd8684f628fe285ea5c86f88e1c30716239dc9d6ac55e7851a4b7f555b628da3", + "sha256:cdb0cecafb528ab15ed89cdfed183074d15912d046d3e304955513b50a34b907", + "sha256:d74aa60b1ec076d4d5dcde27c9a535fc0ebb12613f599681c438ca3daa68acac", + "sha256:d7f008799682e8826ce98f25e8bc43532d2cd26c187a1462499fa8d123ae054f", + "sha256:d9a8d277dc218ddf04ec243a53ac309b1afcebe297c0526a8f82320139b56289", + "sha256:da47070e1340a1639aca6b1c18fe1f1f3d8d64d3a1f9ddc67b94475f44cd40f3", + "sha256:da584d917a1a17f690fc726617fd2c3f3006ea959dae5bb07a5630f7b16f9f5f", + "sha256:de536cf796abc5b58d11c0ad56580215d231d9554ea4bb6b8b1b3bed80aa3234", + "sha256:de8e310d24b5a61de08812dd70d5234da1458d41b059038ee7895a9e4c8cae79", + "sha256:df7107a91126a495880576610ae989f19106e1900dd5218d08498391fa43b31d", + "sha256:e0ce7f3d1faf7ad58652ed758cc9753049af5308b38f89948aa71793282419c5", + "sha256:e2d01fd53e89cb3d71d20b8c225a8c70d84660f2d223afc7ed7851a4086afe6d", + "sha256:e5227da556b2939da6125cda1d5eecf9e412e58bc97b41e2f192605c3ccbb7c2", + "sha256:e6229ad15366cd8b6d6b4185c55dd48debf9ca546f91416ba2e5921ad6e210a6", + "sha256:e878553543ece1f8006d0ba4d096b40290580db173bfb18e16158045b9371335", + "sha256:eb77a85253174bf73e52c968b689d64be62d71e8ac33cabef4ca77b03fb4ef92", + "sha256:f114a3e1f8034e2957d34043b7a317a8a05d97dfe8fddb36d9a2252c0117dbbc", + "sha256:f495007ada16a4e16312b502636fafff42a9003adf1d4fb7541e0a0870bc056f", + "sha256:f5c82af8e329c3cdc3e717dd3c7b2ff1a218b6de611f6ce76ee34967570a9de9" + ], + "markers": "python_version >= '3.9'", + "version": "==0.4.0" }, "pycares": { "hashes": [ - "sha256:112a4979c695b1c86f6782163d7dec58d57a3b9510536dcf4826550f9053dd9a", - "sha256:1168a48a834813aa80f412be2df4abaf630528a58d15c704857448b20b1675c0", - "sha256:21a5a0468861ec7df7befa69050f952da13db5427ae41ffe4713bc96291d1d95", - "sha256:229a1675eb33bc9afb1fc463e73ee334950ccc485bc83a43f6ae5839fb4d5fa3", - "sha256:22c00bf659a9fa44d7b405cf1cd69b68b9d37537899898d8cbe5dffa4016b273", - "sha256:23aa3993a352491a47fcf17867f61472f32f874df4adcbb486294bd9fbe8abee", - "sha256:24da119850841d16996713d9c3374ca28a21deee056d609fbbed29065d17e1f6", - "sha256:2eeec144bcf6a7b6f2d74d6e70cbba7886a84dd373c886f06cb137a07de4954c", - "sha256:34736a2ffaa9c08ca9c707011a2d7b69074bbf82d645d8138bba771479b2362f", - "sha256:3aebc73e5ad70464f998f77f2da2063aa617cbd8d3e8174dd7c5b4518f967153", - "sha256:3eaa6681c0a3e3f3868c77aca14b7760fed35fdfda2fe587e15c701950e7bc69", - "sha256:4afc2644423f4eef97857a9fd61be9758ce5e336b4b0bd3d591238bb4b8b03e0", - "sha256:52084961262232ec04bd75f5043aed7e5d8d9695e542ff691dfef0110209f2d4", - "sha256:56cf3349fa3a2e67ed387a7974c11d233734636fe19facfcda261b411af14d80", - "sha256:5ed4e04af4012f875b78219d34434a6d08a67175150ac1b79eb70ab585d4ba8c", - "sha256:64965dc19c578a683ea73487a215a8897276224e004d50eeb21f0bc7a0b63c88", - "sha256:6ef64649eba56448f65e26546d85c860709844d2fc22ef14d324fe0b27f761a9", - "sha256:77cf5a2fd5583c670de41a7f4a7b46e5cbabe7180d8029f728571f4d2e864084", - "sha256:7bddc6adba8f699728f7fc1c9ce8cef359817ad78e2ed52b9502cb5f8dc7f741", - "sha256:813d661cbe2e37d87da2d16b7110a6860e93ddb11735c6919c8a3545c7b9c8d8", - "sha256:82bba2ab77eb5addbf9758d514d9bdef3c1bfe7d1649a47bd9a0d55a23ef478b", - "sha256:8bf2eaa83a5987e48fa63302f0fe7ce3275cfda87b34d40fef9ce703fb3ac002", - "sha256:8d186dafccdaa3409194c0f94db93c1a5d191145a275f19da6591f9499b8e7b8", - "sha256:8f64cb58729689d4d0e78f0bfb4c25ce2f851d0274c0273ac751795c04b8798a", - "sha256:902461a92b6a80fd5041a2ec5235680c7cc35e43615639ec2a40e63fca2dfb51", - "sha256:917f08f0b5d9324e9a34211e68d27447c552b50ab967044776bbab7e42a553a2", - "sha256:94d6962db81541eb0396d2f0dfcbb18cdb8c8b251d165efc2d974ae652c547d4", - "sha256:97892cced5794d721fb4ff8765764aa4ea48fe8b2c3820677505b96b83d4ef47", - "sha256:9a0303428d013ccf5c51de59c83f9127aba6200adb7fd4be57eddb432a1edd2a", - "sha256:9dc04c54c6ea615210c1b9e803d0e2d2255f87a3d5d119b6482c8f0dfa15b26b", - "sha256:a0c5368206057884cde18602580083aeaad9b860e2eac14fd253543158ce1e93", - "sha256:ad58e284a658a8a6a84af2e0b62f2f961f303cedfe551854d7bd40c3cbb61912", - "sha256:afb91792f1556f97be7f7acb57dc7756d89c5a87bd8b90363a77dbf9ea653817", - "sha256:b61579cecf1f4d616e5ea31a6e423a16680ab0d3a24a2ffe7bb1d4ee162477ff", - "sha256:b7af06968cbf6851566e806bf3e72825b0e6671832a2cbe840be1d2d65350710", - "sha256:bce8db2fc6f3174bd39b81405210b9b88d7b607d33e56a970c34a0c190da0490", - "sha256:bfb89ca9e3d0a9b5332deeb666b2ede9d3469107742158f4aeda5ce032d003f4", - "sha256:c680fef1b502ee680f8f0b95a41af4ec2c234e50e16c0af5bbda31999d3584bd", - "sha256:c6a8bde63106f162fca736e842a916853cad3c8d9d137e11c9ffa37efa818b02", - "sha256:cb49d5805cd347c404f928c5ae7c35e86ba0c58ffa701dbe905365e77ce7d641", - "sha256:ceb12974367b0a68a05d52f4162b29f575d241bd53de155efe632bf2c943c7f6", - "sha256:d33e2a1120887e89075f7f814ec144f66a6ce06a54f5722ccefc62fbeda83cff", - "sha256:db24c4e7fea4a052c6e869cbf387dd85d53b9736cfe1ef5d8d568d1ca925e977", - "sha256:e3a6f7cfdfd11eb5493d6d632e582408c8f3b429f295f8799c584c108b28db6f", - "sha256:eb66c30eb11e877976b7ead13632082a8621df648c408b8e15cdb91a452dd502", - "sha256:ed2a38e34bec6f2586435f6ff0bc5fe11d14bebd7ed492cf739a424e81681540", - "sha256:f36bdc1562142e3695555d2f4ac0cb69af165eddcefa98efc1c79495b533481f", - "sha256:f47579d508f2f56eddd16ce72045782ad3b1b3b678098699e2b6a1b30733e1c2", - "sha256:f5f646eec041db6ffdbcaf3e0756fb92018f7af3266138c756bb09d2b5baadec", - "sha256:fd644505a8cfd7f6584d33a9066d4e3d47700f050ef1490230c962de5dfb28c6", - "sha256:fff16b09042ba077f7b8aa5868d1d22456f0002574d0ba43462b10a009331677" - ], - "markers": "python_version >= '3.8'", - "version": "==4.4.0" + "sha256:00538826d2eaf4a0e4becb0753b0ac8d652334603c445c9566c9eb273657eb4c", + "sha256:066f3caa07c85e1a094aebd9e7a7bb3f3b2d97cff2276665693dd5c0cc81cf84", + "sha256:0aed0974eab3131d832e7e84a73ddb0dddbc57393cd8c0788d68a759a78c4a7b", + "sha256:1571a7055c03a95d5270c914034eac7f8bfa1b432fc1de53d871b821752191a4", + "sha256:1732db81e348bfce19c9bf9448ba660aea03042eeeea282824da1604a5bd4dcf", + "sha256:1dbbf0cfb39be63598b4cdc2522960627bf2f523e49c4349fb64b0499902ec7c", + "sha256:218619b912cef7c64a339ab0e231daea10c994a05699740714dff8c428b9694a", + "sha256:23d50a0842e8dbdddf870a7218a7ab5053b68892706b3a391ecb3d657424d266", + "sha256:29daa36548c04cdcd1a78ae187a4b7b003f0b357a2f4f1f98f9863373eedc759", + "sha256:2c296ab94d1974f8d2f76c499755a9ce31ffd4986e8898ef19b90e32525f7d84", + "sha256:2d5cac829da91ade70ce1af97dad448c6cd4778b48facbce1b015e16ced93642", + "sha256:30ceed06f3bf5eff865a34d21562c25a7f3dad0ed336b9dd415330e03a6c50c4", + "sha256:30d197180af626bb56f17e1fa54640838d7d12ed0f74665a3014f7155435b199", + "sha256:30feeab492ac609f38a0d30fab3dc1789bd19c48f725b2955bcaaef516e32a21", + "sha256:3139ec1f4450a4b253386035c5ecd2722582ae3320a456df5021ffe3f174260a", + "sha256:31b85ad00422b38f426e5733a71dfb7ee7eb65a99ea328c508d4f552b1760dc8", + "sha256:35ff1ec260372c97ed688efd5b3c6e5481f2274dea08f6c4ea864c195a9673c6", + "sha256:3784b80d797bcc2ff2bf3d4b27f46d8516fe1707ff3b82c2580dc977537387f9", + "sha256:386da2581db4ea2832629e275c061103b0be32f9391c5dfaea7f6040951950ad", + "sha256:3b44e54cad31d3c3be5e8149ac36bc1c163ec86e0664293402f6f846fb22ad00", + "sha256:3bd81ad69f607803f531ff5cfa1262391fa06e78488c13495cee0f70d02e0287", + "sha256:3d5300a598ad48bbf169fba1f2b2e4cf7ab229e7c1a48d8c1166f9ccf1755cb3", + "sha256:3db6b6439e378115572fa317053f3ee6eecb39097baafe9292320ff1a9df73e3", + "sha256:3ef1ab7abbd238bb2dbbe871c3ea39f5a7fc63547c015820c1e24d0d494a1689", + "sha256:45d3254a694459fdb0640ef08724ca9d4b4f6ff6d7161c9b526d7d2e2111379e", + "sha256:4b6f7581793d8bb3014028b8397f6f80b99db8842da58f4409839c29b16397ad", + "sha256:4da2e805ed8c789b9444ef4053f6ef8040cd13b0c1ca6d3c4fe6f9369c458cb4", + "sha256:5344d52efa37df74728505a81dd52c15df639adffd166f7ddca7a6318ecdb605", + "sha256:5d69e2034160e1219665decb8140e439afc7a7afcfd4adff08eb0f6142405c3e", + "sha256:5d70324ca1d82c6c4b00aa678347f7560d1ef2ce1d181978903459a97751543a", + "sha256:5e1ab899bb0763dea5d6569300aab3a205572e6e2d0ef1a33b8cf2b86d1312a4", + "sha256:6195208b16cce1a7b121727710a6f78e8403878c1017ab5a3f92158b048cec34", + "sha256:66c310773abe42479302abf064832f4a37c8d7f788f4d5ee0d43cbad35cf5ff4", + "sha256:6f74b1d944a50fa12c5006fd10b45e1a45da0c5d15570919ce48be88e428264c", + "sha256:6f751f5a0e4913b2787f237c2c69c11a53f599269012feaa9fb86d7cef3aec26", + "sha256:702d21823996f139874aba5aa9bb786d69e93bde6e3915b99832eb4e335d31ae", + "sha256:719f7ddff024fdacde97b926b4b26d0cc25901d5ef68bb994a581c420069936d", + "sha256:742fbaa44b418237dbd6bf8cdab205c98b3edb334436a972ad341b0ea296fb47", + "sha256:7570e0b50db619b2ee370461c462617225dc3a3f63f975c6f117e2f0c94f82ca", + "sha256:775d99966e28c8abd9910ddef2de0f1e173afc5a11cea9f184613c747373ab80", + "sha256:77bf82dc0beb81262bf1c7f546e1c1fde4992e5c8a2343b867ca201b85f9e1aa", + "sha256:7830709c23bbc43fbaefbb3dde57bdd295dc86732504b9d2e65044df8fd5e9fb", + "sha256:7aba9a312a620052133437f2363aae90ae4695ee61cb2ee07cbb9951d4c69ddd", + "sha256:80752133442dc7e6dd9410cec227c49f69283c038c316a8585cca05ec32c2766", + "sha256:836725754c32363d2c5d15b931b3ebd46b20185c02e850672cb6c5f0452c1e80", + "sha256:83a7401d7520fa14b00d85d68bcca47a0676c69996e8515d53733972286f9739", + "sha256:84b0b402dd333403fdce0e204aef1ef834d839c439c0c1aa143dc7d1237bb197", + "sha256:84fde689557361764f052850a2d68916050adbfd9321f6105aca1d8f1a9bd49b", + "sha256:87dab618fe116f1936f8461df5970fcf0befeba7531a36b0a86321332ff9c20b", + "sha256:8a75a406432ce39ce0ca41edff7486df6c970eb0fe5cfbe292f195a6b8654461", + "sha256:910ce19a549f493fb55cfd1d7d70960706a03de6bfc896c1429fc5d6216df77e", + "sha256:9518514e3e85646bac798d94d34bf5b8741ee0cb580512e8450ce884f526b7cf", + "sha256:95bc81f83fadb67f7f87914f216a0e141555ee17fd7f56e25aa0cc165e99e53b", + "sha256:96e07d5a8b733d753e37d1f7138e7321d2316bb3f0f663ab4e3d500fabc82807", + "sha256:97d971b3a88a803bb95ff8a40ea4d68da59319eb8b59e924e318e2560af8c16d", + "sha256:9a00408105901ede92e318eecb46d0e661d7d093d0a9b1224c71b5dd94f79e83", + "sha256:9d0c543bdeefa4794582ef48f3c59e5e7a43d672a4bfad9cbbd531e897911690", + "sha256:a4060d8556c908660512d42df1f4a874e4e91b81f79e3a9090afedc7690ea5ba", + "sha256:a98fac4a3d4f780817016b6f00a8a2c2f41df5d25dfa8e5b1aa0d783645a6566", + "sha256:aa160dc9e785212c49c12bb891e242c949758b99542946cc8e2098ef391f93b0", + "sha256:aca981fc00c8af8d5b9254ea5c2f276df8ece089b081af1ef4856fbcfc7c698a", + "sha256:afc6503adf8b35c21183b9387be64ca6810644ef54c9ef6c99d1d5635c01601b", + "sha256:b50ca218a3e2e23cbda395fd002d030385202fbb8182aa87e11bea0a568bd0b8", + "sha256:b93d624560ba52287873bacff70b42c99943821ecbc810b959b0953560f53c36", + "sha256:bac55842047567ddae177fb8189b89a60633ac956d5d37260f7f71b517fd8b87", + "sha256:c0eec184df42fc82e43197e073f9cc8f93b25ad2f11f230c64c2dc1c80dbc078", + "sha256:c2971af3a4094280f7c24293ff4d361689c175c1ebcbea6b3c1560eaff7cb240", + "sha256:c2af7a9d3afb63da31df1456d38b91555a6c147710a116d5cc70ab1e9f457a4f", + "sha256:c863d9003ca0ce7df26429007859afd2a621d3276ed9fef154a9123db9252557", + "sha256:c9d839b5700542b27c1a0d359cbfad6496341e7c819c7fea63db9588857065ed", + "sha256:cb711a66246561f1cae51244deef700eef75481a70d99611fd3c8ab5bd69ab49", + "sha256:cdac992206756b024b371760c55719eb5cd9d6b2cb25a8d5a04ae1b0ff426232", + "sha256:cf306f3951740d7bed36149a6d8d656a7d5432dd4bbc6af3bb6554361fc87401", + "sha256:d2a3526dbf6cb01b355e8867079c9356a8df48706b4b099ac0bf59d4656e610d", + "sha256:d552fb2cb513ce910d1dc22dbba6420758a991a356f3cd1b7ec73a9e31f94d01", + "sha256:d5fe089be67bc5927f0c0bd60c082c79f22cf299635ee3ddd370ae2a6e8b4ae0", + "sha256:dc54a21586c096df73f06f9bdf594e8d86d7be84e5d4266358ce81c04c3cc88c", + "sha256:dcd4a7761fdfb5aaac88adad0a734dd065c038f5982a8c4b0dd28efa0bd9cc7c", + "sha256:dde02314eefb85dce3cfdd747e8b44c69a94d442c0d7221b7de151ee4c93f0f5", + "sha256:df0a17f4e677d57bca3624752bbb515316522ad1ce0de07ed9d920e6c4ee5d35", + "sha256:e0fcd3a8bac57a0987d9b09953ba0f8703eb9dca7c77f7051d8c2ed001185be8", + "sha256:e2f8d9cfe0eb3a2997fde5df99b1aaea5a46dabfcfcac97b2d05f027c2cd5e28", + "sha256:ea785d1f232b42b325578f0c8a2fa348192e182cc84a1e862896076a4a2ba2a7", + "sha256:eddf5e520bb88b23b04ac1f28f5e9a7c77c718b8b4af3a4a7a2cc4a600f34502", + "sha256:ee1ea367835eb441d246164c09d1f9703197af4425fc6865cefcde9e2ca81f85", + "sha256:ee751409322ff10709ee867d5aea1dc8431eec7f34835f0f67afd016178da134", + "sha256:f199702740f3b766ed8c70efb885538be76cb48cd0cb596b948626f0b825e07a", + "sha256:f4695153333607e63068580f2979b377b641a03bc36e02813659ffbea2b76fe2", + "sha256:f6c602c5e3615abbf43dbdf3c6c64c65e76e5aa23cb74e18466b55d4a2095468", + "sha256:faa8321bc2a366189dcf87b3823e030edf5ac97a6b9a7fc99f1926c4bf8ef28e", + "sha256:ff3d25883b7865ea34c00084dd22a7be7c58fd3131db6b25c35eafae84398f9d", + "sha256:ffb22cee640bc12ee0e654eba74ecfb59e2e0aebc5bccc3cc7ef92f487008af7" + ], + "markers": "python_version >= '3.9'", + "version": "==4.11.0" }, "pycparser": { "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", + "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934" ], - "version": "==2.21" + "markers": "python_version >= '3.8'", + "version": "==2.23" }, "pymongo": { "extras": [ "srv" ], "hashes": [ - "sha256:014e7049dd019a6663747ca7dae328943e14f7261f7c1381045dfc26a04fa330", - "sha256:055f5c266e2767a88bb585d01137d9c7f778b0195d3dbf4a487ef0638be9b651", - "sha256:05c30fd35cc97f14f354916b45feea535d59060ef867446b5c3c7f9b609dd5dc", - "sha256:0634994b026336195778e5693583c060418d4ab453eff21530422690a97e1ee8", - "sha256:09c7de516b08c57647176b9fc21d929d628e35bcebc7422220c89ae40b62126a", - "sha256:107a234dc55affc5802acb3b6d83cbb8c87355b38a9457fcd8806bdeb8bce161", - "sha256:10a379fb60f1b2406ae57b8899bacfe20567918c8e9d2d545e1b93628fcf2050", - "sha256:128b1485753106c54af481789cdfea12b90a228afca0b11fb3828309a907e10e", - "sha256:1394c4737b325166a65ae7c145af1ebdb9fb153ebedd37cf91d676313e4a67b8", - "sha256:1c63e3a2e8fb815c4b1f738c284a4579897e37c3cfd95fdb199229a1ccfb638a", - "sha256:1e4ed21029d80c4f62605ab16398fe1ce093fff4b5f22d114055e7d9fbc4adb0", - "sha256:1ec71ac633b126c0775ed4604ca8f56c3540f5c21a1220639f299e7a544b55f9", - "sha256:21812453354b151200034750cd30b0140e82ec2a01fd4357390f67714a1bfbde", - "sha256:256c503a75bd71cf7fb9ebf889e7e222d49c6036a48aad5a619f98a0adf0e0d7", - "sha256:2703a9f8f5767986b4f51c259ff452cc837c5a83c8ed5f5361f6e49933743b2f", - "sha256:288c21ab9531b037f7efa4e467b33176bc73a0c27223c141b822ab4a0e66ff2a", - "sha256:2972dd1f1285866aba027eff2f4a2bbf8aa98563c2ced14cb34ee5602b36afdf", - "sha256:2973f113e079fb98515722cd728e1820282721ec9fd52830e4b73cabdbf1eb28", - "sha256:2ca0ba501898b2ec31e6c3acf90c31910944f01d454ad8e489213a156ccf1bda", - "sha256:2d2be5c9c3488fa8a70f83ed925940f488eac2837a996708d98a0e54a861f212", - "sha256:2f8c04277d879146eacda920476e93d520eff8bec6c022ac108cfa6280d84348", - "sha256:325701ae7b56daa5b0692305b7cb505ca50f80a1288abb32ff420a8a209b01ca", - "sha256:3729b8db02063da50eeb3db88a27670d85953afb9a7f14c213ac9e3dca93034b", - "sha256:3919708594b86d0f5cdc713eb6fccd3f9b9532af09ea7a5d843c933825ef56c4", - "sha256:39a1cd5d383b37285641d5a7a86be85274466ae336a61b51117155936529f9b3", - "sha256:3ec6c20385c5a58e16b1ea60c5e4993ea060540671d7d12664f385f2fb32fe79", - "sha256:47aa128be2e66abd9d1a9b0437c62499d812d291f17b55185cb4aa33a5f710a4", - "sha256:49f2af6cf82509b15093ce3569229e0d53c90ad8ae2eef940652d4cf1f81e045", - "sha256:4a0269811661ba93c472c8a60ea82640e838c2eb148d252720a09b5123f2c2fe", - "sha256:518c90bdd6e842c446d01a766b9136fec5ec6cc94f3b8c3f8b4a332786ee6b64", - "sha256:5717a308a703dda2886a5796a07489c698b442f5e409cf7dc2ac93de8d61d764", - "sha256:5802acc012bbb4bce4dff92973dff76482f30ef35dd4cb8ab5b0e06aa8f08c80", - "sha256:5e63146dbdb1eac207464f6e0cfcdb640c9c5ff0f57b754fa96fe252314a1dc6", - "sha256:6695d7136a435c1305b261a9ddb9b3ecec9863e05aab3935b96038145fd3a977", - "sha256:680fa0fc719e1a3dcb81130858368f51d83667d431924d0bcf249644bce8f303", - "sha256:6b18276f14b4b6d92e707ab6db19b938e112bd2f1dc3f9f1a628df58e4fd3f0d", - "sha256:6bafea6061d63059d8bc2ffc545e2f049221c8a4457d236c5cd6a66678673eab", - "sha256:6d6a1b1361f118e7fefa17ae3114e77f10ee1b228b20d50c47c9f351346180c8", - "sha256:747c84f4e690fbe6999c90ac97246c95d31460d890510e4a3fa61b7d2b87aa34", - "sha256:79f41576b3022c2fe9780ae3e44202b2438128a25284a8ddfa038f0785d87019", - "sha256:7b0e6361754ac596cd16bfc6ed49f69ffcd9b60b7bc4bcd3ea65c6a83475e4ff", - "sha256:7e3b0127b260d4abae7b62203c4c7ef0874c901b55155692353db19de4b18bc4", - "sha256:7fc2bb8a74dcfcdd32f89528e38dcbf70a3a6594963d60dc9595e3b35b66e414", - "sha256:806e094e9e85d8badc978af8c95b69c556077f11844655cb8cd2d1758769e521", - "sha256:81dd1308bd5630d2bb5980f00aa163b986b133f1e9ed66c66ce2a5bc3572e891", - "sha256:82e620842e12e8cb4050d2643a81c8149361cd82c0a920fa5a15dc4ca8a4000f", - "sha256:85f2cdc400ee87f5952ebf2a117488f2525a3fb2e23863a8efe3e4ee9e54e4d1", - "sha256:8ab6bcc8e424e07c1d4ba6df96f7fb963bcb48f590b9456de9ebd03b88084fe8", - "sha256:8adf014f2779992eba3b513e060d06f075f0ab2fb3ad956f413a102312f65cdf", - "sha256:9b0f98481ad5dc4cb430a60bbb8869f05505283b9ae1c62bdb65eb5e020ee8e3", - "sha256:9bea9138b0fc6e2218147e9c6ce1ff76ff8e29dc00bb1b64842bd1ca107aee9f", - "sha256:a09bfb51953930e7e838972ddf646c5d5f984992a66d79da6ba7f6a8d8a890cd", - "sha256:a0be99b599da95b7a90a918dd927b20c434bea5e1c9b3efc6a3c6cd67c23f813", - "sha256:a49aca4d961823b2846b739380c847e8964ff7ae0f0a683992b9d926054f0d6d", - "sha256:a4dc1319d0c162919ee7f4ee6face076becae2abbd351cc14f1fe70af5fb20d9", - "sha256:a8273e1abbcff1d7d29cbbb1ea7e57d38be72f1af3c597c854168508b91516c2", - "sha256:a8f7f9feecae53fa18d6a3ea7c75f9e9a1d4d20e5c3f9ce3fba83f07bcc4eee2", - "sha256:ad4f66fbb893b55f96f03020e67dcab49ffde0177c6565ccf9dec4fdf974eb61", - "sha256:af425f323fce1b07755edd783581e7283557296946212f5b1a934441718e7528", - "sha256:b14dd73f595199f4275bed4fb509277470d9b9059310537e3b3daba12b30c157", - "sha256:b4ad70d7cac4ca0c7b31444a0148bd3af01a2662fa12b1ad6f57cd4a04e21766", - "sha256:b80a4ee19b3442c57c38afa978adca546521a8822d663310b63ae2a7d7b13f3a", - "sha256:ba51129fcc510824b6ca6e2ce1c27e3e4d048b6e35d3ae6f7e517bed1b8b25ce", - "sha256:c011bd5ad03cc096f99ffcfdd18a1817354132c1331bed7a837a25226659845f", - "sha256:cc94f9fea17a5af8cf1a343597711a26b0117c0b812550d99934acb89d526ed2", - "sha256:ccd785fafa1c931deff6a7116e9a0d402d59fabe51644b0d0c268295ff847b25", - "sha256:d16a534da0e39785687b7295e2fcf9a339f4a20689024983d11afaa4657f8507", - "sha256:d3077a31633beef77d057c6523f5de7271ddef7bde5e019285b00c0cc9cac1e3", - "sha256:d603edea1ff7408638b2504905c032193b7dcee7af269802dbb35bc8c3310ed5", - "sha256:db082f728160369d9a6ed2e722438291558fc15ce06d0a7d696a8dad735c236b", - "sha256:ddef295aaf80cefb0c1606f1995899efcb17edc6b327eb6589e234e614b87756", - "sha256:e16ade71c93f6814d095d25cd6d28a90d63511ea396bd96e9ffcb886b278baaa", - "sha256:e3db7d833a7c38c317dc95b54e27f1d27012e031b45a7c24e360b53197d5f6e7", - "sha256:e5e193f89f4f8c1fe273f9a6e6df915092c9f2af6db2d1afb8bd53855025c11f", - "sha256:eb438a8bf6b695bf50d57e6a059ff09652a07968b2041178b3744ea785fcef9b", - "sha256:ebf02c32afa6b67e5861a27183dd98ed88419a94a2ab843cc145fb0bafcc5b28", - "sha256:ecd9e1fa97aa11bf67472220285775fa15e896da108f425e55d23d7540a712ce", - "sha256:ef67fedd863ffffd4adfd46d9d992b0f929c7f61a8307366d664d93517f2c78e", - "sha256:f28ae33dc5a0b9cee06e95fd420e42155d83271ab75964baf747ce959cac5f52", - "sha256:fb1c56d891f9e34303c451998ef62ba52659648bb0d75b03c5e4ac223a3342c2", - "sha256:fe03bf25fae4b95d8afe40004a321df644400fdcba4c8e5e1a19c1085b740888" - ], - "markers": "python_version >= '3.7'", - "version": "==4.6.0" + "sha256:024e735127e7f39763eb3043c628a857cbf6cdfabd9bf5a1825f3597bab74352", + "sha256:03bd7284fd299c7df09cebeb53f3251e0b4850fba71bf63cbbff1ddf20cc569d", + "sha256:05b9eab3bc049f8fd150869375eff3a85ceab606531b6226b60f054daf7d1368", + "sha256:05e96219d1acca15643042478103241771e46a3f5331bae3e19d2ea2756968b1", + "sha256:0ad7ec297e8999b0f984c998e2c1c605f11e9b8c7682256bbbc53c24a195f76e", + "sha256:1393e7e9d2fc291e0d72f8583ef58e1999e84f7cd01d5a72db53b4ed1ae44686", + "sha256:18bc73e47d21cabfde719d0cc5aa6b556856993397c9433d934089c86732e3d3", + "sha256:1b5c61e32c6afbf35a9c6638db892f75dc53ebcd45a9a1bf992ffff0ec28aaaa", + "sha256:1db14e952ceb574cb8acacf063040e2a6e9570bd50671fa903fb47adb7cf49cc", + "sha256:1f2af4b98fc6d54489d187c0faa12bfbf0ef6c56c3e735eeb837ac8ff235b490", + "sha256:20ee2722ac45fba2c502edbc5281b6efcd8601d94ae1900a48c106459a1715d7", + "sha256:21b1d1d33bdbc87c1a082b747aa9ab40a30638c4e58e799d8fe9f5cb15feb38f", + "sha256:22ad78ac0222b8c5f5a28cdf6300cf19481fff193110506768c9915c8cd3396b", + "sha256:29645a9a8166f20b3fc6aa05095af6caf8ee9af9a4cf23cd857576084e29cc9c", + "sha256:2968cf01e2257f2f5193aba259116c1e9e56f739a16eceef36e85a55edc91604", + "sha256:2b6c8588b04e304bb4670e5409b3def2d9daedb8f719d47780a59de7227f1d3f", + "sha256:2c816a9e9d4aaaa0e4e9fb2534b72957666d262f3ce874a0408f8b925cfd4d99", + "sha256:2daa9434828a5e5638b9d78f0031c9e19b5bc84ce9f5e69cf6083f58aa3e3901", + "sha256:2fad596a092ab9cd821c98d75b48dd6a9c3fc52df8b1453d2f10d8219676269a", + "sha256:338b29d89f92c665a1038d53c7cc68869e2a04e171dd4fb2d416d7ad263dc50a", + "sha256:38785ba507a019edb742e333c6bf2fa3644043f1ce79ef4d20a4f7bb2180ee74", + "sha256:3ab5ba56b868c56a38cfeb3202ee78dcdd4152bc364d24b71aaf1ee3994c7f96", + "sha256:3dc0ec9d78d4f28a24bd965e06c0a77459086522005aa199a8e4fc652ed1ce8e", + "sha256:3fafe5ef96943ab9b837f89b6abe779951102bee44d21c743259d43cfc1d9f6e", + "sha256:42acd45f7030743eed3d5e66a03dd3e9c12c7869301d123bffa1f71dc0e3f882", + "sha256:45103766c3f1bf1f5fc2da43a48dbe03a343389a334eb1d02ef39024957cdc91", + "sha256:475a97d48be850140f2455ed4a2a9920f70538b0824c53ffa5deeb940f49fdb3", + "sha256:50307e2403f0cfdf4fd0f5c6c9a45edbb4c5fa63196e1671b7fed5bbcd884109", + "sha256:50325282876a263ece78371319e78518dd034e434c11e3ab12402547292b8fd5", + "sha256:557611de3fa33bd5b8e5d38a7056b15d5c38361af50378ff5cf8b9cbf371913b", + "sha256:587202db4a64d5c091bc39695095af461a6a08b2a52ddd881a6e5cb34244d672", + "sha256:597dce90bc607b3180735a6692abcf75c111d7f6169b2b1cca1db85086ee980c", + "sha256:5b72de1a2f8cc52561c65a5062ade72e06da76e0899d4f11ae1c1bced1534ff8", + "sha256:5fa558bc6320e1183965db06e069973c9642b971a37729a8ae23c37f1c13ce21", + "sha256:6462763611c5fb97b56fcd3a62c325bc8111c686c7768f50668882d21b4f28f4", + "sha256:68fbc920409bd96e6a63b651254baa45e27473c4b73232a3fb5662279383a622", + "sha256:69515e1042a2fb4fadf6384918be34703aa2c792b9a8d3d406ad43e07cb095a2", + "sha256:6d797730d07bff953d05693e75d9575e7357739a5eb2747521987d2f99b9899f", + "sha256:7089a1f2d5883f5137f1c2766691db904741985bb7e7a400ed50c3b370507b17", + "sha256:7466840413fbd23605e9f95b702374b061525e85ea7f47dca6a88981455490ec", + "sha256:75f6f8363a57ba8a6bb1076114dc9aa29336f525c8b621cc1e4cfccae4ff546a", + "sha256:76c1c013bc577c7fb2c9a69d52ee335672eac1bdbfb9c37a432bb155bc69ffdc", + "sha256:780447f9112f0e57d821ced8d593657b45616f3821becb0740e6c0fc38b0e91e", + "sha256:82ba58edb6f6112aac543214ac22fc8e3d569372a7b3a180511cf4a70bd4c0ef", + "sha256:9fa833908d94b5869e6c9a53b778dc8235caca6fcda03aac8410b8f067cd8a6f", + "sha256:a15ad3f11556a30e5dd86344567e85eb46550b09e0ea8d3297476788f0c76d77", + "sha256:a244e27c034707f48f979fdcebe0df47ea000fd52ee1b2b2d2d2cb5b7b0e24dd", + "sha256:a33e118e14bd350bef6127a000c8d08e6bade8b9045bcd70d09a665434035705", + "sha256:a42ad84dfab44218f264e2d68b79e0e684c03c66fe8180a7961d6eb670eec4a3", + "sha256:a4a0d3cf68f9bf84a7ee737ba0b29265cfeeaf586a856c6d7773491c545e5230", + "sha256:a775371086ff63da1ae97f676bcb5556c86e4e281ccac998d49d6e24efa50ca1", + "sha256:a98f67df7aae325c0476aa453877475f9a1160f84b7e6e24e4804498ef99178e", + "sha256:a994b40542ba44748af9e382fd54e69428f40c1728ae06bc649c87a1135d1cfb", + "sha256:b5fe426128a03393d2e7f10169e1f10cf6a6355f40876f52b51a03721c12e6e5", + "sha256:bf646006bfce5e153cc838adaee319ff8a3d625978d491208cc290e89f9c2a21", + "sha256:c434219d66bf20f46011cc11b28e0dbfeb965f7a7cfd1e4b8e733a5f642ae1c2", + "sha256:c95a8d0ca11d16e325749fbd9f7d9aeb9a90241245e419007a941f446ff94dd6", + "sha256:cedfd1be19c8f7b41a1f5fbaea299303087b5d40605e956ffbcfe2adc76de0ec", + "sha256:d54b8139979e6e2ee6fec91b189e948ee2d83f125957793cf191c5e33be567e7", + "sha256:d9410537204bb9e83f1c5e43f6e5df2c0d3fe092dbd8d30bd883736818a6d786", + "sha256:ddf9face1dadf4cce4578dda29547ca2af6df09d44e7dd1bd6fe185f7c18dfc9", + "sha256:de0c88d7229a96a5bfe2827170578bcd871ee16843c47e5cb3290edf1aaf62ca", + "sha256:dece75a28450fa813040b13f7fbe80a614d02e04f7ff84255a2600c440bf227a", + "sha256:e6a22f0349142c92bb2ccbd35a8a0b7dc5a2eeac14217fb28cfa9956bcfee139", + "sha256:eb1423432631994d965e92ee63e448627d57793fd780c56c49570f12d4be1ff4", + "sha256:ebd6f6eed7c6c92af3d3fa375ecd0e730da628c59a95aca5b2445fbb3d1eb874", + "sha256:ee0ab602d309c6f903c002f8705b92459d885349f1f9561040f34a2a06c84891", + "sha256:f03716cfd4c86e3a8537ab8e1169cec26d532cc70fcd02e30027820ac587d28b", + "sha256:f5bfbde2ccc88b96d56cdc6bd104b856d9b039aa209b491311f8012e611d9f58", + "sha256:f736f1a6d85f3b1c182018ae0e6c387bb342935e3b97637c258b9b46e0509af2", + "sha256:f9d3bbb4741a6ab81dbcd73b0754725f304b118c4c738449639fd060ee8b5da9" + ], + "markers": "python_version >= '3.9'", + "version": "==4.15.2" }, "python-dateutil": { "hashes": [ @@ -928,7 +1390,7 @@ "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.8.2" }, "python-dotenv": { @@ -951,64 +1413,70 @@ }, "six": { "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", + "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.17.0" }, "tinycss2": { "hashes": [ - "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847", - "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627" + "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", + "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289" ], - "markers": "python_version >= '3.7'", - "version": "==1.2.1" + "markers": "python_version >= '3.8'", + "version": "==1.4.0" }, "urllib3": { "hashes": [ - "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", - "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", + "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" ], - "markers": "python_version >= '3.8'", - "version": "==2.1.0" + "markers": "python_version >= '3.9'", + "version": "==2.5.0" }, "uvloop": { "hashes": [ - "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", - "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", - "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b", - "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", - "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797", - "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5", - "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", - "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d", - "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be", - "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd", - "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", - "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17", - "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", - "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", - "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", - "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", - "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", - "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", - "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", - "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67", - "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", - "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", - "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd", - "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", - "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7", - "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", - "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", - "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", - "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", - "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7", - "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256" + "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", + "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", + "sha256:10da8046cc4a8f12c91a1c39d1dd1585c41162a15caaef165c2174db9ef18bdc", + "sha256:17df489689befc72c39a08359efac29bbee8eee5209650d4b9f34df73d22e414", + "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", + "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", + "sha256:221f4f2a1f46032b403bf3be628011caf75428ee3cc204a22addf96f586b19fd", + "sha256:2d1f581393673ce119355d56da84fe1dd9d2bb8b3d13ce792524e1607139feff", + "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", + "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", + "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", + "sha256:460def4412e473896ef179a1671b40c039c7012184b627898eea5072ef6f017a", + "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", + "sha256:46923b0b5ee7fc0020bef24afe7836cb068f5050ca04caf6b487c513dc1a20b2", + "sha256:53e420a3afe22cdcf2a0f4846e377d16e718bc70103d7088a4f7623567ba5fb0", + "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", + "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", + "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", + "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", + "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", + "sha256:88cb67cdbc0e483da00af0b2c3cdad4b7c61ceb1ee0f33fe00e09c81e3a6cb75", + "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", + "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", + "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", + "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", + "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", + "sha256:bc09f0ff191e61c2d592a752423c767b4ebb2986daa9ed62908e2b1b9a9ae206", + "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", + "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", + "sha256:c097078b8031190c934ed0ebfee8cc5f9ba9642e6eb88322b9958b649750f72b", + "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", + "sha256:e678ad6fe52af2c58d2ae3c73dc85524ba8abe637f134bf3564ed07f555c5e79", + "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", + "sha256:f0ce1b49560b1d2d8a2977e3ba4afb2414fb46b86a1b64056bc4ab929efdafbe", + "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", + "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", + "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2" ], "markers": "sys_platform != 'win32'", - "version": "==0.19.0" + "version": "==0.21.0" }, "webencodings": { "hashes": [ @@ -1019,118 +1487,255 @@ }, "yarl": { "hashes": [ - "sha256:09c19e5f4404574fcfb736efecf75844ffe8610606f3fccc35a1515b8b6712c4", - "sha256:0ab5baaea8450f4a3e241ef17e3d129b2143e38a685036b075976b9c415ea3eb", - "sha256:0d155a092bf0ebf4a9f6f3b7a650dc5d9a5bbb585ef83a52ed36ba46f55cc39d", - "sha256:126638ab961633f0940a06e1c9d59919003ef212a15869708dcb7305f91a6732", - "sha256:1a0a4f3aaa18580038cfa52a7183c8ffbbe7d727fe581300817efc1e96d1b0e9", - "sha256:1d93461e2cf76c4796355494f15ffcb50a3c198cc2d601ad8d6a96219a10c363", - "sha256:26a1a8443091c7fbc17b84a0d9f38de34b8423b459fb853e6c8cdfab0eacf613", - "sha256:271d63396460b6607b588555ea27a1a02b717ca2e3f2cf53bdde4013d7790929", - "sha256:28a108cb92ce6cf867690a962372996ca332d8cda0210c5ad487fe996e76b8bb", - "sha256:29beac86f33d6c7ab1d79bd0213aa7aed2d2f555386856bb3056d5fdd9dab279", - "sha256:2c757f64afe53a422e45e3e399e1e3cf82b7a2f244796ce80d8ca53e16a49b9f", - "sha256:2dad8166d41ebd1f76ce107cf6a31e39801aee3844a54a90af23278b072f1ccf", - "sha256:2dc72e891672343b99db6d497024bf8b985537ad6c393359dc5227ef653b2f17", - "sha256:2f3c8822bc8fb4a347a192dd6a28a25d7f0ea3262e826d7d4ef9cc99cd06d07e", - "sha256:32435d134414e01d937cd9d6cc56e8413a8d4741dea36af5840c7750f04d16ab", - "sha256:3cfa4dbe17b2e6fca1414e9c3bcc216f6930cb18ea7646e7d0d52792ac196808", - "sha256:3d5434b34100b504aabae75f0622ebb85defffe7b64ad8f52b8b30ec6ef6e4b9", - "sha256:4003f380dac50328c85e85416aca6985536812c082387255c35292cb4b41707e", - "sha256:44e91a669c43f03964f672c5a234ae0d7a4d49c9b85d1baa93dec28afa28ffbd", - "sha256:4a14907b597ec55740f63e52d7fee0e9ee09d5b9d57a4f399a7423268e457b57", - "sha256:4ce77d289f8d40905c054b63f29851ecbfd026ef4ba5c371a158cfe6f623663e", - "sha256:4d6d74a97e898c1c2df80339aa423234ad9ea2052f66366cef1e80448798c13d", - "sha256:51382c72dd5377861b573bd55dcf680df54cea84147c8648b15ac507fbef984d", - "sha256:525cd69eff44833b01f8ef39aa33a9cc53a99ff7f9d76a6ef6a9fb758f54d0ff", - "sha256:53ec65f7eee8655bebb1f6f1607760d123c3c115a324b443df4f916383482a67", - "sha256:5f74b015c99a5eac5ae589de27a1201418a5d9d460e89ccb3366015c6153e60a", - "sha256:6280353940f7e5e2efaaabd686193e61351e966cc02f401761c4d87f48c89ea4", - "sha256:632c7aeb99df718765adf58eacb9acb9cbc555e075da849c1378ef4d18bf536a", - "sha256:6465d36381af057d0fab4e0f24ef0e80ba61f03fe43e6eeccbe0056e74aadc70", - "sha256:66a6dbf6ca7d2db03cc61cafe1ee6be838ce0fbc97781881a22a58a7c5efef42", - "sha256:6d350388ba1129bc867c6af1cd17da2b197dff0d2801036d2d7d83c2d771a682", - "sha256:7217234b10c64b52cc39a8d82550342ae2e45be34f5bff02b890b8c452eb48d7", - "sha256:721ee3fc292f0d069a04016ef2c3a25595d48c5b8ddc6029be46f6158d129c92", - "sha256:72a57b41a0920b9a220125081c1e191b88a4cdec13bf9d0649e382a822705c65", - "sha256:73cc83f918b69110813a7d95024266072d987b903a623ecae673d1e71579d566", - "sha256:778df71c8d0c8c9f1b378624b26431ca80041660d7be7c3f724b2c7a6e65d0d6", - "sha256:79e1df60f7c2b148722fb6cafebffe1acd95fd8b5fd77795f56247edaf326752", - "sha256:7c86d0d0919952d05df880a1889a4f0aeb6868e98961c090e335671dea5c0361", - "sha256:7eaf13af79950142ab2bbb8362f8d8d935be9aaf8df1df89c86c3231e4ff238a", - "sha256:828235a2a169160ee73a2fcfb8a000709edf09d7511fccf203465c3d5acc59e4", - "sha256:8535e111a064f3bdd94c0ed443105934d6f005adad68dd13ce50a488a0ad1bf3", - "sha256:88d2c3cc4b2f46d1ba73d81c51ec0e486f59cc51165ea4f789677f91a303a9a7", - "sha256:8a2538806be846ea25e90c28786136932ec385c7ff3bc1148e45125984783dc6", - "sha256:8dab30b21bd6fb17c3f4684868c7e6a9e8468078db00f599fb1c14e324b10fca", - "sha256:8f18a7832ff85dfcd77871fe677b169b1bc60c021978c90c3bb14f727596e0ae", - "sha256:946db4511b2d815979d733ac6a961f47e20a29c297be0d55b6d4b77ee4b298f6", - "sha256:96758e56dceb8a70f8a5cff1e452daaeff07d1cc9f11e9b0c951330f0a2396a7", - "sha256:9a172c3d5447b7da1680a1a2d6ecdf6f87a319d21d52729f45ec938a7006d5d8", - "sha256:9a5211de242754b5e612557bca701f39f8b1a9408dff73c6db623f22d20f470e", - "sha256:9df9a0d4c5624790a0dea2e02e3b1b3c69aed14bcb8650e19606d9df3719e87d", - "sha256:aa4643635f26052401750bd54db911b6342eb1a9ac3e74f0f8b58a25d61dfe41", - "sha256:aed37db837ecb5962469fad448aaae0f0ee94ffce2062cf2eb9aed13328b5196", - "sha256:af52725c7c39b0ee655befbbab5b9a1b209e01bb39128dce0db226a10014aacc", - "sha256:b0b8c06afcf2bac5a50b37f64efbde978b7f9dc88842ce9729c020dc71fae4ce", - "sha256:b61e64b06c3640feab73fa4ff9cb64bd8182de52e5dc13038e01cfe674ebc321", - "sha256:b7831566595fe88ba17ea80e4b61c0eb599f84c85acaa14bf04dd90319a45b90", - "sha256:b8bc5b87a65a4e64bc83385c05145ea901b613d0d3a434d434b55511b6ab0067", - "sha256:b8d51817cf4b8d545963ec65ff06c1b92e5765aa98831678d0e2240b6e9fd281", - "sha256:b9f9cafaf031c34d95c1528c16b2fa07b710e6056b3c4e2e34e9317072da5d1a", - "sha256:bb72d2a94481e7dc7a0c522673db288f31849800d6ce2435317376a345728225", - "sha256:c25ec06e4241e162f5d1f57c370f4078797ade95c9208bd0c60f484834f09c96", - "sha256:c405d482c320a88ab53dcbd98d6d6f32ada074f2d965d6e9bf2d823158fa97de", - "sha256:c4472fe53ebf541113e533971bd8c32728debc4c6d8cc177f2bff31d011ec17e", - "sha256:c4b1efb11a8acd13246ffb0bee888dd0e8eb057f8bf30112e3e21e421eb82d4a", - "sha256:c5f3faeb8100a43adf3e7925d556801d14b5816a0ac9e75e22948e787feec642", - "sha256:c6f034386e5550b5dc8ded90b5e2ff7db21f0f5c7de37b6efc5dac046eb19c10", - "sha256:c99ddaddb2fbe04953b84d1651149a0d85214780e4d0ee824e610ab549d98d92", - "sha256:ca6b66f69e30f6e180d52f14d91ac854b8119553b524e0e28d5291a724f0f423", - "sha256:cccdc02e46d2bd7cb5f38f8cc3d9db0d24951abd082b2f242c9e9f59c0ab2af3", - "sha256:cd49a908cb6d387fc26acee8b7d9fcc9bbf8e1aca890c0b2fdfd706057546080", - "sha256:cf7a4e8de7f1092829caef66fd90eaf3710bc5efd322a816d5677b7664893c93", - "sha256:cfd77e8e5cafba3fb584e0f4b935a59216f352b73d4987be3af51f43a862c403", - "sha256:d34c4f80956227f2686ddea5b3585e109c2733e2d4ef12eb1b8b4e84f09a2ab6", - "sha256:d61a0ca95503867d4d627517bcfdc28a8468c3f1b0b06c626f30dd759d3999fd", - "sha256:d81657b23e0edb84b37167e98aefb04ae16cbc5352770057893bd222cdc6e45f", - "sha256:d92d897cb4b4bf915fbeb5e604c7911021a8456f0964f3b8ebbe7f9188b9eabb", - "sha256:dd318e6b75ca80bff0b22b302f83a8ee41c62b8ac662ddb49f67ec97e799885d", - "sha256:dd952b9c64f3b21aedd09b8fe958e4931864dba69926d8a90c90d36ac4e28c9a", - "sha256:e0e7e83f31e23c5d00ff618045ddc5e916f9e613d33c5a5823bc0b0a0feb522f", - "sha256:e0f17d1df951336a02afc8270c03c0c6e60d1f9996fcbd43a4ce6be81de0bd9d", - "sha256:e2a16ef5fa2382af83bef4a18c1b3bcb4284c4732906aa69422cf09df9c59f1f", - "sha256:e36021db54b8a0475805acc1d6c4bca5d9f52c3825ad29ae2d398a9d530ddb88", - "sha256:e73db54c967eb75037c178a54445c5a4e7461b5203b27c45ef656a81787c0c1b", - "sha256:e741bd48e6a417bdfbae02e088f60018286d6c141639359fb8df017a3b69415a", - "sha256:f7271d6bd8838c49ba8ae647fc06469137e1c161a7ef97d778b72904d9b68696", - "sha256:fc391e3941045fd0987c77484b2799adffd08e4b6735c4ee5f054366a2e1551d", - "sha256:fc94441bcf9cb8c59f51f23193316afefbf3ff858460cb47b5758bf66a14d130", - "sha256:fe34befb8c765b8ce562f0200afda3578f8abb159c76de3ab354c80b72244c41", - "sha256:fe8080b4f25dfc44a86bedd14bc4f9d469dfc6456e6f3c5d9077e81a5fedfba7", - "sha256:ff34cb09a332832d1cf38acd0f604c068665192c6107a439a92abfd8acf90fe2" - ], - "markers": "python_version >= '3.7'", - "version": "==1.9.3" + "sha256:019c2798df9d74fe8fb9cc916702966dad7e2e3eef66b4c19f8084ba5e0b6ecd", + "sha256:01ef0d7f1dd60d241529dc79a3fa647451056394f9a5ed05fbceeb5009de6122", + "sha256:028c59136b65fccfe5578520a3fb2a94e06601c545ca0125b7e07b3a39f238a5", + "sha256:0416fde6dc89866f4ff494a0ffcc4b2da984cf61aaa279c14a53495e8520c809", + "sha256:056fc431f10ae35aa2375c9de2b68176b34f54fb7de8bc2e830564e2a3d29efa", + "sha256:069cfc781f5d68389c8a4228f720cab453e1b6fa606bcd710a9cc01e38ffe2c1", + "sha256:06c71f698ac5b5bfdde1ce3d58d262235b3c1109f083286c96c01cee64ebf705", + "sha256:0a9454d4c513a3aa2fd87471126e0d32b01f1bf58d49309a84431521488b30c4", + "sha256:0a94664fe3c6dd44c36e875af0f338769dc9f80a1ccd58f53cf5f5b8341e8627", + "sha256:0aaa36261a1279b03fa0655a9bd879cc42e06406adaae0150fde25c778393fcb", + "sha256:0ab4e81b455dd8beb2537648be972eb63351bbe34fb55457054392fee759ac9c", + "sha256:0b16c889a7168ecf7242946dec013c9fb82ade70ab8e6b5d3290383390083a2b", + "sha256:0cc3eeea8f527119aac1b0c874bbb8092675da85fd6d9d91946cf7be7d59477b", + "sha256:0d37bf6f601c714b536159715d9ec6e69bf8a94dc593abe54c1b43ac339eb5e7", + "sha256:0e485c4f9f5b5b9fc10b4bb0ba5baf145ed0a702756da126c9f62f8a89b391a8", + "sha256:10580c7d9b50c883b93cc0ab5c91df5cc1e5b18713736471d622776b01c36810", + "sha256:1107b93c32cf7d7e2ece9bbb1b1820ecb923cfea24c8aa599a309434ed37d707", + "sha256:13c9b91e2e1224a8d33addc1bd58bb097396519c4c49524843947776b8dd45da", + "sha256:140402fef1f482840fcd4d2ee9bfd07f08bfb2c80dd215220bd47f6f3566b882", + "sha256:14872677213d96552268f927982d4c83f5d0674b0d54b623d8e909710460ab14", + "sha256:16957642c0594feba56a4bb430eea5f9132bb589ebb8b4740c0d47f022a5d976", + "sha256:1743d35529a8b9b2b6a9e5f00076c2c146726453051621b739b081dda382ee70", + "sha256:1754b3380ffef931b8eae3bbe6fc0b249db56294ffeb6e6124c2d031a82a3a92", + "sha256:178860382595f3b1fab2596b19570adc495c6211eee8b10a4112ce96342f6515", + "sha256:18e8272a4166d2bb68d51f86445f061aac21fcfc9c1d5b1187f9703f362d85dd", + "sha256:190356a39fed15109ab95600f8ff59c1a0665625f4cfe910388c82b965edaf87", + "sha256:19df967a905f2f9a09733dfb397baa6807772502931000f881943d7cfc6e9f47", + "sha256:1a0ba7cd4eabb7433e69737f33333d9e79d8ab6dbaa2f4d7313ad6611200cc65", + "sha256:1b5d29c1a86cc63e55f69253b8c817091884c4e1b79ee762a8643de834e70a64", + "sha256:1bff86850033508af0a7f9973ced23a16de7ba4ce30521080e2330475b8711b5", + "sha256:1e0b01fa225ec12e54c73be383326ae2a4a59a4a465a0e6cac679f314ed85d1f", + "sha256:20b2dca6588f65b5def8e8eae4a087d504eacf34b5b435c021cc233ce82f6c15", + "sha256:212a5c72d551f94b7799b5de1cc55ddcf3c69ac462f7c0df1beee7e47edb9fef", + "sha256:221aa7c16055e8b9f2eba718cbbf10f174e47f02e659156804d9679654c5cbb0", + "sha256:2227fcc88bebdc90ed87d924bdf8a76a730fc91796641e41ca747aabd13a5074", + "sha256:2584651c047718ec4a863ee81a5432f6f68974e6f0c58975f0aab408ff839798", + "sha256:26940710eece6b5b08a108e81d6325b47610990cd8bb28886e27d4a0d6d60930", + "sha256:2a05a5e018de23c4d2d75c8fbd8b58aba5199f752326f60a22aa37ef28d987bd", + "sha256:2b2f8e0bbdf49530ed09b2bc988082cab6ce24f4c49a0efd2ff5d9477cb29084", + "sha256:2b841c5529f9ca28cf23ed34c8040547ca6530b968a482c14de96a6ade470ee5", + "sha256:30b6a56388963ebe5428d835112439563bcaa9c8349742aeac68a8ad5a231221", + "sha256:37b5e7bba1f6df45058cff626c83a0e8a1259363095e768046a3da40b24e9c4f", + "sha256:3b539230fd64f283594a56633a9751d299cde5ab9c2791452ccb47a865842fa8", + "sha256:3cbae81bff4014ca7745fa11f7015f784198fadba8935cf5a71e139b0b124ff0", + "sha256:430e162d961af58f3dcac58aed038ba974ec7a73803ac6545db2338fbd0f4ed3", + "sha256:45aa7711e1933bac1679f9534f112767f1fe64c97a8576294b760015d0fb65e7", + "sha256:45f17adf1b8bc56becb1bc38f293b1714866786c9d79e245fb3d3731788622a6", + "sha256:4b449296e2ba009481385349138130f209bb502c4f890b3298bf3ea13d43a6d5", + "sha256:4d5af10c9f580002c0ea6c8f345c8cadb2e0c53dce77d3f2639b9e31e5f24d3d", + "sha256:4ee80f79c928ce7c18cf3ad18a5da7f3f0f1b08923e08d87143d628a6d5d2dba", + "sha256:4fcce63c1117ef0630a92a0bda3028a96dc17feed2c78c713de4c963d13d1881", + "sha256:5110ebfe3cbf892b41590fcf4aa70a17ac0a5e9a73b4a8945010bdb970ff1b93", + "sha256:52a8b7541c5d8240ae32d12014f8448e29e1ae794f9443ea020b926cff8691e1", + "sha256:56ead8d62b346c1ec67a6e8b2f66885180ea5bec05821d309ac1cb99ff4aacf5", + "sha256:5c0123db2d86d169554d5fb19421e8e455efcfe2e8e254328b85c77e712ab506", + "sha256:5e7d24e9c3b638f046fcd9a5374818257a8c6d1c3fc7542887521b81a970fbc2", + "sha256:6074904025bc462b0b3f7230b36d8942d9a611b783ce1431ade5ad6a8867b73d", + "sha256:60dcb45a3d762460ac5014755c190db36acf127f68d68643cde7d6d7ce0e5627", + "sha256:61bf6233d04ccba7906f5261ff3628fa97a68fc526cda3d9dd092d2f49926933", + "sha256:63157d66cf7682dec8b3117491cb87a5d8e1cd56df59156d5553ab9721895d19", + "sha256:6378871775e0feb225693cbdad3d997327af0ab4c7e39d93849008c73b867134", + "sha256:6614325ef69d8a53c731ed5e4bd55449ffc5fe86ad652789c0afc853099662ad", + "sha256:66248832212957d8bad28e8d9d307be1d987b94ffaf7e7cca658a349d52d3572", + "sha256:692603a8f82e7baa86bb3921d5002b711788cec547b626030f1f6cf017290ab7", + "sha256:701cd0ee20fe9087c21229db579f2222a75c229b44840a7df7b2d795522068c3", + "sha256:7331a7d2683e644b7830c924ac634fa3ec52257f5098f6415d8ad765d6bc29a8", + "sha256:74b2e94d3e410ed49c7a4cb2c3a5089a6632f7ab68e49bb612b972577e26e771", + "sha256:780313d2a1877adef0e3839ef9596ad53ab640715e7f453e7304c121cd7f262d", + "sha256:7a9d0efd6ff6f4f55ff7a37852e4fcdc24b1feb3b09e204df3dda990171fe725", + "sha256:7b7d46a6ca781a336c7317d9c1d381bebb3b0da5309c2293dd1c4fe3d62942bf", + "sha256:7d271fed8a4b46723db5001619c36192d94a3bd49d76ef186f13abb6897ff8e5", + "sha256:7d5d8eeb1051fac562d80aad7b6b496e2901f41fc2b0988c61016a1426996f66", + "sha256:7d8917677a64304db00ec46629aff335c935c788a10a164b29464b7e2d707463", + "sha256:7da21f0d9bebdc8ac1dde69b3c0951b339984883e2a751790f0f72cbfd1dd007", + "sha256:863d7401d3a109f75c7a5ca0e33e8fb7704a61007f4bda03e08e05f3bf1af40f", + "sha256:866c17223f7d734377a260a2800e14791cb5e55ec252de624e053a0b36b8568a", + "sha256:884d4f3509dfc810299d14faed24c0fbcac82ae2a9737b0cb1d8f7a5e8a291f8", + "sha256:88ff0c0bea02ce78af8a91b173fb43aad5f1945221182f77ba7816fd01bcbc4c", + "sha256:8910f022242c0a15f6d77d781c6ba16bb88d9fed3bff8964de652ee2580029ac", + "sha256:8bfdb95a85404a943197264461b904a2e9e228fd28cb86e4e57321f5b4d5be07", + "sha256:8d39e71705dccdcdf077752d4dc0fcc9554bf797f8af0c1db59f0025a72d4ed2", + "sha256:92a719bb1118f302f6fc3c7638e78e152de8bf279c0200325af831afa1b60f1a", + "sha256:9618070bb76a064c13020323b7fc23c332930604dfbc96b77e7ad7baca960c12", + "sha256:973d630c00bbaf07045870d331c8596bf4fa07aa8eb10d69a02c542af714f128", + "sha256:99febd7a9efab236d798d72ca878ae0d92fffadcc2e472636d6e093ce2677980", + "sha256:9eaf0f28ed19919bdeb02cfa541daaee8a05c070227eaab8d9732f1eebfe2869", + "sha256:9ee84156656d4a09010c280f41011f0a317c62e745f7a2cfafabd8035823fe2d", + "sha256:a999c5c50af0e564cab5bbbbbee97d494eb0e09f99481385108ddfd90049b3fe", + "sha256:ac210d628b9a50699189ec09f0f73630c78e60027d81d75c461deebf7aed752c", + "sha256:ac487adb2e838d03aed0c1a9df4ba348ca2c215bf2afa2f6e1d9449c7029971f", + "sha256:ad6775f8bd57e2c4068246e03c00e212e01b27ea0e96a4b4f17f9d45d80cd5d8", + "sha256:aef7e9b60b371f4d3c3ea80c0ef2d841623dd64aad7718ab815a3205bd4bdf08", + "sha256:b0e38cf49c17e35831ec38029854b772717d6071f0419b74b80be57571a83d0a", + "sha256:b68c0c9deb2fcd183376600df99e88032a9c192d352b0f781e130b09220ef1cf", + "sha256:b846a17f810708f1beff6ad088121fd35334729df3e520412163c74ef49433f7", + "sha256:bc8a06f7bc45219b2c191d68e779e6b3f62e32d09d2f8cf7b381ba1dcb7a68f9", + "sha256:bd6ca6e66b4fee5e879207854f125b94f6ad77e98ddae4d7778d2e96be94ede4", + "sha256:c115756cb1cad49862aa0c2687922ed10da6be7689cf35e3ab602c4a6da2d8fb", + "sha256:c2c4da0802f6897f7fb766c4f0e7f55c96b103981265fcf12b648d088bee3744", + "sha256:c464852c531e44abc5ba05d0c0c97a8fa63719106b3dca46fedae14daedf46ae", + "sha256:c48477c6ff32032624aa122323adc343055bb7e347e01146a86e652b06281731", + "sha256:c6dfa317e4b87052589253f50119211b801146ff7214b8684830e9084fa6eb0a", + "sha256:c763e42a29ac98e7240004e36b7ce231046054393182f1f630c897ce049579ed", + "sha256:c7fab0120e4ea5a2c170382bd27345b2b56e22b6270b40e4231a68f090ce17ed", + "sha256:cb56dcaf10bac9713fff133074d2460b0b217f27760a2b642efb2bc4179bfde6", + "sha256:cfcca979b72f240bac7c73564026eae4c97639151a415e6ced6392d120022d2d", + "sha256:d070756da822a538231d519ce290a1423ab108d6174ad1497cd020bee503d818", + "sha256:d5c35188fac7e448b52eb3916365fe5f59eb27fecec21ba757eea4f650584ca5", + "sha256:d8da09e318a2916da7110d1147355056ee89d61b4ded49ba3ada717517f2fc71", + "sha256:d957259a15e45e5fa5d51ce59ab7519cff8d3de0109d404627276ec68412c718", + "sha256:de1ab4f48fbcb4c2e578951338cc1c8245e510be061d2773a2d47616fb0d6470", + "sha256:de9f7a51f828f73ea0ca2e856a7cac8766752f336241abdb6c5f45f402dd59ea", + "sha256:e00aaf1574075439ccb0b827ca822c5a97c0103351ead292c42a9f17bd2eae0a", + "sha256:e6df05c2234786b15632cd154d60122c302fd860d89c3ee47c166ad92eb6ae55", + "sha256:e7a8f70c7c283d0b4af90314ff8d969c9ab2c7ee522bfb612f42c542935f6e11", + "sha256:ec1f6129c1175d15da7b7c13ae5d4226acf6b5fe362c5b01ac9787fa88c64781", + "sha256:ececd833be7fd8390371c082103916702170e81a1b22beb989452f934def78d6", + "sha256:ee77d3c82576baae66a3281c9a6431fc84281443a7e36a8490a45b3dbbb60446", + "sha256:f0a6cd797394761692cc6f33b10f2ea46789ac0b7fba82b6df737f51e1297122", + "sha256:f1b3930f0934057825227016a141ce16aad4b2a3805fb4e2de71064d042d72e9", + "sha256:f9dae6ef584d3241571674ed7bcd1a28b003a5f0c3a6ca561ab42e5ce0c482e3", + "sha256:fb09731156f54dfd8bb097ce80f9436c2a1a282061ba29e526c375c69086b764" + ], + "markers": "python_version >= '3.9'", + "version": "==1.21.0" + }, + "zstandard": { + "hashes": [ + "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", + "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", + "sha256:05353cef599a7b0b98baca9b068dd36810c3ef0f42bf282583f438caf6ddcee3", + "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", + "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", + "sha256:07b527a69c1e1c8b5ab1ab14e2afe0675614a09182213f21a0717b62027b5936", + "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", + "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", + "sha256:106281ae350e494f4ac8a80470e66d1fe27e497052c8d9c3b95dc4cf1ade81aa", + "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", + "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", + "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", + "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", + "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", + "sha256:19796b39075201d51d5f5f790bf849221e58b48a39a5fc74837675d8bafc7362", + "sha256:1cd5da4d8e8ee0e88be976c294db744773459d51bb32f707a0f166e5ad5c8649", + "sha256:1f3689581a72eaba9131b1d9bdbfe520ccd169999219b41000ede2fca5c1bfdb", + "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", + "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", + "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", + "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", + "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", + "sha256:25f8f3cd45087d089aef5ba3848cd9efe3ad41163d3400862fb42f81a3a46701", + "sha256:2b6bd67528ee8b5c5f10255735abc21aa106931f0dbaf297c7be0c886353c3d0", + "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", + "sha256:3756b3e9da9b83da1796f8809dd57cb024f838b9eeafde28f3cb472012797ac1", + "sha256:37daddd452c0ffb65da00620afb8e17abd4adaae6ce6310702841760c2c26860", + "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", + "sha256:3b870ce5a02d4b22286cf4944c628e0f0881b11b3f14667c1d62185a99e04f53", + "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", + "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", + "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", + "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", + "sha256:4b14abacf83dfb5c25eb4e4a79520de9e7e205f72c9ee7702f91233ae57d33a2", + "sha256:4b6d83057e713ff235a12e73916b6d356e3084fd3d14ced499d84240f3eecee0", + "sha256:4d441506e9b372386a5271c64125f72d5df6d2a8e8a2a45a0ae09b03cb781ef7", + "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", + "sha256:51526324f1b23229001eb3735bc8c94f9c578b1bd9e867a0a646a3b17109f388", + "sha256:53e08b2445a6bc241261fea89d065536f00a581f02535f8122eba42db9375530", + "sha256:53f94448fe5b10ee75d246497168e5825135d54325458c4bfffbaafabcc0a577", + "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", + "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", + "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", + "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", + "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", + "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", + "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", + "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", + "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", + "sha256:75ffc32a569fb049499e63ce68c743155477610532da1eb38e7f24bf7cd29e74", + "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", + "sha256:78228d8a6a1c177a96b94f7e2e8d012c55f9c760761980da16ae7546a15a8e9b", + "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", + "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", + "sha256:81dad8d145d8fd981b2962b686b2241d3a1ea07733e76a2f15435dfb7fb60150", + "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", + "sha256:89c4b48479a43f820b749df49cd7ba2dbc2b1b78560ecb5ab52985574fd40b27", + "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", + "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", + "sha256:9174f4ed06f790a6869b41cba05b43eeb9a35f8993c4422ab853b705e8112bbd", + "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", + "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", + "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", + "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", + "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", + "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", + "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", + "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", + "sha256:a51ff14f8017338e2f2e5dab738ce1ec3b5a851f23b18c1ae1359b1eecbee6df", + "sha256:a5a419712cf88862a45a23def0ae063686db3d324cec7edbe40509d1a79a0aab", + "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", + "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", + "sha256:ab85470ab54c2cb96e176f40342d9ed41e58ca5733be6a893b730e7af9c40550", + "sha256:b9af1fe743828123e12b41dd8091eca1074d0c1569cc42e6e1eee98027f2bbd0", + "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", + "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", + "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", + "sha256:c2ba942c94e0691467ab901fc51b6f2085ff48f2eea77b1a48240f011e8247c7", + "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", + "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", + "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", + "sha256:d8c56bb4e6c795fc77d74d8e8b80846e1fb8292fc0b5060cd8131d522974b751", + "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", + "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", + "sha256:e05ab82ea7753354bb054b92e2f288afb750e6b439ff6ca78af52939ebbc476d", + "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", + "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", + "sha256:e59fdc271772f6686e01e1b3b74537259800f57e24280be3f29c8a0deb1904dd", + "sha256:e7360eae90809efd19b886e59a09dad07da4ca9ba096752e61a2e03c8aca188e", + "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", + "sha256:ea9d54cc3d8064260114a0bbf3479fc4a98b21dffc89b3459edd506b69262f6e", + "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", + "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", + "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", + "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", + "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", + "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", + "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", + "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01" + ], + "markers": "python_version >= '3.9'", + "version": "==0.25.0" } }, "develop": { "astroid": { "hashes": [ - "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca", - "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e" + "sha256:4148645659b08b70d72460ed1921158027a9e53ae8b7234149b1400eddacbb93", + "sha256:92fcf218b89f449cdf9f7b39a269f8d5d617b27be68434912e11e79203963a17" ], "markers": "python_full_version >= '3.8.0'", - "version": "==3.0.1" + "version": "==3.0.3" }, "bandit": { "hashes": [ - "sha256:75665181dc1e0096369112541a056c59d1c5f66f9bb74a8d686c3c362b83f549", - "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e" + "sha256:3348e934d736fcdb68b6aa4030487097e23a501adf3e7827b63658df464dddd0", + "sha256:dbfe9c25fc6961c2078593de55fd19f2559f9e45b99f1272341f5b95dea4e56b" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==1.7.5" + "markers": "python_version >= '3.9'", + "version": "==1.8.6" }, "black": { "hashes": [ @@ -1159,51 +1764,35 @@ }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", + "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4" ], - "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "markers": "python_version >= '3.10'", + "version": "==8.3.0" }, "dill": { "hashes": [ - "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e", - "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03" + "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", + "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049" ], - "markers": "python_version < '3.11'", - "version": "==0.3.7" - }, - "gitdb": { - "hashes": [ - "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", - "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b" - ], - "markers": "python_version >= '3.7'", - "version": "==4.0.11" - }, - "gitpython": { - "hashes": [ - "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4", - "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.40" + "markers": "python_version >= '3.8'", + "version": "==0.4.0" }, "isort": { "hashes": [ - "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", - "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" + "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", + "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" ], "markers": "python_full_version >= '3.8.0'", - "version": "==5.12.0" + "version": "==5.13.2" }, "markdown-it-py": { "hashes": [ - "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", - "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", + "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3" ], - "markers": "python_version >= '3.8'", - "version": "==3.0.0" + "markers": "python_version >= '3.10'", + "version": "==4.0.0" }, "mccabe": { "hashes": [ @@ -1223,11 +1812,11 @@ }, "mypy-extensions": { "hashes": [ - "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", - "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", + "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558" ], - "markers": "python_version >= '3.5'", - "version": "==1.0.0" + "markers": "python_version >= '3.8'", + "version": "==1.1.0" }, "packaging": { "hashes": [ @@ -1240,35 +1829,27 @@ }, "pathspec": { "hashes": [ - "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", - "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" + "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", + "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" ], - "markers": "python_version >= '3.7'", - "version": "==0.11.2" - }, - "pbr": { - "hashes": [ - "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda", - "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9" - ], - "markers": "python_version >= '2.6'", - "version": "==6.0.0" + "markers": "python_version >= '3.8'", + "version": "==0.12.1" }, "platformdirs": { "hashes": [ - "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b", - "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731" + "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", + "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf" ], - "markers": "python_version >= '3.7'", - "version": "==4.0.0" + "markers": "python_version >= '3.9'", + "version": "==4.4.0" }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", + "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.8'", + "version": "==2.19.2" }, "pylint": { "hashes": [ @@ -1281,99 +1862,145 @@ }, "pyyaml": { "hashes": [ - "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", - "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", - "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", - "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", - "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", - "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", - "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", - "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", - "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", - "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", - "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", - "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", - "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", - "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", - "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", - "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", - "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", - "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", - "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", - "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", - "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", - "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", - "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", - "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", - "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", - "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", - "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", - "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", - "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", - "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", - "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", - "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", - "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", - "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", - "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", - "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", - "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", - "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", - "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", - "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", - "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", - "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", - "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", - "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", - "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", - "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", - "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", - "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", - "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", - "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", + "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", + "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", + "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", + "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", + "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", + "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", + "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", + "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", + "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", + "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", + "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6", + "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", + "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", + "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", + "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", + "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", + "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", + "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295", + "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", + "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", + "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", + "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", + "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", + "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", + "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", + "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", + "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b", + "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", + "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", + "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", + "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", + "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369", + "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", + "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", + "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", + "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", + "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", + "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", + "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", + "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", + "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", + "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", + "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", + "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", + "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", + "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", + "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", + "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", + "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4", + "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", + "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", + "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", + "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", + "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", + "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", + "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", + "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", + "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", + "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", + "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", + "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f", + "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", + "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", + "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", + "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", + "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", + "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", + "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", + "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3", + "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", + "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", + "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" ], - "markers": "python_version >= '3.6'", - "version": "==6.0.1" + "markers": "python_version >= '3.8'", + "version": "==6.0.3" }, "rich": { "hashes": [ - "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", - "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" + "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", + "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.7.0" - }, - "smmap": { - "hashes": [ - "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", - "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" - ], - "markers": "python_version >= '3.7'", - "version": "==5.0.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==14.1.0" }, "stevedore": { "hashes": [ - "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d", - "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c" + "sha256:18363d4d268181e8e8452e71a38cd77630f345b2ef6b4a8d5614dac5ee0d18cf", + "sha256:d31496a4f4df9825e1a1e4f1f74d19abb0154aff311c3b376fcc89dae8fccd73" ], - "markers": "python_version >= '3.8'", - "version": "==5.1.0" + "markers": "python_version >= '3.9'", + "version": "==5.5.0" }, "tomli": { "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", + "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", + "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", + "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", + "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", + "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", + "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", + "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", + "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", + "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", + "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", + "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", + "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", + "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", + "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", + "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", + "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", + "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", + "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", + "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", + "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", + "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", + "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", + "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", + "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", + "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", + "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", + "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", + "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", + "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" ], - "markers": "python_version < '3.11'", - "version": "==2.0.1" + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.2.1" }, "tomlkit": { "hashes": [ - "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4", - "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba" + "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", + "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0" ], - "markers": "python_version >= '3.7'", - "version": "==0.12.3" + "markers": "python_version >= '3.8'", + "version": "==0.13.3" }, "typing-extensions": { "hashes": [ diff --git a/README.md b/README.md index 2e3d32e344..50f71890ca 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ <img src="https://img.shields.io/discord/1079074933008781362.svg?label=Discord&logo=Discord&colorB=7289da&style=for-the-badge" alt="Support"> </a> - <a href="https://patreon.com/kyber"> - <img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Patreon"> + <a href="https://buymeacoffee.com/modmaildev"> + <img src="https://img.shields.io/badge/buymeacoffee-donate-ff813f.svg?style=for-the-badge&logo=buy-me-a-coffee" alt="Buy Me A Coffee"> </a> <a href="https://www.python.org/downloads/"> @@ -48,7 +48,7 @@ Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way. -This bot is free for everyone and always will be. If you like this project and would like to show your appreciation, you can support us on **[Patreon](https://www.patreon.com/kyber)**, cool benefits included! +This bot is free for everyone and always will be. If you like this project and would like to show your appreciation, you can support us on **[Buy Me A Coffee](https://buymeacoffee.com/modmaildev)**, cool benefits included! For up-to-date setup instructions, please visit our [**documentation**](https://docs.modmail.dev/installation) page. @@ -72,7 +72,7 @@ Our Logviewer will save the threads so you can view previous threads through the * When you close a thread, Modmail will generate a log link and post it to your log channel. * Native Discord dark-mode feel. * Markdown/formatting support. - * Login via Discord to protect your logs ([premium Patreon feature](https://patreon.com/kyber)). + * Login via Discord to protect your logs ([premium feature](https://buymeacoffee.com/modmaildev/membership)). * See past logs of a user with `?logs`. * Searchable by text queries using `?logs search`. @@ -90,15 +90,15 @@ There are a number of options for hosting your very own dedicated Modmail bot. Visit our [**documentation**](https://docs.modmail.dev/installation) page for detailed guidance on how to deploy your Modmail bot. -### Patreon Hosting +### Paid Hosting -If you don't want the trouble of renting and configuring your server to host Modmail, we got a solution for you! We offer hosting and maintenance of your own, private Modmail bot (including a Logviewer) through [**Patreon**](https://patreon.com/kyber). +If you don't want the trouble of renting and configuring your server to host Modmail, we got a solution for you! We offer hosting and maintenance of your own, private Modmail bot (including a Logviewer) through [**Buy Me A Coffee**](https://buymeacoffee.com/modmaildev/membership). ## FAQ **Q: Where can I find the Modmail bot invite link?** -**A:** Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following our [**documentation**](https://docs.modmail.dev/installation) steps or subscribe to [**Patreon**](https://patreon.com/kyber). +**A:** Unfortunately, due to how this bot functions, it cannot be invited. The lack of an invite link is to ensure an individuality to your server and grant you full control over your bot and data. Nonetheless, you can quickly obtain a free copy of Modmail for your server by following our [**documentation**](https://docs.modmail.dev/installation) steps or subscribe to [**Buy Me A Coffee**](https://buymeacoffee.com/modmaildev/membership). **Q: Where can I find out more info about Modmail?** @@ -147,13 +147,6 @@ Advertise Your Server: </a> <br> <br> -Help Us • Help Other's: -<br> -<a href='https://discord.gg/5yQCFzY6HU'> - <img height=100 src='https://i.imgur.com/Gi3jxeH.gif' style='margin:5px'> -</a> -<br> -<br> Discord Advice Center: <br> <a href='https://discord.gg/zmwZy5fd9v'> @@ -161,20 +154,19 @@ Discord Advice Center: </a> <br> <br> -Blacklight Promotions: +Kistó Bakery: <br> -<a href='https://blacklightpromotions.online'> - <img height=100 src='https://i.imgur.com/yLgE6h6.png' style='margin:5px'> +<a href='https://www.roblox.com/communities/9318596/Kist#!/about'> + <img height=100 src='https://i.imgur.com/ck81JiJ.jpeg' style='margin:5px'> </a> - -Become a sponsor on [Patreon](https://patreon.com/kyber). +Become a sponsor on [Buy Me A Coffee](https://buymeacoffee.com/modmaildev/membership). ## Contributing Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/modmail-dev/modmail/blob/master/.github/CONTRIBUTING.md) before you get started. -If you like this project and would like to show your appreciation, support us on **[Patreon](https://www.patreon.com/kyber)**! +If you like this project and would like to show your appreciation, support us on **[Buy Me A Coffee](https://buymeacoffee.com/modmaildev)**! ## Beta Testing diff --git a/SPONSORS.json b/SPONSORS.json index b6212b8ed7..cdaf3621ac 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -112,33 +112,6 @@ "title": "uncommon community" } }, - { - "embed": { - "author": { - "name": "Help us • Help Others" - }, - "title": "Join Today", - "url": "https://discord.gg/5yQCFzY6HU", - "description": "At Help Us • Help Others, we accept as true with inside the transformative electricity of cooperation and kindness. Each one people has the capability to make a meaningful impact by means of helping and caring for others. Whether you want assistance or want to offer it, this is the right region for you!", - "fields": [ - { - "name": "What we offer:", - "value": "`🎬` - Active community\n`👮` - Active staff around the globe! \n`🛜` - 40+ Advertising channels to grow your socials!\n`💎` - Boosting Perks\n`🎉` - Event's monthly especially bank holiday roles!!\n`🔢` - Unique levelling systems\n`📞` - Multiple voice channels including gaming!\n`🎁` - Exclusive giveaways!" - }, - { - "name": "We Are Hiring", - "value": "`🔵` - Moderators\n`🔵` - Human Resources\n`🔵` - Community Team\n`🔵` - Partnership Manager\n`🔵` - Growth Manager\n`🚀` Much more to come!\n\n\nJoin Today!" - } - ], - "image": { - "url": "https://cdn.discordapp.com/attachments/1218338794416246874/1243635366326567002/AD_animated.gif" - }, - "color": 45300, - "footer": { - "text": "Help Us • Help Others" - } - } - }, { "embed": { "description": "> Be apart of our community as we start to grow! and embark on a long journey.\n——————————————————-\n**What we offer?**\n\n➺〚🖌️〛Custom Liveries \n➺〚❤️〛Friendly and Growing community.\n➺〚🤝〛Partnerships.\n➺〚🎮〛Daily SSUs. \n➺〚🚨〛Great roleplays.\n➺〚💬〛Kind and Professional staff\n➺〚🎉〛Giveaways!!! \n——————————————————-\n**Emergency Services**\n\n➺〚🚔〛NY Police Force\n➺〚🚒〛Fire & Emergency NY\n➺〚🚧〛NY department of transportation \n\n——————————————————-\n**Whitelisted**\nComing soon!\n——————————————————-\n**What are we looking for!**\n\n➺〚💬〛More members\n➺〚⭐〛Staff Members - **WE'RE HIRING!**\n➺〚🤝〛Partnerships\n➺〚💎〛Boosters\n——————————————————\n\n**[Join now](https://discord.com/invite/qt62qSnKVa)**", diff --git a/bot.py b/bot.py index 3f13ef7ced..671d9ab9c4 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.1.2" +__version__ = "4.2.0" import asyncio @@ -48,7 +48,15 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint, human_join +from core.utils import ( + extract_block_timestamp, + normalize_alias, + parse_alias, + truncate, + tryint, + human_join, + extract_forwarded_content, +) logger = getLogger(__name__) @@ -879,10 +887,182 @@ async def process_dm_modmail(self, message: discord.Message) -> None: return sent_emoji, blocked_emoji = await self.retrieve_emoji() + # Handle forwarded messages (Discord forwards) + # See: https://discord.com/developers/docs/resources/message#message-reference-content-attribution-forwards + # 1. Multi-forward (message_snapshots) + if hasattr(message, "flags") and getattr(message.flags, "has_snapshot", False): + if hasattr(message, "message_snapshots") and message.message_snapshots: + thread = await self.threads.find(recipient=message.author) + if thread is None: + delta = await self.get_thread_cooldown(message.author) + if delta: + await message.channel.send( + embed=discord.Embed( + title=self.config["cooldown_thread_title"], + description=self.config["cooldown_thread_response"].format(delta=delta), + color=self.error_color, + ) + ) + return + if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): + embed = discord.Embed( + title=self.config["disabled_new_thread_title"], + color=self.error_color, + description=self.config["disabled_new_thread_response"], + ) + embed.set_footer( + text=self.config["disabled_new_thread_footer"], + icon_url=self.get_guild_icon(guild=message.guild, size=128), + ) + logger.info( + "A new thread was blocked from %s due to disabled Modmail.", message.author + ) + await self.add_reaction(message, blocked_emoji) + return await message.channel.send(embed=embed) + thread = await self.threads.create(message.author, message=message) + else: + if self.config["dm_disabled"] == DMDisabled.ALL_THREADS: + embed = discord.Embed( + title=self.config["disabled_current_thread_title"], + color=self.error_color, + description=self.config["disabled_current_thread_response"], + ) + embed.set_footer( + text=self.config["disabled_current_thread_footer"], + icon_url=self.get_guild_icon(guild=message.guild, size=128), + ) + logger.info("A message was blocked from %s due to disabled Modmail.", message.author) + await self.add_reaction(message, blocked_emoji) + return await message.channel.send(embed=embed) + # Extract forwarded content using utility function + combined_content = extract_forwarded_content(message) or "[Forwarded message with no content]" + + class ForwardedMessage: + def __init__(self, original_message, forwarded_content): + self.author = original_message.author + self.content = forwarded_content + self.attachments = [] + self.stickers = [] + self.created_at = original_message.created_at + self.embeds = [] + self.id = original_message.id + self.flags = original_message.flags + self.message_snapshots = original_message.message_snapshots + self.type = getattr(original_message, "type", None) + + forwarded_msg = ForwardedMessage(message, combined_content) + await thread.send(forwarded_msg) + await self.add_reaction(message, sent_emoji) + self.dispatch("thread_reply", thread, False, message, False, False) + return + else: + message.content = "[Forwarded message with no content]" + # 2. Single-message forward (MessageType.forward) + elif getattr(message, "type", None) == getattr(discord.MessageType, "forward", None): + # Check for message.reference and its type + ref = getattr(message, "reference", None) + if ref and getattr(ref, "type", None) == getattr(discord, "MessageReferenceType", None).forward: + # Try to fetch the referenced message + ref_msg = None + try: + if ref.resolved: + ref_msg = ref.resolved + elif ref.message_id and ref.channel_id: + channel = self.get_channel(ref.channel_id) or ( + await self.fetch_channel(ref.channel_id) + ) + ref_msg = await channel.fetch_message(ref.message_id) + except Exception: + ref_msg = None + if ref_msg: + # Forward the referenced message as if it was sent + thread = await self.threads.find(recipient=message.author) + if thread is None: + delta = await self.get_thread_cooldown(message.author) + if delta: + await message.channel.send( + embed=discord.Embed( + title=self.config["cooldown_thread_title"], + description=self.config["cooldown_thread_response"].format(delta=delta), + color=self.error_color, + ) + ) + return + if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): + embed = discord.Embed( + title=self.config["disabled_new_thread_title"], + color=self.error_color, + description=self.config["disabled_new_thread_response"], + ) + embed.set_footer( + text=self.config["disabled_new_thread_footer"], + icon_url=self.get_guild_icon(guild=message.guild, size=128), + ) + logger.info( + "A new thread was blocked from %s due to disabled Modmail.", message.author + ) + await self.add_reaction(message, blocked_emoji) + return await message.channel.send(embed=embed) + thread = await self.threads.create(message.author, message=message) + else: + if self.config["dm_disabled"] == DMDisabled.ALL_THREADS: + embed = discord.Embed( + title=self.config["disabled_current_thread_title"], + color=self.error_color, + description=self.config["disabled_current_thread_response"], + ) + embed.set_footer( + text=self.config["disabled_current_thread_footer"], + icon_url=self.get_guild_icon(guild=message.guild, size=128), + ) + logger.info( + "A message was blocked from %s due to disabled Modmail.", message.author + ) + await self.add_reaction(message, blocked_emoji) + return await message.channel.send(embed=embed) + + # Create a forwarded message wrapper to preserve forward info + class ForwardedMessage: + def __init__(self, original_message, ref_message): + self.author = original_message.author + # Use the utility function to extract content or fallback to ref message content + extracted_content = extract_forwarded_content(original_message) + self.content = ( + extracted_content + or ref_message.content + or "[Forwarded message with no text content]" + ) + self.attachments = getattr(ref_message, "attachments", []) + self.stickers = getattr(ref_message, "stickers", []) + self.created_at = original_message.created_at + self.embeds = getattr(ref_message, "embeds", []) + self.id = original_message.id + self.type = getattr(original_message, "type", None) + self.reference = original_message.reference + + forwarded_msg = ForwardedMessage(message, ref_msg) + await thread.send(forwarded_msg) + await self.add_reaction(message, sent_emoji) + self.dispatch("thread_reply", thread, False, message, False, False) + return + else: + message.content = "[Forwarded message with no content]" + if message.type not in [discord.MessageType.default, discord.MessageType.reply]: return thread = await self.threads.find(recipient=message.author) + if thread and thread.snoozed: + await thread.restore_from_snooze() + self.threads.cache[thread.id] = thread + # Update the DB with the new channel_id after restoration + if thread.channel: + await self.api.logs.update_one( + {"recipient.id": str(thread.id)}, {"$set": {"channel_id": str(thread.channel.id)}} + ) + # Re-fetch the thread object to ensure channel is valid + thread = await self.threads.find(recipient=message.author) + if thread is None: delta = await self.get_thread_cooldown(message.author) if delta: @@ -1156,6 +1336,19 @@ async def on_message(self, message): content = "" await self.mention_channel.send(content=content, embed=em) + # --- MODERATOR-ONLY MESSAGE LOGGING --- + # If a moderator sends a message directly in a thread channel (not via modmail command), log it + if not message.author.bot and not isinstance(message.channel, discord.DMChannel): + thread = await self.threads.find(channel=message.channel) + if thread is not None: + ctxs = await self.get_contexts(message) + is_command = any(ctx.command for ctx in ctxs) + if not is_command: + # Only log if not a command + perms = message.channel.permissions_for(message.author) + if perms.manage_messages or perms.administrator: + await self.api.append_log(message, type_="internal") + await self.process_commands(message) async def process_commands(self, message): @@ -1193,8 +1386,6 @@ async def process_commands(self, message): or self.config.get("plain_reply_without_command") ): await thread.reply(message, anonymous=anonymous, plain=plain) - else: - await self.api.append_log(message, type_="internal") elif ctx.invoked_with: exc = commands.CommandNotFound('Command "{}" is not found'.format(ctx.invoked_with)) self.dispatch("command_error", ctx, exc) @@ -1212,7 +1403,10 @@ async def on_typing(self, channel, user, _): thread = await self.threads.find(recipient=user) if thread: - await thread.channel.typing() + try: + await thread.channel.typing() + except Exception: + pass else: if not self.config.get("mod_typing"): return @@ -1222,7 +1416,10 @@ async def on_typing(self, channel, user, _): for user in thread.recipients: if await self.is_blocked(user): continue - await user.typing() + try: + await user.typing() + except Exception: + pass async def handle_reaction_events(self, payload): user = self.get_user(payload.user_id) @@ -1529,7 +1726,10 @@ async def on_command_error( return if isinstance(exception, (commands.BadArgument, commands.BadUnionArgument)): - await context.typing() + try: + await context.typing() + except Exception: + pass await context.send(embed=discord.Embed(color=self.error_color, description=str(exception))) elif isinstance(exception, commands.CommandNotFound): logger.warning("CommandNotFound: %s", exception) @@ -1820,7 +2020,7 @@ def main(): sys.exit(0) # check discord version - discord_version = "2.3.2" + discord_version = "2.6.3" if discord.__version__ != discord_version: logger.error( "Dependencies are not updated, run pipenv install. discord.py version expected %s, received %s", diff --git a/cogs/modmail.py b/cogs/modmail.py index e2a0039384..d7d9d7b010 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1,8 +1,9 @@ import asyncio import re -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta from itertools import zip_longest from typing import Optional, Union, List, Tuple, Literal +import logging import discord from discord.ext import commands @@ -29,6 +30,19 @@ class Modmail(commands.Cog): def __init__(self, bot): self.bot = bot + def _resolve_user(self, user_str): + """Helper to resolve a user from mention, ID, or username.""" + import re + + if not user_str: + return None + if user_str.isdigit(): + return int(user_str) + match = re.match(r"<@!?(\d+)>", user_str) + if match: + return int(match.group(1)) + return None + @commands.command() @trigger_typing @checks.has_permissions(PermissionLevel.OWNER) @@ -94,7 +108,7 @@ async def setup(self, ctx): name="Thanks for using our bot!", value="If you like what you see, consider giving the " "[repo a star](https://github.com/modmail-dev/modmail) :star: and if you are " - "feeling extra generous, buy us coffee on [Patreon](https://patreon.com/kyber) :heart:!", + "feeling extra generous, buy us coffee on [Buy Me A Coffee](https://buymeacoffee.com/modmaildev) :heart:!", ) embed.set_footer(text=f'Type "{self.bot.prefix}help" for a complete list of commands.') @@ -143,6 +157,21 @@ async def snippet(self, ctx, *, name: str.lower = None): """ if name is not None: + if name == "compact": + embeds = [] + + for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): + description = format_description(i, names) + embed = discord.Embed(color=self.bot.main_color, description=description) + embed.set_author( + name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128) + ) + embeds.append(embed) + + session = EmbedPaginatorSession(ctx, *embeds) + await session.run() + return + snippet_name = self.bot._resolve_snippet(name) if snippet_name is None: @@ -162,13 +191,14 @@ async def snippet(self, ctx, *, name: str.lower = None): embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) return await ctx.send(embed=embed) - embeds = [] - - for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): - description = format_description(i, names) - embed = discord.Embed(color=self.bot.main_color, description=description) + embeds = [discord.Embed(color=self.bot.main_color) for _ in range((len(self.bot.snippets) // 10) + 1)] + for embed in embeds: embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) - embeds.append(embed) + + for i, snippet in enumerate(sorted(self.bot.snippets.items())): + embeds[i // 10].add_field( + name=snippet[0], value=return_or_truncate(snippet[1], 350), inline=False + ) session = EmbedPaginatorSession(ctx, *embeds) await session.run() @@ -849,7 +879,10 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str ) if self.bot.config["show_timestamp"]: em.timestamp = discord.utils.utcnow() - em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) + em.set_footer( + text=str(ctx.author), + icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else None, + ) for u in users: to_exec.append(u.send(embed=em)) @@ -865,7 +898,9 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str ) if self.bot.config["show_timestamp"]: em.timestamp = discord.utils.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) + em.set_footer( + text=f"{users[0]}", icon_url=users[0].display_avatar.url if users[0].display_avatar else None + ) for i in ctx.thread.recipients: if i not in users: @@ -942,7 +977,10 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ) if self.bot.config["show_timestamp"]: em.timestamp = discord.utils.utcnow() - em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url) + em.set_footer( + text=str(ctx.author), + icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else None, + ) for u in users: to_exec.append(u.send(embed=em)) @@ -958,7 +996,9 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ) if self.bot.config["show_timestamp"]: em.timestamp = discord.utils.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) + em.set_footer( + text=f"{users[0]}", icon_url=users[0].display_avatar.url if users[0].display_avatar else None + ) for i in ctx.thread.recipients: if i not in users: @@ -1036,7 +1076,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) - em.set_footer(text=name, icon_url=avatar_url) + em.set_footer(text=name, icon_url=avatar_url if avatar_url else None) for u in users: to_exec.append(u.send(embed=em)) @@ -1052,7 +1092,9 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, ) if self.bot.config["show_timestamp"]: em.timestamp = discord.utils.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) + em.set_footer( + text=f"{users[0]}", icon_url=users[0].display_avatar.url if users[0].display_avatar else None + ) for i in ctx.thread.recipients: if i not in users: @@ -1125,7 +1167,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) - em.set_footer(text=name, icon_url=avatar_url) + em.set_footer(text=name, icon_url=avatar_url if avatar_url else None) for u in users: to_exec.append(u.send(embed=em)) @@ -1141,7 +1183,9 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro ) if self.bot.config["show_timestamp"]: em.timestamp = discord.utils.utcnow() - em.set_footer(text=f"{users[0]}", icon_url=users[0].display_avatar.url) + em.set_footer( + text=f"{users[0]}", icon_url=users[0].display_avatar.url if users[0].display_avatar else None + ) for i in ctx.thread.recipients: if i not in users: @@ -1156,6 +1200,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() async def logs(self, ctx, *, user: User = None): """ Get previous Modmail thread logs of a member. @@ -1165,7 +1210,8 @@ async def logs(self, ctx, *, user: User = None): `user` may be a user ID, mention, or name. """ - await ctx.typing() + async with safe_typing(ctx): + pass if not user: thread = ctx.thread @@ -1297,7 +1343,8 @@ async def logs_search(self, ctx, limit: Optional[int] = None, *, query): Provide a `limit` to specify the maximum number of logs the bot should find. """ - await ctx.typing() + async with safe_typing(ctx): + pass entries = await self.bot.api.search_by_text(query, limit) @@ -1326,7 +1373,7 @@ async def reply(self, ctx, *, msg: str = ""): ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message) @commands.command(aliases=["formatreply"]) @@ -1348,7 +1395,7 @@ async def freply(self, ctx, *, msg: str = ""): msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author ) ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message) @commands.command(aliases=["formatanonreply"]) @@ -1370,7 +1417,7 @@ async def fareply(self, ctx, *, msg: str = ""): msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author ) ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message, anonymous=True) @commands.command(aliases=["formatplainreply"]) @@ -1392,7 +1439,7 @@ async def fpreply(self, ctx, *, msg: str = ""): msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author ) ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message, plain=True) @commands.command(aliases=["formatplainanonreply"]) @@ -1414,7 +1461,7 @@ async def fpareply(self, ctx, *, msg: str = ""): msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author ) ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message, anonymous=True, plain=True) @commands.command(aliases=["anonreply", "anonymousreply"]) @@ -1431,7 +1478,7 @@ async def areply(self, ctx, *, msg: str = ""): and `anon_tag` config variables to do so. """ ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message, anonymous=True) @commands.command(aliases=["plainreply"]) @@ -1445,7 +1492,7 @@ async def preply(self, ctx, *, msg: str = ""): automatically embedding image URLs. """ ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message, plain=True) @commands.command(aliases=["plainanonreply", "plainanonymousreply"]) @@ -1459,7 +1506,7 @@ async def pareply(self, ctx, *, msg: str = ""): automatically embedding image URLs. """ ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): await ctx.thread.reply(ctx.message, anonymous=True, plain=True) @commands.group(invoke_without_command=True) @@ -1472,7 +1519,7 @@ async def note(self, ctx, *, msg: str = ""): Useful for noting context. """ ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): msg = await ctx.thread.note(ctx.message) await msg.pin() @@ -1484,7 +1531,7 @@ async def note_persistent(self, ctx, *, msg: str = ""): Take a persistent note about the current user. """ ctx.message.content = msg - async with ctx.typing(): + async with safe_typing(ctx): msg = await ctx.thread.note(ctx.message, persistent=True) await msg.pin() await self.bot.api.create_note(recipient=ctx.thread.recipient, message=ctx.message, message_id=msg.id) @@ -1621,6 +1668,7 @@ async def contact( creator=creator, category=category, manual_trigger=manual_trigger, + # The minimum character check is enforced in ThreadManager.create ) if thread.cancelled: @@ -1644,7 +1692,9 @@ async def contact( ) if self.bot.config["show_timestamp"]: em.timestamp = discord.utils.utcnow() - em.set_footer(text=f"{creator}", icon_url=creator.display_avatar.url) + em.set_footer( + text=f"{creator}", icon_url=creator.display_avatar.url if creator.display_avatar else None + ) for u in users: await u.send(embed=em) @@ -2213,6 +2263,243 @@ async def isenable(self, ctx): return await ctx.send(embed=embed) + @commands.command(usage="[duration]") + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def snooze(self, ctx, *, duration: UserFriendlyTime = None): + """ + Snooze this thread: deletes the channel, keeps the ticket open in DM, and restores it when the user replies or a moderator unsnoozes it. + Optionally specify a duration, e.g. 'snooze 2d' for 2 days. + Uses config: max_snooze_time, snooze_title, snooze_text + """ + thread = ctx.thread + if thread.snoozed: + await ctx.send("This thread is already snoozed.") + logging.info(f"[SNOOZE] Thread for {getattr(thread.recipient, 'id', None)} already snoozed.") + return + max_snooze = self.bot.config.get("max_snooze_time") + if max_snooze is None: + max_snooze = 604800 + max_snooze = int(max_snooze) + if duration: + snooze_for = int((duration.dt - duration.now).total_seconds()) + if snooze_for > max_snooze: + snooze_for = max_snooze + else: + snooze_for = max_snooze + + # Storing snooze_start and snooze_for in the log entry + now = datetime.now(timezone.utc) + await self.bot.api.logs.update_one( + {"recipient.id": str(thread.id)}, + {"$set": {"snooze_start": now.isoformat(), "snooze_for": snooze_for}}, + ) + embed = discord.Embed( + title=self.bot.config.get("snooze_title") or "Thread Snoozed", + description=self.bot.config.get("snooze_text") or "This thread has been snoozed.", + color=self.bot.error_color, + ) + await ctx.send(embed=embed) + ok = await thread.snooze(moderator=ctx.author, snooze_for=snooze_for) + if ok: + logging.info( + f"[SNOOZE] Thread for {getattr(thread.recipient, 'id', None)} snoozed for {snooze_for}s." + ) + self.bot.threads.cache[thread.id] = thread + else: + await ctx.send("Failed to snooze this thread.") + logging.error(f"[SNOOZE] Failed to snooze thread for {getattr(thread.recipient, 'id', None)}.") + + @commands.command() + @checks.has_permissions(PermissionLevel.SUPPORTER) + async def unsnooze(self, ctx, *, user: str = None): + """ + Unsnooze a thread: restores the channel and replays messages. + You can specify a user by mention or ID, or run in a thread channel to unsnooze that thread. + Uses config: unsnooze_text + """ + import discord + + thread = None + user_obj = None + if user is not None: + user_id = self._resolve_user(user) + if user_id: + try: + user_obj = await self.bot.get_or_fetch_user(user_id) + except Exception: + user_obj = discord.Object(user_id) + if user_obj: + thread = await self.bot.threads.find(recipient=user_obj) + if not thread: + await ctx.send(f"[DEBUG] No thread found for user {user} (obj: {user_obj}).") + logging.warning(f"[UNSNOOZE] No thread found for user {user} (obj: {user_obj})") + return + elif hasattr(ctx, "thread"): + thread = ctx.thread + else: + await ctx.send("This is not a Modmail thread.") + logging.warning("[UNSNOOZE] Not a Modmail thread context.") + return + if not thread.snoozed: + await ctx.send("This thread is not snoozed.") + logging.info(f"[UNSNOOZE] Thread for {getattr(thread.recipient, 'id', None)} is not snoozed.") + return + + # Manually fetch snooze_data if the thread object doesn't have it + if not thread.snooze_data: + log_entry = await self.bot.api.logs.find_one({"recipient.id": str(thread.id), "snoozed": True}) + if log_entry: + thread.snooze_data = log_entry.get("snooze_data") + + ok = await thread.restore_from_snooze() + if ok: + self.bot.threads.cache[thread.id] = thread + await ctx.send( + self.bot.config.get("unsnooze_text") or "This thread has been unsnoozed and restored." + ) + logging.info(f"[UNSNOOZE] Thread for {getattr(thread.recipient, 'id', None)} unsnoozed.") + else: + await ctx.send("Failed to unsnooze this thread.") + logging.error( + f"[UNSNOOZE] Failed to unsnooze thread for {getattr(thread.recipient, 'id', None)}." + ) + + @commands.command() + @checks.has_permissions(PermissionLevel.SUPPORTER) + async def snoozed(self, ctx): + """ + List all currently snoozed threads/users. + """ + snoozed_threads = [thread for thread in self.bot.threads.cache.values() if thread.snoozed] + if not snoozed_threads: + await ctx.send("No threads are currently snoozed.") + return + + lines = [] + now = datetime.now(timezone.utc) + for thread in snoozed_threads: + user = thread.recipient.name if thread.recipient else "Unknown" + user_id = thread.id + + since_str = "?" + until_str = "?" + + if thread.snooze_data: + since = thread.snooze_data.get("snooze_start") + duration = thread.snooze_data.get("snooze_for") + + if since: + try: + since_dt = datetime.fromisoformat(since) + since_str = f"<t:{int(since_dt.timestamp())}:R>" # Discord relative timestamp + except (ValueError, TypeError) as e: + logging.warning(f"[SNOOZED] Invalid snooze_start for {user_id}: {since} ({e})") + else: + logging.warning(f"[SNOOZED] Missing snooze_start for {user_id}") + + if duration and since_str != "?": + try: + until_dt = datetime.fromisoformat(since) + timedelta(seconds=int(duration)) + until_str = f"<t:{int(until_dt.timestamp())}:R>" + except (ValueError, TypeError) as e: + logging.warning( + f"[SNOOZED] Invalid until time for {user_id}: {since} + {duration} ({e})" + ) + + lines.append(f"- {user} (`{user_id}`) since {since_str}, until {until_str}") + + await ctx.send("Snoozed threads:\n" + "\n".join(lines)) + + async def cog_load(self): + self.bot.loop.create_task(self.snooze_auto_unsnooze_task()) + + async def snooze_auto_unsnooze_task(self): + await self.bot.wait_until_ready() + while True: + now = datetime.now(timezone.utc) + snoozed = await self.bot.api.logs.find({"snoozed": True}).to_list(None) + for entry in snoozed: + start = entry.get("snooze_start") + snooze_for = entry.get("snooze_for") + if not start: + continue + start_dt = datetime.fromisoformat(start) + if snooze_for is not None: + duration = int(snooze_for) + else: + max_snooze = self.bot.config.get("max_snooze_time") + if max_snooze is None: + max_snooze = 604800 + duration = int(max_snooze) + if (now - start_dt).total_seconds() > duration: + # Auto-unsnooze + thread = await self.bot.threads.find(recipient_id=int(entry["recipient"]["id"])) + if thread and thread.snoozed: + await thread.restore_from_snooze() + await asyncio.sleep(60) + + async def process_dm_modmail(self, message: discord.Message) -> None: + # ... existing code ... + # Before processing, check if thread is snoozed and auto-unsnooze + thread = await self.threads.find(recipient=message.author) + if thread and thread.snoozed: + await thread.restore_from_snooze() + # Ensure the thread object in the cache is updated with the new channel + self.threads.cache[thread.id] = thread + # ... rest of the method unchanged ... + + @commands.command() + @checks.has_permissions(PermissionLevel.OWNER) + async def clearsnoozed(self, ctx): + """ + List all snoozed threads and ask for confirmation before clearing (unsnoozing) all of them. + Only proceed if the user confirms. + """ + snoozed = await self.bot.api.logs.find({"snoozed": True}).to_list(None) + if not snoozed: + await ctx.send("No threads are currently snoozed.") + return + lines = [] + for entry in snoozed: + user = entry.get("recipient", {}).get("name", "Unknown") + user_id = entry.get("recipient", {}).get("id", "?") + lines.append(f"- {user} (`{user_id}`)") + msg = await ctx.send( + "The following threads are currently snoozed and will be unsnoozed if you confirm:\n" + + "\n".join(lines) + + "\n\nType `yes` to confirm, or anything else to cancel." + ) + + def check(m): + return m.author == ctx.author and m.channel == ctx.channel + + try: + reply = await self.bot.wait_for("message", check=check, timeout=30) + except asyncio.TimeoutError: + await ctx.send("Timed out. No threads were unsnoozed.") + return + if reply.content.strip().lower() != "yes": + await ctx.send("Cancelled. No threads were unsnoozed.") + return + count = 0 + for entry in snoozed: + user_id = entry.get("recipient", {}).get("id") + if not user_id: + continue + user_obj = None + try: + user_obj = await self.bot.get_or_fetch_user(int(user_id)) + except Exception: + user_obj = discord.Object(int(user_id)) + thread = await self.bot.threads.find(recipient=user_obj) + if thread and thread.snoozed: + ok = await thread.restore_from_snooze() + if ok: + self.bot.threads.cache[thread.id] = thread + count += 1 + await ctx.send(f"Unsnoozed {count} threads.") + async def setup(bot): await bot.add_cog(Modmail(bot)) diff --git a/cogs/plugins.py b/cogs/plugins.py index 78bc0aa544..c7dceb7283 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -20,7 +20,7 @@ from core import checks from core.models import PermissionLevel, getLogger from core.paginator import EmbedPaginatorSession -from core.utils import trigger_typing, truncate +from core.utils import trigger_typing, truncate, safe_typing logger = getLogger(__name__) @@ -484,7 +484,7 @@ async def update_plugin(self, ctx, plugin_name): embed = discord.Embed(description="Plugin is not installed.", color=self.bot.error_color) return await ctx.send(embed=embed) - async with ctx.typing(): + async with safe_typing(ctx): embed = discord.Embed( description=f"Successfully updated {plugin.name}.", color=self.bot.main_color ) @@ -759,7 +759,10 @@ async def plugins_registry_compact(self, ctx): for page in pages: embed = discord.Embed(color=self.bot.main_color, description=page) - embed.set_author(name="Plugin Registry", icon_url=self.bot.user.display_avatar.url) + embed.set_author( + name="Plugin Registry", + icon_url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None, + ) embeds.append(embed) paginator = EmbedPaginatorSession(ctx, *embeds) diff --git a/cogs/utility.py b/cogs/utility.py index 31cb065a28..16eeafc4d6 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1,3 +1,4 @@ +from core.utils import trigger_typing, truncate, safe_typing import asyncio import inspect import os @@ -90,7 +91,9 @@ async def format_cog_help(self, cog, *, no_cog=False): embed.add_field(name="Commands", value=format_ or "No commands.") name = cog.qualified_name + " - Help" if not no_cog else "Miscellaneous Commands" - embed.set_author(name=name, icon_url=bot.user.display_avatar.url) + embed.set_author( + name=name, icon_url=bot.user.display_avatar.url if bot.user.display_avatar else None + ) embed.set_footer( text=f'Type "{prefix}{self.command_attrs["name"]} command" ' @@ -322,10 +325,10 @@ async def about(self, ctx): embed = discord.Embed(color=self.bot.main_color, timestamp=discord.utils.utcnow()) embed.set_author( name="Modmail - About", - icon_url=self.bot.user.display_avatar.url, + icon_url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None, url="https://discord.gg/F34cRU8", ) - embed.set_thumbnail(url=self.bot.user.display_avatar.url) + embed.set_thumbnail(url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None) desc = "This is an open source Discord bot that serves as a means for " desc += "members to easily communicate with server administrators in " @@ -359,7 +362,7 @@ async def about(self, ctx): embed.add_field( name="Support the Developers", value="This bot is completely free for everyone. We rely on kind individuals " - "like you to support us on [`Patreon`](https://patreon.com/kyber) (perks included) " + "like you to support us on [`Buy Me A Coffee`](https://buymeacoffee.com/modmaildev) (perks included for memberships) " "to keep this bot free forever!", inline=False, ) @@ -854,7 +857,10 @@ async def config_get(self, ctx, *, key: str.lower = None): if key in keys: desc = f"`{key}` is set to `{self.bot.config[key]}`" embed = discord.Embed(color=self.bot.main_color, description=desc) - embed.set_author(name="Config variable", icon_url=self.bot.user.display_avatar.url) + embed.set_author( + name="Config variable", + icon_url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None, + ) else: embed = discord.Embed( @@ -871,7 +877,10 @@ async def config_get(self, ctx, *, key: str.lower = None): color=self.bot.main_color, description="Here is a list of currently set configuration variable(s).", ) - embed.set_author(name="Current config(s):", icon_url=self.bot.user.display_avatar.url) + embed.set_author( + name="Current config(s):", + icon_url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None, + ) config = self.bot.config.filter_default(self.bot.config) for name, value in config.items(): @@ -1354,7 +1363,18 @@ async def permissions_add( key = self.bot.modmail_guild.get_member(value) if key is not None: logger.info("Granting %s access to Modmail category.", key.name) - await self.bot.main_category.set_permissions(key, read_messages=True) + try: + await self.bot.main_category.set_permissions(key, read_messages=True) + except discord.Forbidden: + warn = discord.Embed( + title="Missing Permissions", + color=self.bot.error_color, + description=( + "I couldn't update the Modmail category permissions. " + "Please grant me 'Manage Channels' and 'Manage Roles' for this category." + ), + ) + await ctx.send(embed=warn) embed = discord.Embed( title="Success", @@ -1445,17 +1465,50 @@ async def permissions_remove( if level > PermissionLevel.REGULAR: if value == -1: logger.info("Denying @everyone access to Modmail category.") - await self.bot.main_category.set_permissions( - self.bot.modmail_guild.default_role, read_messages=False - ) + try: + await self.bot.main_category.set_permissions( + self.bot.modmail_guild.default_role, read_messages=False + ) + except discord.Forbidden: + warn = discord.Embed( + title="Missing Permissions", + color=self.bot.error_color, + description=( + "I couldn't update the Modmail category permissions. " + "Please grant me 'Manage Channels' and 'Manage Roles' for this category." + ), + ) + await ctx.send(embed=warn) elif isinstance(user_or_role, discord.Role): logger.info("Denying %s access to Modmail category.", user_or_role.name) - await self.bot.main_category.set_permissions(user_or_role, overwrite=None) + try: + await self.bot.main_category.set_permissions(user_or_role, overwrite=None) + except discord.Forbidden: + warn = discord.Embed( + title="Missing Permissions", + color=self.bot.error_color, + description=( + "I couldn't update the Modmail category permissions. " + "Please grant me 'Manage Channels' and 'Manage Roles' for this category." + ), + ) + await ctx.send(embed=warn) else: member = self.bot.modmail_guild.get_member(value) if member is not None and member != self.bot.modmail_guild.me: logger.info("Denying %s access to Modmail category.", member.name) - await self.bot.main_category.set_permissions(member, overwrite=None) + try: + await self.bot.main_category.set_permissions(member, overwrite=None) + except discord.Forbidden: + warn = discord.Embed( + title="Missing Permissions", + color=self.bot.error_color, + description=( + "I couldn't update the Modmail category permissions. " + "Please grant me 'Manage Channels' and 'Manage Roles' for this category." + ), + ) + await ctx.send(embed=warn) embed = discord.Embed( title="Success", @@ -1678,7 +1731,7 @@ async def oauth(self, ctx): """ Commands relating to logviewer oauth2 login authentication. - This functionality on your logviewer site is a [**Patron**](https://patreon.com/kyber) only feature. + This functionality on your logviewer site is a [**Buy Me A Coffee**](https://buymeacoffee.com/modmaildev/membership) only feature. """ await ctx.send_help(ctx.command) @@ -1912,8 +1965,12 @@ async def github(self, ctx): if data: embed = discord.Embed(title="GitHub", description="Current User", color=self.bot.main_color) user = data["user"] - embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) - embed.set_thumbnail(url=user["avatar_url"]) + embed.set_author( + name=user["username"], + icon_url=user["avatar_url"] if user["avatar_url"] else None, + url=user["url"], + ) + embed.set_thumbnail(url=user["avatar_url"] if user["avatar_url"] else None) await ctx.send(embed=embed) else: await ctx.send(embed=discord.Embed(title="Invalid Github Token", color=self.bot.error_color)) @@ -1943,7 +2000,11 @@ async def update(self, ctx, *, flag: str = ""): data = await self.bot.api.get_user_info() if data: user = data["user"] - embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) + embed.set_author( + name=user["username"], + icon_url=user["avatar_url"] if user["avatar_url"] else None, + url=user["url"], + ) await ctx.send(embed=embed) else: error = None @@ -1982,7 +2043,7 @@ async def update(self, ctx, *, flag: str = ""): embed.set_author( name=user["username"] + " - Updating bot", - icon_url=user["avatar_url"], + icon_url=user["avatar_url"] if user["avatar_url"] else None, url=user["url"], ) @@ -2000,7 +2061,11 @@ async def update(self, ctx, *, flag: str = ""): color=self.bot.main_color, ) embed.set_footer(text="Force update") - embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) + embed.set_author( + name=user["username"], + icon_url=user["avatar_url"] if user["avatar_url"] else None, + url=user["url"], + ) await ctx.send(embed=embed) else: command = "git pull" diff --git a/core/_color_data.py b/core/_color_data.py index 0ac42d5c1f..13ec45620e 100644 --- a/core/_color_data.py +++ b/core/_color_data.py @@ -3,7 +3,6 @@ Slightly modified to conform with usage. """ - BASE_COLORS = { "b": "0000ff", "g": "007f00", diff --git a/core/changelog.py b/core/changelog.py index 06f141fce1..465479bf17 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -90,7 +90,7 @@ def embed(self) -> Embed: embed = Embed(color=self.bot.main_color, description=self.description) embed.set_author( name=f"v{self.version} - Changelog", - icon_url=self.bot.user.display_avatar.url, + icon_url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None, url=self.url, ) @@ -98,7 +98,7 @@ def embed(self) -> Embed: embed.add_field(name=name, value=truncate(value, 1024), inline=False) embed.set_footer(text=f"Current version: v{self.bot.version}") - embed.set_thumbnail(url=self.bot.user.display_avatar.url) + embed.set_thumbnail(url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None) return embed diff --git a/core/clients.py b/core/clients.py index 61c39fdd4b..459ee2ea6b 100644 --- a/core/clients.py +++ b/core/clients.py @@ -592,14 +592,14 @@ async def create_log_entry(self, recipient: Member, channel: TextChannel, creato "id": str(recipient.id), "name": recipient.name, "discriminator": recipient.discriminator, - "avatar_url": recipient.display_avatar.url, + "avatar_url": recipient.display_avatar.url if recipient.display_avatar else None, "mod": False, }, "creator": { "id": str(creator.id), "name": creator.name, "discriminator": creator.discriminator, - "avatar_url": creator.display_avatar.url, + "avatar_url": creator.display_avatar.url if creator.display_avatar else None, "mod": isinstance(creator, Member), }, "closer": None, @@ -661,7 +661,7 @@ async def append_log( "id": str(message.author.id), "name": message.author.name, "discriminator": message.author.discriminator, - "avatar_url": message.author.display_avatar.url, + "avatar_url": message.author.display_avatar.url if message.author.display_avatar else None, "mod": not isinstance(message.channel, DMChannel), }, "content": message.content, @@ -711,7 +711,9 @@ async def create_note(self, recipient: Member, message: Message, message_id: Uni "id": str(message.author.id), "name": message.author.name, "discriminator": message.author.discriminator, - "avatar_url": message.author.display_avatar.url, + "avatar_url": ( + message.author.display_avatar.url if message.author.display_avatar else None + ), }, "message": message.content, "message_id": str(message_id), diff --git a/core/config.py b/core/config.py index 5c6b0dd09d..a704443bb1 100644 --- a/core/config.py +++ b/core/config.py @@ -129,6 +129,17 @@ class ConfigManager: # regex "use_regex_autotrigger": False, "use_hoisted_top_role": True, + # Minimum characters for thread creation + "thread_min_characters": 0, + "thread_min_characters_title": "Message too short", + "thread_min_characters_response": "Your message is too short to create a thread. Please provide more details.", + "thread_min_characters_footer": "Minimum {min_characters} characters required.", + # --- SNOOZE FEATURE CONFIG --- + "max_snooze_time": 604800, # in seconds, default 7 days + "snooze_title": "Thread Snoozed", + "snooze_text": "This thread has been snoozed. The channel will be restored when the user replies or a moderator unsnoozes it.", + "unsnooze_text": "This thread has been unsnoozed and restored.", + "unsnooze_notify_channel": "thread", # Can be a channel ID or 'thread' for the thread's own channel } private_keys = { diff --git a/core/config_help.json b/core/config_help.json index d301763fe4..462e4e1c03 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -1222,5 +1222,105 @@ "If this configuration is enabled, only roles that are hoisted (displayed seperately in member list) will be used. If a user has no hoisted roles, it will return 'None'.", "If you would like to display the top role of a user regardless of if it's hoisted or not, disable `use_hoisted_top_role`." ] + }, + "thread_min_characters": { + "default": "0", + "description": "The minimum number of characters required in the initial message to create a thread. Set to 0 to disable.", + "examples": [ + "`{prefix}config set thread_min_characters 20`" + ], + "notes": [ + "If a user tries to create a thread with a message shorter than this, an error will be shown.", + "See also: `thread_min_characters_title`, `thread_min_characters_response`, `thread_min_characters_footer`." + ] + }, + "thread_min_characters_title": { + "default": "Message too short", + "description": "The title of the error embed when a user tries to create a thread with too few characters.", + "examples": [ + "`{prefix}config set thread_min_characters_title Too short!`" + ], + "notes": [ + "See also: `thread_min_characters`, `thread_min_characters_response`, `thread_min_characters_footer`." + ] + }, + "thread_min_characters_response": { + "default": "Your message is too short to create a thread. Please provide more details.", + "description": "The description of the error embed when a user tries to create a thread with too few characters.", + "examples": [ + "`{prefix}config set thread_min_characters_response Please write a longer message.`" + ], + "notes": [ + "You can use `{min_characters}` as a placeholder for the minimum required characters.", + "See also: `thread_min_characters`, `thread_min_characters_title`, `thread_min_characters_footer`." + ] + }, + "thread_min_characters_footer": { + "default": "Minimum {min_characters} characters required.", + "description": "The footer of the error embed when a user tries to create a thread with too few characters.", + "examples": [ + "`{prefix}config set thread_min_characters_footer At least {min_characters} characters needed.`" + ], + "notes": [ + "You can use `{min_characters}` as a placeholder for the minimum required characters.", + "See also: `thread_min_characters`, `thread_min_characters_title`, `thread_min_characters_response`." + ] + }, + "max_snooze_time": { + "default": "604800 (7 days in seconds)", + "description": "The maximum duration in seconds that a thread can be snoozed. When a thread is snoozed, it is temporarily hidden until the user replies or a moderator unsnoozes it.", + "examples": [ + "`{prefix}config set max_snooze_time 86400` (1 day)", + "`{prefix}config set max_snooze_time 1209600` (14 days)" + ], + "notes": [ + "The value must be specified in seconds.", + "See also: `snooze_title`, `snooze_text`, `unsnooze_text`, `unsnooze_notify_channel`." + ] + }, + "snooze_title": { + "default": "\"Thread Snoozed\"", + "description": "This is the message embed title sent when a thread is snoozed.", + "examples": [ + "`{prefix}config set snooze_title Thread Paused`" + ], + "notes": [ + "See also: `snooze_text`, `unsnooze_title`, `max_snooze_time`." + ] + }, + "snooze_text": { + "default": "\"This thread has been snoozed. The channel will be restored when the user replies or a moderator unsnoozes it.\"", + "description": "This is the message embed content sent when a thread is snoozed.", + "examples": [ + "`{prefix}config set snooze_text This conversation is on hold temporarily.`" + ], + "notes": [ + "Discord flavoured markdown is fully supported in `snooze_text`.", + "See also: `snooze_title`, `unsnooze_text`, `max_snooze_time`." + ] + }, + "unsnooze_text": { + "default": "\"This thread has been unsnoozed and restored.\"", + "description": "This is the message content sent when a thread is unsnoozed and restored.", + "examples": [ + "`{prefix}config set unsnooze_text Thread has been reactivated.`" + ], + "notes": [ + "Discord flavoured markdown is fully supported in `unsnooze_text`.", + "See also: `snooze_text`, `unsnooze_notify_channel`, `max_snooze_time`." + ] + }, + "unsnooze_notify_channel": { + "default": "\"thread\"", + "description": "This is the channel where the unsnooze notification will be sent. Set to \"thread\" to send in the thread's own channel, or provide a specific channel ID.", + "examples": [ + "`{prefix}config set unsnooze_notify_channel thread`", + "`{prefix}config set unsnooze_notify_channel 9234932582312` (9234932582312 is the channel ID)" + ], + "notes": [ + "If set to \"thread\", the notification will be sent in the thread channel itself.", + "If set to a channel ID, the notification will be sent to that specific channel.", + "See also: `unsnooze_text`, `max_snooze_time`." + ] } -} +} \ No newline at end of file diff --git a/core/paginator.py b/core/paginator.py index 5a6844f382..48222d283e 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -149,16 +149,27 @@ def last_page(self): """Returns the index of the last page""" return len(self.pages) - 1 - async def run(self) -> typing.Optional[Message]: + async def run(self) -> None: """ Starts the pagination session. """ if not self.running: await self.show_page(self.current) - if self.view is not None: - await self.view.wait() + # Don't block command execution while waiting for the View timeout. + # Schedule the wait-and-close sequence in the background so the command + # returns immediately (prevents typing indicator from hanging). + if self.view is not None: + + async def _wait_and_close(): + try: + await self.view.wait() + finally: + await self.close(delete=False) + # Fire and forget + self.ctx.bot.loop.create_task(_wait_and_close()) + else: await self.close(delete=False) async def close( @@ -223,8 +234,7 @@ def __init__(self, handler: PaginatorSession, *args, **kwargs): self.clear_items() # clear first so we can control the order self.fill_items() - @discord.ui.button(label="Stop", style=ButtonStyle.danger) - async def stop_button(self, interaction: Interaction, button: Button): + async def stop_callback(self, interaction: Interaction): await self.handler.close(interaction=interaction) def fill_items(self): @@ -244,7 +254,10 @@ def fill_items(self): self.handler._buttons_map[label] = button self.add_item(button) - self.add_item(self.stop_button) + + stop_button = Button(label="Stop", style=ButtonStyle.danger) + stop_button.callback = self.stop_callback + self.add_item(stop_button) async def interaction_check(self, interaction: Interaction): """Only allow the message author to interact""" @@ -314,7 +327,7 @@ def __init__(self, ctx: commands.Context, *embeds, **options): footer_text = footer_text + " • " + embed.footer.text if embed.footer.icon: - icon_url = embed.footer.icon.url + icon_url = embed.footer.icon.url if embed.footer.icon else None else: icon_url = None embed.set_footer(text=footer_text, icon_url=icon_url) @@ -375,7 +388,7 @@ def _set_footer(self): footer_text = footer_text + " • " + self.footer_text if self.embed.footer.icon: - icon_url = self.embed.footer.icon.url + icon_url = self.embed.footer.icon.url if self.embed.footer.icon else None else: icon_url = None diff --git a/core/thread.py b/core/thread.py index 00060ab7f5..d380552694 100644 --- a/core/thread.py +++ b/core/thread.py @@ -8,7 +8,7 @@ import traceback import typing import warnings -from datetime import timedelta +from datetime import timedelta, datetime, timezone from types import SimpleNamespace import isodate @@ -33,6 +33,7 @@ DenyButton, ConfirmThreadCreationView, DummyParam, + extract_forwarded_content, ) logger = getLogger(__name__) @@ -66,6 +67,10 @@ def __init__( self.close_task = None self.auto_close_task = None self._cancelled = False + # --- SNOOZE STATE --- + self.snoozed = False # True if thread is snoozed + self.snooze_data = None # Dict with channel/category/position/messages for restoration + self.log_key = None # Ensure log_key always exists def __repr__(self): return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipients={len(self._other_recipients)})' @@ -126,6 +131,202 @@ def cancelled(self, flag: bool): for i in self.wait_tasks: i.cancel() + async def snooze(self, moderator=None, command_used=None, snooze_for=None): + """ + Save channel/category/position/messages to DB, mark as snoozed, delete channel. + """ + if self.snoozed: + return False # Already snoozed + channel = self.channel + if not isinstance(channel, discord.TextChannel): + return False + # Ensure self.log_key is set before snoozing + if not self.log_key: + # Try to fetch from DB using channel_id + log_entry = await self.bot.api.get_log(self.channel.id) + if log_entry and "key" in log_entry: + self.log_key = log_entry["key"] + # Fallback: try by recipient id + elif hasattr(self, "id"): + log_entry = await self.bot.api.get_log(str(self.id)) + if log_entry and "key" in log_entry: + self.log_key = log_entry["key"] + + now = datetime.now(timezone.utc) + self.snooze_data = { + "category_id": channel.category_id, + "position": channel.position, + "name": channel.name, + "topic": channel.topic, + "slowmode_delay": channel.slowmode_delay, + "nsfw": channel.nsfw, + "overwrites": [(role.id, perm._values) for role, perm in channel.overwrites.items()], + "messages": [ + { + "author_id": m.author.id, + "content": m.content, + "attachments": [a.url for a in m.attachments], + "embeds": [e.to_dict() for e in m.embeds], + "created_at": m.created_at.isoformat(), + "type": ( + "mod_only" + if ( + m.embeds + and getattr(m.embeds[0], "author", None) + and ( + getattr(m.embeds[0].author, "name", "").startswith("📝 Note") + or getattr(m.embeds[0].author, "name", "").startswith("📝 Persistent Note") + ) + ) + else None + ), + "author_name": getattr(m.author, "name", None), + } + async for m in channel.history(limit=None, oldest_first=True) + if not ( + m.embeds + and getattr(m.embeds[0], "author", None) + and ( + getattr(m.embeds[0].author, "name", "").startswith("📝 Note") + or getattr(m.embeds[0].author, "name", "").startswith("📝 Persistent Note") + ) + ) + and getattr(m, "type", None) not in ("internal", "note") + ], + "snoozed_by": getattr(moderator, "name", None) if moderator else None, + "snooze_command": command_used, + "log_key": self.log_key, + "snooze_start": now.isoformat(), + "snooze_for": snooze_for, + } + self.snoozed = True + # Save to DB (robust: try recipient.id, then channel_id) + result = await self.bot.api.logs.update_one( + {"recipient.id": str(self.id)}, + {"$set": {"snoozed": True, "snooze_data": self.snooze_data}}, + ) + if result.modified_count == 0 and self.channel: + result = await self.bot.api.logs.update_one( + {"channel_id": str(self.channel.id)}, + {"$set": {"snoozed": True, "snooze_data": self.snooze_data}}, + ) + import logging + + logging.info(f"[SNOOZE] DB update result: {result.modified_count}") + # Delete channel + await channel.delete(reason="Thread snoozed by moderator") + self._channel = None + return True + + async def restore_from_snooze(self): + """ + Recreate channel in original category/position, replay messages, mark as not snoozed. + """ + if not self.snooze_data or not isinstance(self.snooze_data, dict): + import logging + + logging.warning( + f"[UNSNOOZE] Tried to restore thread {self.id} but snooze_data is None or not a dict." + ) + return False + # Now safe to access self.snooze_data + snoozed_by = self.snooze_data.get("snoozed_by") + snooze_command = self.snooze_data.get("snooze_command") + guild = self.bot.modmail_guild + category = guild.get_channel(self.snooze_data["category_id"]) + overwrites = {} + for role_id, perm_values in self.snooze_data["overwrites"]: + role = guild.get_role(role_id) or guild.get_member(role_id) + if role: + overwrites[role] = discord.PermissionOverwrite(**perm_values) + channel = await guild.create_text_channel( + name=self.snooze_data["name"], + category=category, + topic=self.snooze_data["topic"], + slowmode_delay=self.snooze_data["slowmode_delay"], + overwrites=overwrites, + nsfw=self.snooze_data["nsfw"], + position=self.snooze_data["position"], + reason="Thread unsnoozed/restored", + ) + self._channel = channel + # Strictly restore the log_key from snooze_data (never create a new one) + self.log_key = self.snooze_data.get("log_key") + # Replay messages + for msg in self.snooze_data["messages"]: + author = self.bot.get_user(msg["author_id"]) or await self.bot.get_or_fetch_user(msg["author_id"]) + content = msg["content"] + embeds = [discord.Embed.from_dict(e) for e in msg.get("embeds", []) if e] + attachments = msg.get("attachments", []) + msg_type = msg.get("type") + # Only send if there is content, embeds, or attachments + if not content and not embeds and not attachments: + continue # Skip empty messages + author_is_mod = msg["author_id"] not in [r.id for r in self.recipients] + if author_is_mod: + username = msg.get("author_name") or (getattr(author, "name", None)) or "Unknown" + user_id = msg.get("author_id") + if embeds: + embeds[0].set_author( + name=f"{username} ({user_id})", + icon_url=( + author.display_avatar.url + if author and hasattr(author, "display_avatar") + else None + ), + ) + await channel.send(embeds=embeds) + else: + formatted = ( + f"**{username} ({user_id})**: {content}" if content else f"**{username} ({user_id})**" + ) + await channel.send(formatted) + else: + await channel.send(content=content or None, embeds=embeds or None) + self.snoozed = False + # Store snooze_data for notification before clearing + snooze_data_for_notify = self.snooze_data + self.snooze_data = None + # Update channel_id in DB and clear snooze_data (robust: try log_key first) + if self.log_key: + result = await self.bot.api.logs.update_one( + {"key": self.log_key}, + {"$set": {"channel_id": str(channel.id)}, "$unset": {"snoozed": "", "snooze_data": ""}}, + ) + else: + result = await self.bot.api.logs.update_one( + {"recipient.id": str(self.id)}, + {"$set": {"channel_id": str(channel.id)}, "$unset": {"snoozed": "", "snooze_data": ""}}, + ) + if result.modified_count == 0: + result = await self.bot.api.logs.update_one( + {"channel_id": str(channel.id)}, + { + "$set": {"channel_id": str(channel.id)}, + "$unset": {"snoozed": "", "snooze_data": ""}, + }, + ) + import logging + + logging.info(f"[UNSNOOZE] DB update result: {result.modified_count}") + # Notify in the configured channel + notify_channel = self.bot.config.get("unsnooze_notify_channel") or "thread" + notify_text = self.bot.config.get("unsnooze_text") or "This thread has been unsnoozed and restored." + if notify_channel == "thread": + await channel.send(notify_text) + else: + ch = self.bot.get_channel(int(notify_channel)) + if ch: + await ch.send(f"Thread for user <@{self.id}> has been unsnoozed and restored.") + # Show who ran the snooze command and the command used + # Use snooze_data_for_notify to avoid accessing self.snooze_data after it is set to None + snoozed_by = snooze_data_for_notify.get("snoozed_by") if snooze_data_for_notify else None + snooze_command = snooze_data_for_notify.get("snooze_command") if snooze_data_for_notify else None + if snoozed_by or snooze_command: + info = f"Snoozed by: {snoozed_by or 'Unknown'} | Command: {snooze_command or '?snooze'}" + await channel.send(info) + return True + @classmethod async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChannel) -> "Thread": # there is a chance it grabs from another recipient's main thread @@ -415,6 +616,8 @@ async def close( await self._close(closer, silent, delete_channel, message) async def _close(self, closer, silent=False, delete_channel=True, message=None, scheduled=False): + if self.channel: + self.manager.closing.add(self.channel.id) try: self.manager.cache.pop(self.id) except KeyError as e: @@ -541,10 +744,15 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, if user is not None: tasks.append(user.send(embed=embed)) - if delete_channel: + if delete_channel and self.channel: tasks.append(self.channel.delete()) - await asyncio.gather(*tasks) + try: + await asyncio.gather(*tasks) + finally: + if self.channel: + self.manager.closing.discard(self.channel.id) + self.bot.dispatch("thread_close", self, closer, silent, delete_channel, message, scheduled) async def cancel_closure(self, auto_close: bool = False, all: bool = False) -> None: @@ -620,10 +828,7 @@ async def find_linked_messages( ): raise ValueError("Thread message not found.") - if message1.embeds[0].color.value == self.bot.main_color and ( - message1.embeds[0].author.name.startswith("Note") - or message1.embeds[0].author.name.startswith("Persistent Note") - ): + if message1.embeds[0].footer and "Internal Message" in message1.embeds[0].footer.text: if not note: raise ValueError("Thread message not found.") return message1, None @@ -686,7 +891,7 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> embed1.description = message tasks = [self.bot.api.edit_message(message1.id, message), message1.edit(embed=embed1)] - if message1.embeds[0].author.name.startswith("Persistent Note"): + if message1.embeds[0].footer and "Persistent Internal Message" in message1.embeds[0].footer.text: tasks += [self.bot.api.edit_note(message1.id, message)] else: for m2 in message2: @@ -713,7 +918,7 @@ async def delete_message( if m2 is not None: tasks += [m2.delete()] - if message1.embeds[0].author.name.startswith("Persistent Note"): + if message1.embeds[0].footer and "Persistent Internal Message" in message1.embeds[0].footer.text: tasks += [self.bot.api.delete_note(message1.id)] if tasks: @@ -811,8 +1016,9 @@ async def note( thread_creation=thread_creation, ) + # Log as 'note' type for logviewer self.bot.loop.create_task( - self.bot.api.append_log(message, message_id=msg.id, channel_id=self.channel.id, type_="system") + self.bot.api.append_log(message, message_id=msg.id, channel_id=self.channel.id, type_="note") ) return msg @@ -920,6 +1126,38 @@ async def send( persistent_note: bool = False, thread_creation: bool = False, ) -> None: + # Handle notes with Discord-like system message format - return early + if note: + destination = destination or self.channel + content = message.content or "[No content]" + + # Create embed for note with Discord system message style + embed = discord.Embed( + description=content, color=0x5865F2 # Discord blurple color for system messages + ) + + # Set author with note icon and username + if persistent_note: + note_type = "Persistent Note" + else: + note_type = "Note" + + embed.set_author( + name=f"📝 {note_type} ({message.author.name})", icon_url=message.author.display_avatar.url + ) + + # Add timestamp if enabled + if self.bot.config["show_timestamp"]: + embed.timestamp = message.created_at + + # Add a subtle footer to distinguish from replies + if persistent_note: + embed.set_footer(text="Persistent Internal Note") + else: + embed.set_footer(text="Internal Note") + + return await destination.send(embed=embed) + if not note and from_mod: self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close @@ -943,6 +1181,15 @@ async def send( destination = destination or self.channel + if destination is None: + logger.error("Attempted to send a message to a thread with no channel (destination is None).") + return + try: + await destination.typing() + except discord.NotFound: + logger.warning("Channel not found when trying to send message.") + return + author = message.author member = self.bot.guild.get_member(author.id) if member: @@ -950,10 +1197,57 @@ async def send( else: avatar_url = author.display_avatar.url - embed = discord.Embed(description=message.content) + # Handle forwarded messages first + forwarded_jump_url = None + if hasattr(message, "message_snapshots") and len(message.message_snapshots) > 0: + snap = message.message_snapshots[0] + # Only show "No content" if there's truly no content (no text, attachments, embeds, or stickers) + if not snap.content and not message.attachments and not message.embeds and not message.stickers: + content = "No content" + else: + content = snap.content or "" + + # Get jump_url from cached_message, fetch if not cached + if hasattr(snap, "cached_message") and snap.cached_message is not None: + forwarded_jump_url = snap.cached_message.jump_url + else: + if ( + hasattr(message, "reference") + and message.reference + and message.reference.type == discord.MessageReferenceType.forward + ): + try: + original_msg_channel = self.bot.get_channel(message.reference.channel_id) + original_msg = await original_msg_channel.fetch_message(message.reference.message_id) + forwarded_jump_url = original_msg.jump_url + except (discord.NotFound, discord.Forbidden, AttributeError): + pass + + content = f"📨 **Forwarded message:**\n{content}" if content else "📨 **Forwarded message:**" + else: + # Only show "No content" if there's truly no content (no text, attachments, embeds, or stickers) + if ( + not message.content + and not message.attachments + and not message.embeds + and not message.stickers + ): + content = "No content" + else: + content = message.content or "" + + # Only set description if there's actual content to show + if content: + embed = discord.Embed(description=content) + else: + embed = discord.Embed() if self.bot.config["show_timestamp"]: embed.timestamp = message.created_at + # Add forwarded message context + if forwarded_jump_url: + embed.add_field(name="Context", value=f"- {forwarded_jump_url}", inline=True) + system_avatar_url = "https://discordapp.com/assets/f78426a064bc9dd24847519259bc42af.png" if not note: @@ -983,12 +1277,18 @@ async def send( url=f"https://discordapp.com/users/{author.id}#{message.id}", ) else: - # Special note messages + # Notes use system message style with note icon + if persistent_note: + note_type = "Persistent Note" + else: + note_type = "Note" + embed.set_author( - name=f"{'Persistent' if persistent_note else ''} Note ({author.name})", - icon_url=system_avatar_url, + name=f"📝 {note_type} ({str(author)})", + icon_url=avatar_url, url=f"https://discordapp.com/users/{author.id}#{message.id}", ) + embed.color = 0x5865F2 # Discord blurple for system messages ext = [(a.url, a.filename, False) for a in message.attachments] @@ -1001,7 +1301,7 @@ async def send( attachments.append(attachment) image_urls = re.findall( - r"http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$\-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", + r"http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message.content, ) @@ -1113,22 +1413,33 @@ def lottie_to_png(data): file_upload_count += 1 if from_mod: - embed.colour = self.bot.mod_color - # Anonymous reply sent in thread channel - if anonymous and isinstance(destination, discord.TextChannel): - embed.set_footer(text="Anonymous Reply") - # Normal messages - elif not anonymous: - mod_tag = self.bot.config["mod_tag"] - if mod_tag is None: - mod_tag = str(get_top_role(message.author, self.bot.config["use_hoisted_top_role"])) - embed.set_footer(text=mod_tag) # Normal messages + if note: + # Notes use Discord blurple and special footer + embed.colour = 0x5865F2 + if persistent_note: + embed.set_footer(text="Persistent Internal Note") + else: + embed.set_footer(text="Internal Note") else: - embed.set_footer(text=self.bot.config["anon_tag"]) - elif note: - embed.colour = self.bot.main_color + # Regular mod messages + embed.colour = self.bot.mod_color + # Anonymous reply sent in thread channel + if anonymous and isinstance(destination, discord.TextChannel): + embed.set_footer(text="Anonymous Reply") + # Normal messages + elif not anonymous: + mod_tag = self.bot.config["mod_tag"] + if mod_tag is None: + mod_tag = str(get_top_role(message.author, self.bot.config["use_hoisted_top_role"])) + embed.set_footer(text=mod_tag) # Normal messages + else: + embed.set_footer(text=self.bot.config["anon_tag"]) else: - embed.set_footer(text=f"Message ID: {message.id}") + # Add forwarded message indicator in footer for mods + footer_text = f"Message ID: {message.id}" + if hasattr(message, "message_snapshots") and len(message.message_snapshots) > 0: + footer_text += " • Forwarded" + embed.set_footer(text=footer_text) embed.colour = self.bot.recipient_color if (from_mod or note) and not thread_creation: @@ -1146,11 +1457,14 @@ def lottie_to_png(data): ): logger.info("Sending a message to %s when DM disabled is set.", self.recipient) + # Best-effort typing: never block message delivery if typing fails try: await destination.typing() except discord.NotFound: logger.warning("Channel not found.") raise + except (discord.Forbidden, discord.HTTPException, Exception) as e: + logger.warning("Unable to send typing to %s: %s. Continuing without typing.", destination, e) if not from_mod and not note: mentions = await self.get_notifications() @@ -1278,6 +1592,7 @@ class ThreadManager: def __init__(self, bot): self.bot = bot self.cache = {} + self.closing = set() async def populate_cache(self) -> None: for channel in self.bot.modmail_guild.text_channels: @@ -1301,6 +1616,8 @@ async def find( ) -> typing.Optional[Thread]: """Finds a thread from cache or from discord channel topics.""" if recipient is None and channel is not None and isinstance(channel, discord.TextChannel): + if channel.id in self.closing: + return None thread = await self._find_from_channel(channel) if thread is None: user_id, thread = next( @@ -1322,11 +1639,8 @@ async def find( logger.warning("Thread for %s cancelled.", recipient) return thread else: - if not thread.cancelled and ( - not thread.channel or not self.bot.get_channel(thread.channel.id) - ): - logger.warning("Found existing thread for %s but the channel is invalid.", recipient_id) - await thread.close(closer=self.bot.user, silent=True, delete_channel=False) + # If the thread is snoozed (channel is None), return it for restoration + if thread.cancelled: thread = None else: @@ -1406,6 +1720,33 @@ async def create( ) -> Thread: """Creates a Modmail thread""" + # Minimum character check + min_chars = self.bot.config.get("thread_min_characters") + if min_chars is None: + min_chars = 0 + try: + min_chars = int(min_chars) + except ValueError: + min_chars = 0 + if min_chars > 0 and message is not None and message.content is not None: + if len(message.content.strip()) < min_chars: + embed = discord.Embed( + title=self.bot.config["thread_min_characters_title"], + description=self.bot.config["thread_min_characters_response"].replace( + "{min_characters}", str(min_chars) + ), + color=self.bot.error_color, + ) + embed.set_footer( + text=self.bot.config["thread_min_characters_footer"].replace( + "{min_characters}", str(min_chars) + ) + ) + await message.channel.send(embed=embed) + thread = Thread(self, recipient) + thread.cancelled = True + return thread + # checks for existing thread in cache thread = self.cache.get(recipient.id) if thread: @@ -1433,8 +1774,10 @@ async def create( else: destination = message.channel view = ConfirmThreadCreationView() - view.add_item(AcceptButton(self.bot.config["confirm_thread_creation_accept"])) - view.add_item(DenyButton(self.bot.config["confirm_thread_creation_deny"])) + view.add_item( + AcceptButton("accept-thread-creation", self.bot.config["confirm_thread_creation_accept"]) + ) + view.add_item(DenyButton("deny-thread-creation", self.bot.config["confirm_thread_creation_deny"])) confirm = await destination.send( embed=discord.Embed( title=self.bot.config["confirm_thread_creation_title"], diff --git a/core/time.py b/core/time.py index c56c7264e2..b6ce91f419 100644 --- a/core/time.py +++ b/core/time.py @@ -3,6 +3,7 @@ Source: https://github.com/Rapptz/RoboDanny/blob/rewrite/cogs/utils/time.py """ + from __future__ import annotations import datetime @@ -159,6 +160,30 @@ def __init__(self, dt: datetime.datetime, now: datetime.datetime = None): async def ensure_constraints( self, ctx: Context, uft: UserFriendlyTime, now: datetime.datetime, remaining: str ) -> None: + # Strip stray connector words like "in", "to", or "at" that may + # remain when the natural language parser isolates the time token + # positioned at the end (e.g. "in 10m" leaves "in" before the token). + if isinstance(remaining, str): + cleaned = remaining.strip(" ,.!") + stray_tokens = { + "in", + "to", + "at", + "me", + # also treat vague times of day as stray tokens when they are the only leftover word + "evening", + "night", + "midnight", + "morning", + "afternoon", + "tonight", + "noon", + "today", + "tomorrow", + } + if cleaned.lower() in stray_tokens: + remaining = "" + if self.dt < now: raise commands.BadArgument("This time is in the past.") @@ -198,6 +223,26 @@ async def convert(self, ctx: Context, argument: str, *, now=None) -> FriendlyTim if now is None: now = ctx.message.created_at + # Heuristic: If the user provides only certain single words that are commonly + # used as salutations or vague times of day, interpret them as a message + # rather than a schedule. This avoids accidental scheduling when the intent + # is a short message (e.g. '?close evening'). Explicit scheduling still works + # via 'in 2h', '2m30s', 'at 8pm', etc. + if argument.strip().lower() in { + "evening", + "night", + "midnight", + "morning", + "afternoon", + "tonight", + "noon", + "today", + "tomorrow", + }: + result = FriendlyTimeResult(now) + await result.ensure_constraints(ctx, self, now, argument) + return result + match = regex.match(argument) if match is not None and match.group(0): data = {k: int(v) for k, v in match.groupdict(default=0).items()} @@ -244,7 +289,10 @@ async def convert(self, ctx: Context, argument: str, *, now=None) -> FriendlyTim if not status.hasDateOrTime: raise commands.BadArgument('Invalid time provided, try e.g. "tomorrow" or "3 days".') - if begin not in (0, 1) and end != len(argument): + # If the parsed time token is embedded in the text but only followed by + # trailing punctuation/whitespace, treat it as if it's positioned at the end. + trailing = argument[end:].strip(" ,.!") + if begin not in (0, 1) and trailing != "": raise commands.BadArgument( "Time is either in an inappropriate location, which " "must be either at the end or beginning of your input, " @@ -259,6 +307,20 @@ async def convert(self, ctx: Context, argument: str, *, now=None) -> FriendlyTim if status.accuracy == pdt.pdtContext.ACU_HALFDAY: dt = dt.replace(day=now.day + 1) + # Heuristic: If the matched time string is a vague time-of-day (e.g., + # 'evening', 'morning', 'afternoon', 'night') and there's additional + # non-punctuation text besides that token, assume the user intended a + # closing message rather than scheduling. This avoids cases like + # '?close Have a good evening!' being treated as a scheduled close. + vague_tod = {"evening", "morning", "afternoon", "night"} + matched_text = dt_string.strip().strip('"').rstrip(" ,.!").lower() + pre_text = argument[:begin].strip(" ,.!") + post_text = argument[end:].strip(" ,.!") + if matched_text in vague_tod and (pre_text or post_text): + result = FriendlyTimeResult(now) + await result.ensure_constraints(ctx, self, now, argument) + return result + result = FriendlyTimeResult(dt.replace(tzinfo=datetime.timezone.utc), now) remaining = "" diff --git a/core/utils.py b/core/utils.py index 9f9f572f5a..19ff4cd37b 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,10 +1,10 @@ import base64 import functools +import contextlib import re import typing from datetime import datetime, timezone from difflib import get_close_matches -from distutils.util import strtobool as _stb # pylint: disable=import-error from itertools import takewhile, zip_longest from urllib import parse @@ -34,15 +34,18 @@ "normalize_alias", "format_description", "trigger_typing", + "safe_typing", "escape_code_block", "tryint", "get_top_role", "get_joint_id", "extract_block_timestamp", + "return_or_truncate", "AcceptButton", "DenyButton", "ConfirmThreadCreationView", "DummyParam", + "extract_forwarded_content", ] @@ -52,15 +55,12 @@ def strtobool(val): if isinstance(val, bool): return val - try: - return _stb(str(val)) - except ValueError: - val = val.lower() - if val == "enable": - return 1 - if val == "disable": - return 0 - raise + val = str(val).lower() + if val in ("y", "yes", "on", "1", "true", "t", "enable"): + return 1 + if val in ("n", "no", "off", "0", "false", "f", "disable"): + return 0 + raise ValueError(f"invalid truth value {val}") class User(commands.MemberConverter): @@ -391,7 +391,7 @@ def decode_alias(m): iterate = [alias] for a in iterate: - a = re.sub("\x1AU(.+?)\x1AU", decode_alias, a) + a = re.sub(r"\x1AU(.+?)\x1AU", decode_alias, a) if a[0] == a[-1] == '"': a = a[1:-1] aliases.append(a) @@ -423,11 +423,42 @@ def format_description(i, names): ) +class _SafeTyping: + """Best-effort typing context manager. + + Suppresses errors from Discord's typing endpoint so core flows continue + when typing is disabled or experiencing outages. + """ + + def __init__(self, target): + # target can be a Context or any Messageable (channel/DM/user) + self._target = target + self._cm = None + + async def __aenter__(self): + try: + self._cm = self._target.typing() + return await self._cm.__aenter__() + except Exception: + # typing is best-effort; ignore any failure + self._cm = None + + async def __aexit__(self, exc_type, exc, tb): + if self._cm is not None: + with contextlib.suppress(Exception): + return await self._cm.__aexit__(exc_type, exc, tb) + + +def safe_typing(target): + return _SafeTyping(target) + + def trigger_typing(func): @functools.wraps(func) async def wrapper(self, ctx: commands.Context, *args, **kwargs): - await ctx.typing() - return await func(self, ctx, *args, **kwargs) + # Keep typing active for the duration of the command; suppress failures + async with safe_typing(ctx): + return await func(self, ctx, *args, **kwargs) return wrapper @@ -573,9 +604,15 @@ def extract_block_timestamp(reason, id_): return end_time, after +def return_or_truncate(text, max_length): + if len(text) <= max_length: + return text + return text[: max_length - 3] + "..." + + class AcceptButton(discord.ui.Button): - def __init__(self, emoji): - super().__init__(style=discord.ButtonStyle.gray, emoji=emoji) + def __init__(self, custom_id: str, emoji: str): + super().__init__(style=discord.ButtonStyle.gray, emoji=emoji, custom_id=custom_id) async def callback(self, interaction: discord.Interaction): self.view.value = True @@ -584,8 +621,8 @@ async def callback(self, interaction: discord.Interaction): class DenyButton(discord.ui.Button): - def __init__(self, emoji): - super().__init__(style=discord.ButtonStyle.gray, emoji=emoji) + def __init__(self, custom_id: str, emoji: str): + super().__init__(style=discord.ButtonStyle.gray, emoji=emoji, custom_id=custom_id) async def callback(self, interaction: discord.Interaction): self.view.value = False @@ -599,6 +636,100 @@ def __init__(self): self.value = None +def extract_forwarded_content(message) -> typing.Optional[str]: + """ + Extract forwarded message content from Discord forwarded messages. + + Parameters + ---------- + message : discord.Message + The message to extract forwarded content from. + + Returns + ------- + Optional[str] + The extracted forwarded content, or None if not a forwarded message. + """ + import discord + + try: + # Handle multi-forward (message_snapshots) + if hasattr(message, "flags") and getattr(message.flags, "has_snapshot", False): + if hasattr(message, "message_snapshots") and message.message_snapshots: + forwarded_parts = [] + for snap in message.message_snapshots: + author = getattr(snap, "author", None) + author_name = getattr(author, "name", "Unknown") if author else "Unknown" + snap_content = getattr(snap, "content", "") + + if snap_content: + # Truncate very long messages to prevent spam + if len(snap_content) > 500: + snap_content = snap_content[:497] + "..." + forwarded_parts.append(f"**{author_name}:** {snap_content}") + elif getattr(snap, "embeds", None): + for embed in snap.embeds: + if hasattr(embed, "description") and embed.description: + embed_desc = embed.description + if len(embed_desc) > 300: + embed_desc = embed_desc[:297] + "..." + forwarded_parts.append(f"**{author_name}:** {embed_desc}") + break + elif getattr(snap, "attachments", None): + attachment_info = ", ".join( + [getattr(a, "filename", "Unknown") for a in snap.attachments[:3]] + ) + if len(snap.attachments) > 3: + attachment_info += f" (+{len(snap.attachments) - 3} more)" + forwarded_parts.append(f"**{author_name}:** [Attachments: {attachment_info}]") + else: + forwarded_parts.append(f"**{author_name}:** [No content]") + + if forwarded_parts: + return "\n".join(forwarded_parts) + + # Handle single-message forward + elif getattr(message, "type", None) == getattr(discord.MessageType, "forward", None): + ref = getattr(message, "reference", None) + if ( + ref + and hasattr(discord, "MessageReferenceType") + and getattr(ref, "type", None) == getattr(discord.MessageReferenceType, "forward", None) + ): + try: + ref_msg = getattr(ref, "resolved", None) + if ref_msg: + ref_author = getattr(ref_msg, "author", None) + ref_author_name = getattr(ref_author, "name", "Unknown") if ref_author else "Unknown" + ref_content = getattr(ref_msg, "content", "") + + if ref_content: + if len(ref_content) > 500: + ref_content = ref_content[:497] + "..." + return f"**{ref_author_name}:** {ref_content}" + elif getattr(ref_msg, "embeds", None): + for embed in ref_msg.embeds: + if hasattr(embed, "description") and embed.description: + embed_desc = embed.description + if len(embed_desc) > 300: + embed_desc = embed_desc[:297] + "..." + return f"**{ref_author_name}:** {embed_desc}" + elif getattr(ref_msg, "attachments", None): + attachment_info = ", ".join( + [getattr(a, "filename", "Unknown") for a in ref_msg.attachments[:3]] + ) + if len(ref_msg.attachments) > 3: + attachment_info += f" (+{len(ref_msg.attachments) - 3} more)" + return f"**{ref_author_name}:** [Attachments: {attachment_info}]" + except Exception: + pass + except Exception: + # Silently handle any unexpected errors + pass + + return None + + class DummyParam: """ A dummy parameter that can be used for MissingRequiredArgument. diff --git a/pyproject.toml b/pyproject.toml index 7e29a4d4ef..0a6d6eaa6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.1.2' +version = '4.2.0' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ diff --git a/requirements.txt b/requirements.txt index 2c7bdb7880..8530e8e0d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,41 +1,43 @@ -i https://pypi.org/simple -aiodns==3.1.1 +aiodns==3.5.0; python_version >= '3.9' aiohttp==3.9.0; python_version >= '3.8' -aiosignal==1.3.1; python_version >= '3.7' -async-timeout==4.0.3; python_version < '3.11' -attrs==23.1.0; python_version >= '3.7' +aiosignal==1.4.0; python_version >= '3.9' +attrs==25.3.0; python_version >= '3.8' +audioop-lts==0.2.2; python_version >= '3.13' brotli==1.1.0 -cairocffi==1.6.1; python_version >= '3.7' -cairosvg==2.7.1; python_version >= '3.5' -certifi==2023.11.17; python_version >= '3.6' -cffi==1.16.0; python_version >= '3.8' -charset-normalizer==3.3.2; python_full_version >= '3.7.0' +cairocffi==1.7.1; python_version >= '3.8' +cairosvg==2.8.2; python_version >= '3.9' +certifi==2025.10.5; python_version >= '3.7' +cffi==2.0.0; python_version >= '3.9' +charset-normalizer==3.4.3; python_version >= '3.7' colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' -cssselect2==0.7.0; python_version >= '3.7' +cssselect2==0.8.0; python_version >= '3.9' defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -discord.py[speed]==2.3.2; python_full_version >= '3.8.0' -dnspython==2.4.2; python_version >= '3.8' and python_version < '4.0' +discord.py[speed]==2.6.3; python_version >= '3.8' +dnspython==2.8.0; python_version >= '3.10' emoji==2.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -frozenlist==1.4.0; python_version >= '3.8' -idna==3.4; python_version >= '3.5' +frozenlist==1.8.0; python_version >= '3.9' +idna==3.10; python_version >= '3.6' isodate==0.6.1 lottie[pdf]==0.7.0; python_version >= '3' motor==3.3.2; python_version >= '3.7' -multidict==6.0.4; python_version >= '3.7' +multidict==6.6.4; python_version >= '3.9' natural==0.2.0 -orjson==3.9.10 +orjson==3.11.3; python_version >= '3.9' packaging==23.2; python_version >= '3.7' parsedatetime==2.6 -pillow==10.1.0; python_version >= '3.8' -pycares==4.4.0; python_version >= '3.8' -pycparser==2.21 -pymongo[srv]==4.6.0; python_version >= '3.7' -python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +pillow==11.3.0; python_version >= '3.9' +propcache==0.4.0; python_version >= '3.9' +pycares==4.11.0; python_version >= '3.9' +pycparser==2.23; python_version >= '3.8' +pymongo[srv]==4.15.2; python_version >= '3.9' +python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' python-dotenv==1.0.0; python_version >= '3.8' requests==2.31.0; python_version >= '3.7' -six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -tinycss2==1.2.1; python_version >= '3.7' -urllib3==2.1.0; python_version >= '3.8' -uvloop==0.19.0; sys_platform != 'win32' +six==1.17.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' +tinycss2==1.4.0; python_version >= '3.8' +urllib3==2.5.0; python_version >= '3.9' +uvloop==0.21.0; sys_platform != 'win32' webencodings==0.5.1 -yarl==1.9.3; python_version >= '3.7' +yarl==1.21.0; python_version >= '3.9' +zstandard==0.25.0; python_version >= '3.9' From c11e32fc6de6e3004a72676e11af15aec216ef32 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Mon, 10 Nov 2025 22:32:08 -0800 Subject: [PATCH 689/705] Update readme version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50f71890ca..f7470c9900 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.1.2-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.2.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> From 151769381340d7999c3750ea4157541e4b615bf5 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 11 Nov 2025 02:46:09 -0800 Subject: [PATCH 690/705] Relock pipfile --- Pipfile.lock | 1888 +++++++++++++++++++++++----------------------- requirements.txt | 24 +- 2 files changed, 959 insertions(+), 953 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index ae2da5ae76..5c4310d52e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -115,196 +115,116 @@ }, "attrs": { "hashes": [ - "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", - "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b" + "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", + "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373" ], - "markers": "python_version >= '3.8'", - "version": "==25.3.0" - }, - "audioop-lts": { - "hashes": [ - "sha256:0337d658f9b81f4cd0fdb1f47635070cc084871a3d4646d9de74fdf4e7c3d24a", - "sha256:03f061a1915538fd96272bac9551841859dbb2e3bf73ebe4a23ef043766f5449", - "sha256:068aa17a38b4e0e7de771c62c60bbca2455924b67a8814f3b0dee92b5820c0b3", - "sha256:088327f00488cdeed296edd9215ca159f3a5a5034741465789cad403fcf4bec0", - "sha256:0d9385e96f9f6da847f4d571ce3cb15b5091140edf3db97276872647ce37efd7", - "sha256:106753a83a25ee4d6f473f2be6b0966fc1c9af7e0017192f5531a3e7463dce58", - "sha256:143fad0311e8209ece30a8dbddab3b65ab419cbe8c0dde6e8828da25999be911", - "sha256:15ab25dd3e620790f40e9ead897f91e79c0d3ce65fe193c8ed6c26cffdd24be7", - "sha256:167d3b62586faef8b6b2275c3218796b12621a60e43f7e9d5845d627b9c9b80e", - "sha256:2b267b70747d82125f1a021506565bdc5609a2b24bcb4773c16d79d2bb260bbd", - "sha256:3bcddaaf6cc5935a300a8387c99f7a7fbbe212a11568ec6cf6e4bc458c048636", - "sha256:3fc38008969796f0f689f1453722a0f463da1b8a6fbee11987830bfbb664f623", - "sha256:47eba38322370347b1c47024defbd36374a211e8dd5b0dcbce7b34fdb6f8847b", - "sha256:48159d96962674eccdca9a3df280e864e8ac75e40a577cc97c5c42667ffabfc5", - "sha256:49ee1a41738a23e98d98b937a0638357a2477bc99e61b0f768a8f654f45d9b7a", - "sha256:4a53aa7c16a60a6857e6b0b165261436396ef7293f8b5c9c828a3a203147ed4a", - "sha256:4b4cd51a57b698b2d06cb9993b7ac8dfe89a3b2878e96bc7948e9f19ff51dba6", - "sha256:51c916108c56aa6e426ce611946f901badac950ee2ddaf302b7ed35d9958970d", - "sha256:550c114a8df0aafe9a05442a1162dfc8fec37e9af1d625ae6060fed6e756f303", - "sha256:58cf54380c3884fb49fdd37dfb7a772632b6701d28edd3e2904743c5e1773602", - "sha256:5b00be98ccd0fc123dcfad31d50030d25fcf31488cde9e61692029cd7394733b", - "sha256:5f93a5db13927a37d2d09637ccca4b2b6b48c19cd9eda7b17a2e9f77edee6a6f", - "sha256:64d0c62d88e67b98a1a5e71987b7aa7b5bcffc7dcee65b635823dbdd0a8dbbd0", - "sha256:73f80bf4cd5d2ca7814da30a120de1f9408ee0619cc75da87d0641273d202a09", - "sha256:752d76472d9804ac60f0078c79cdae8b956f293177acd2316cd1e15149aee132", - "sha256:83c381767e2cc10e93e40281a04852facc4cd9334550e0f392f72d1c0a9c5753", - "sha256:8fefe5868cd082db1186f2837d64cfbfa78b548ea0d0543e9b28935ccce81ce9", - "sha256:9191d68659eda01e448188f60364c7763a7ca6653ed3f87ebb165822153a8547", - "sha256:96f19de485a2925314f5020e85911fb447ff5fbef56e8c7c6927851b95533a1c", - "sha256:9a13dc409f2564de15dd68be65b462ba0dde01b19663720c68c1140c782d1d75", - "sha256:a2c2a947fae7d1062ef08c4e369e0ba2086049a5e598fda41122535557012e9e", - "sha256:a2d4f1513d63c795e82948e1305f31a6d530626e5f9f2605408b300ae6095093", - "sha256:a5bf613e96f49712073de86f20dbdd4014ca18efd4d34ed18c75bd808337851b", - "sha256:a6d2e0f9f7a69403e388894d4ca5ada5c47230716a03f2847cfc7bd1ecb589d6", - "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", - "sha256:ba7c3a7e5f23e215cb271516197030c32aef2e754252c4c70a50aaff7031a2c8", - "sha256:c0022283e9556e0f3643b7c3c03f05063ca72b3063291834cca43234f20c60bb", - "sha256:c174e322bb5783c099aaf87faeb240c8d210686b04bd61dfd05a8e5a83d88969", - "sha256:c9c8e68d8b4a56fda8c025e538e639f8c5953f5073886b596c93ec9b620055e7", - "sha256:cfcac6aa6f42397471e4943e0feb2244549db5c5d01efcd02725b96af417f3fe", - "sha256:d5e73fa573e273e4f2e5ff96f9043858a5e9311e94ffefd88a3186a910c70917", - "sha256:def246fe9e180626731b26e89816e79aae2276f825420a07b4a647abaa84becc", - "sha256:dfbbc74ec68a0fd08cfec1f4b5e8cca3d3cd7de5501b01c4b5d209995033cde9", - "sha256:e160bf9df356d841bb6c180eeeea1834085464626dc1b68fa4e1d59070affdc3", - "sha256:e541c3ef484852ef36545f66209444c48b28661e864ccadb29daddb6a4b8e5f5", - "sha256:f9b0b8a03ef474f56d1a842af1a2e01398b8f7654009823c6d9e0ecff4d5cfbf", - "sha256:f9ee9b52f5f857fbaf9d605a360884f034c92c1c23021fb90b2e39b8e64bede6", - "sha256:fbdd522624141e40948ab3e8cdae6e04c748d78710e9f0f8d4dae2750831de19", - "sha256:fd3d4602dc64914d462924a08c1a9816435a2155d74f325853c1f1ac3b2d9800" - ], - "markers": "python_version >= '3.13'", - "version": "==0.2.2" + "markers": "python_version >= '3.9'", + "version": "==25.4.0" }, "brotli": { "hashes": [ - "sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208", - "sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48", - "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354", - "sha256:0737ddb3068957cf1b054899b0883830bb1fec522ec76b1098f9b6e0f02d9419", - "sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a", - "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128", - "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c", - "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088", - "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9", - "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a", - "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3", - "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757", - "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2", - "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438", - "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578", - "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b", - "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b", - "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68", - "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0", - "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d", - "sha256:2feb1d960f760a575dbc5ab3b1c00504b24caaf6986e2dc2b01c09c87866a943", - "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd", - "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409", - "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28", - "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da", - "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50", - "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f", - "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0", - "sha256:3ee8a80d67a4334482d9712b8e83ca6b1d9bc7e351931252ebef5d8f7335a547", - "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180", - "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0", - "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d", - "sha256:4410f84b33374409552ac9b6903507cdb31cd30d2501fc5ca13d18f73548444a", - "sha256:494994f807ba0b92092a163a0a283961369a65f6cbe01e8891132b7a320e61eb", - "sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112", - "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc", - "sha256:4f3607b129417e111e30637af1b56f24f7a49e64763253bbc275c75fa887d4b2", - "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265", - "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327", - "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95", - "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec", - "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd", - "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c", - "sha256:5e55da2c8724191e5b557f8e18943b1b4839b8efc3ef60d65985bcf6f587dd38", - "sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914", - "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0", - "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a", - "sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7", - "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368", - "sha256:6974f52a02321b36847cd19d1b8e381bf39939c21efd6ee2fc13a28b0d99348c", - "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0", - "sha256:6c6e0c425f22c1c719c42670d561ad682f7bfeeef918edea971a79ac5252437f", - "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451", - "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f", - "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8", - "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e", - "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248", - "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c", - "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91", - "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", - "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7", - "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966", - "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9", - "sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97", - "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d", - "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5", - "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf", - "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac", - "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b", - "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951", - "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74", - "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648", - "sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60", - "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c", - "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1", - "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8", - "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d", - "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc", - "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61", - "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460", - "sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751", - "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9", - "sha256:a7e53012d2853a07a4a79c00643832161a910674a893d296c9f1259859a289d2", - "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0", - "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1", - "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474", - "sha256:aea440a510e14e818e67bfc4027880e2fb500c2ccb20ab21c7a7c8b5b4703d75", - "sha256:af6fa6817889314555aede9a919612b23739395ce767fe7fcbea9a80bf140fe5", - "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f", - "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2", - "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f", - "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb", - "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6", - "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9", - "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111", - "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2", - "sha256:cb1dac1770878ade83f2ccdf7d25e494f05c9165f5246b46a621cc849341dc01", - "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467", - "sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619", - "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf", - "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408", - "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579", - "sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84", - "sha256:d2b35ca2c7f81d173d2fadc2f4f31e88cc5f7a39ae5b6db5513cf3383b0e0ec7", - "sha256:d342778ef319e1026af243ed0a07c97acf3bad33b9f29e7ae6a1f68fd083e90c", - "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284", - "sha256:d7702622a8b40c49bffb46e1e3ba2e81268d5c04a34f460978c6b5517a34dd52", - "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b", - "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59", - "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752", - "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1", - "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80", - "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839", - "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0", - "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2", - "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3", - "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64", - "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089", - "sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643", - "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b", - "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e", - "sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985", - "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596", - "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2", - "sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064" - ], - "version": "==1.1.0" + "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24", + "sha256:072e7624b1fc4d601036ab3f4f27942ef772887e876beff0301d261210bca97f", + "sha256:09ac247501d1909e9ee47d309be760c89c990defbb2e0240845c892ea5ff0de4", + "sha256:0bbd5b5ccd157ae7913750476d48099aaf507a79841c0d04a9db4415b14842de", + "sha256:0cf8c3b8ba93d496b2fae778039e2f5ecc7cff99df84df337ca31d8f2252896c", + "sha256:14ef29fc5f310d34fc7696426071067462c9292ed98b5ff5a27ac70a200e5470", + "sha256:15b33fe93cedc4caaff8a0bd1eb7e3dab1c61bb22a0bf5bdfdfd97cd7da79744", + "sha256:1b1d6a4efedd53671c793be6dd760fcf2107da3a52331ad9ea429edf0902f27a", + "sha256:1b557b29782a643420e08d75aea889462a4a8796e9a6cf5621ab05a3f7da8ef2", + "sha256:1b71754d5b6eda54d16fbbed7fce2d8bc6c052a1b91a35c320247946ee103502", + "sha256:1ce223652fd4ed3eb2b7f78fbea31c52314baecfac68db44037bb4167062a937", + "sha256:1e68cdf321ad05797ee41d1d09169e09d40fdf51a725bb148bff892ce04583d7", + "sha256:260d3692396e1895c5034f204f0db022c056f9e2ac841593a4cf9426e2a3faca", + "sha256:26e8d3ecb0ee458a9804f47f21b74845cc823fd1bb19f02272be70774f56e2a6", + "sha256:2881416badd2a88a7a14d981c103a52a23a276a553a8aacc1346c2ff47c8dc17", + "sha256:29b7e6716ee4ea0c59e3b241f682204105f7da084d6254ec61886508efeb43bc", + "sha256:2a7f1d03727130fc875448b65b127a9ec5d06d19d0148e7554384229706f9d1b", + "sha256:2d39b54b968f4b49b5e845758e202b1035f948b0561ff5e6385e855c96625971", + "sha256:2e1ad3fda65ae0d93fec742a128d72e145c9c7a99ee2fcd667785d99eb25a7fe", + "sha256:3173e1e57cebb6d1de186e46b5680afbd82fd4301d7b2465beebe83ed317066d", + "sha256:3219bd9e69868e57183316ee19c84e03e8f8b5a1d1f2667e1aa8c2f91cb061ac", + "sha256:350c8348f0e76fff0a0fd6c26755d2653863279d086d3aa2c290a6a7251135dd", + "sha256:35d382625778834a7f3061b15423919aa03e4f5da34ac8e02c074e4b75ab4f84", + "sha256:3b90b767916ac44e93a8e28ce6adf8d551e43affb512f2377c732d486ac6514e", + "sha256:3e1b35d56856f3ed326b140d3c6d9db91740f22e14b06e840fe4bb1923439a18", + "sha256:3ebe801e0f4e56d17cd386ca6600573e3706ce1845376307f5d2cbd32149b69a", + "sha256:3f3c908bcc404c90c77d5a073e55271a0a498f4e0756e48127c35d91cf155947", + "sha256:40d918bce2b427a0c4ba189df7a006ac0c7277c180aee4617d99e9ccaaf59e6a", + "sha256:465a0d012b3d3e4f1d6146ea019b5c11e3e87f03d1676da1cc3833462e672fb0", + "sha256:4735a10f738cb5516905a121f32b24ce196ab82cfc1e4ba2e3ad1b371085fd46", + "sha256:4ecdb3b6dc36e6d6e14d3a1bdc6c1057c8cbf80db04031d566eb6080ce283a48", + "sha256:50b1b799f45da91292ffaa21a473ab3a3054fa78560e8ff67082a185274431c8", + "sha256:54a50a9dad16b32136b2241ddea9e4df159b41247b2ce6aac0b3276a66a8f1e5", + "sha256:5732eff8973dd995549a18ecbd8acd692ac611c5c0bb3f59fa3541ae27b33be3", + "sha256:598e88c736f63a0efec8363f9eb34e5b5536b7b6b1821e401afcb501d881f59a", + "sha256:640fe199048f24c474ec6f3eae67c48d286de12911110437a36a87d7c89573a6", + "sha256:66c02c187ad250513c2f4fce973ef402d22f80e0adce734ee4e4efd657b6cb64", + "sha256:67a91c5187e1eec76a61625c77a6c8c785650f5b576ca732bd33ef58b0dff49c", + "sha256:6be67c19e0b0c56365c6a76e393b932fb0e78b3b56b711d180dd7013cb1fd984", + "sha256:6c12dad5cd04530323e723787ff762bac749a7b256a5bece32b2243dd5c27b21", + "sha256:71a66c1c9be66595d628467401d5976158c97888c2c9379c034e1e2312c5b4f5", + "sha256:7274942e69b17f9cef76691bcf38f2b2d4c8a5f5dba6ec10958363dcb3308a0a", + "sha256:7547369c4392b47d30a3467fe8c3330b4f2e0f7730e45e3103d7d636678a808b", + "sha256:7a47ce5c2288702e09dc22a44d0ee6152f2c7eda97b3c8482d826a1f3cfc7da7", + "sha256:7a61c06b334bd99bc5ae84f1eeb36bfe01400264b3c352f968c6e30a10f9d08b", + "sha256:7ad8cec81f34edf44a1c6a7edf28e7b7806dfb8886e371d95dcf789ccd4e4982", + "sha256:7e9053f5fb4e0dfab89243079b3e217f2aea4085e4d58c5c06115fc34823707f", + "sha256:7fa18d65a213abcfbb2f6cafbb4c58863a8bd6f2103d65203c520ac117d1944b", + "sha256:81da1b229b1889f25adadc929aeb9dbc4e922bd18561b65b08dd9343cfccca84", + "sha256:82676c2781ecf0ab23833796062786db04648b7aae8be139f6b8065e5e7b1518", + "sha256:832c115a020e463c2f67664560449a7bea26b0c1fdd690352addad6d0a08714d", + "sha256:844a8ceb8483fefafc412f85c14f2aae2fb69567bf2a0de53cdb88b73e7c43ae", + "sha256:865cedc7c7c303df5fad14a57bc5db1d4f4f9b2b4d0a7523ddd206f00c121a16", + "sha256:88ef7d55b7bcf3331572634c3fd0ed327d237ceb9be6066810d39020a3ebac7a", + "sha256:898be2be399c221d2671d29eed26b6b2713a02c2119168ed914e7d00ceadb56f", + "sha256:8d4f47f284bdd28629481c97b5f29ad67544fa258d9091a6ed1fda47c7347cd1", + "sha256:92edab1e2fd6cd5ca605f57d4545b6599ced5dea0fd90b2bcdf8b247a12bd190", + "sha256:9322b9f8656782414b37e6af884146869d46ab85158201d82bab9abbcb971dc7", + "sha256:95db242754c21a88a79e01504912e537808504465974ebb92931cfca2510469e", + "sha256:963a08f3bebd8b75ac57661045402da15991468a621f014be54e50f53a58d19e", + "sha256:96fbe82a58cdb2f872fa5d87dedc8477a12993626c446de794ea025bbda625ea", + "sha256:99cfa69813d79492f0e5d52a20fd18395bc82e671d5d40bd5a91d13e75e468e8", + "sha256:9c79f57faa25d97900bfb119480806d783fba83cd09ee0b33c17623935b05fa3", + "sha256:9e5825ba2c9998375530504578fd4d5d1059d09621a02065d1b6bfc41a8e05ab", + "sha256:9fe11467c42c133f38d42289d0861b6b4f9da31e8087ca2c0d7ebb4543625526", + "sha256:a1778532b978d2536e79c05dac2d8cd857f6c55cd0c95ace5b03740824e0e2f1", + "sha256:a387225a67f619bf16bd504c37655930f910eb03675730fc2ad69d3d8b5e7e92", + "sha256:a56ef534b66a749759ebd091c19c03ef81eb8cd96f0d1d16b59127eaf1b97a12", + "sha256:aa47441fa3026543513139cb8926a92a8e305ee9c71a6209ef7a97d91640ea03", + "sha256:ac27a70bda257ae3f380ec8310b0a06680236bea547756c277b5dfe55a2452a8", + "sha256:acec55bb7c90f1dfc476126f9711a8e81c9af7fb617409a9ee2953115343f08d", + "sha256:adedc4a67e15327dfdd04884873c6d5a01d3e3b6f61406f99b1ed4865a2f6d28", + "sha256:af43b8711a8264bb4e7d6d9a6d004c3a2019c04c01127a868709ec29962b6036", + "sha256:b232029d100d393ae3c603c8ffd7e3fe6f798c5e28ddca5feabb8e8fdb732997", + "sha256:b35c13ce241abdd44cb8ca70683f20c0c079728a36a996297adb5334adfc1c44", + "sha256:b63daa43d82f0cdabf98dee215b375b4058cce72871fd07934f179885aad16e8", + "sha256:b908d1a7b28bc72dfb743be0d4d3f8931f8309f810af66c906ae6cd4127c93cb", + "sha256:ba76177fd318ab7b3b9bf6522be5e84c2ae798754b6cc028665490f6e66b5533", + "sha256:bba6e7e6cfe1e6cb6eb0b7c2736a6059461de1fa2c0ad26cf845de6c078d16c8", + "sha256:c0d6770111d1879881432f81c369de5cde6e9467be7c682a983747ec800544e2", + "sha256:c16ab1ef7bb55651f5836e8e62db1f711d55b82ea08c3b8083ff037157171a69", + "sha256:c1702888c9f3383cc2f09eb3e88b8babf5965a54afb79649458ec7c3c7a63e96", + "sha256:c25332657dee6052ca470626f18349fc1fe8855a56218e19bd7a8c6ad4952c49", + "sha256:c8565e3cdc1808b1a34714b553b262c5de5fbda202285782173ec137fd13709f", + "sha256:cf9cba6f5b78a2071ec6fb1e7bd39acf35071d90a81231d67e92d637776a6a63", + "sha256:d206a36b4140fbb5373bf1eb73fb9de589bb06afd0d22376de23c5e91d0ab35f", + "sha256:d2d085ded05278d1c7f65560aae97b3160aeb2ea2c0b3e26204856beccb60888", + "sha256:d8c05b1dfb61af28ef37624385b0029df902ca896a639881f594060b30ffc9a7", + "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a", + "sha256:e7c0af964e0b4e3412a0ebf341ea26ec767fa0b4cf81abb5e897c9338b5ad6a3", + "sha256:e80a28f2b150774844c8b454dd288be90d76ba6109670fe33d7ff54d96eb5cb8", + "sha256:e813da3d2d865e9793ef681d3a6b66fa4b7c19244a45b817d0cceda67e615990", + "sha256:e85190da223337a6b7431d92c799fca3e2982abd44e7b8dec69938dcc81c8e9e", + "sha256:e99befa0b48f3cd293dafeacdd0d191804d105d279e0b387a32054c1180f3161", + "sha256:eda5a6d042c698e28bda2507a89b16555b9aa954ef1d750e1c20473481aff675", + "sha256:ef87b8ab2704da227e83a246356a2b179ef826f550f794b2c52cddb4efbd0196", + "sha256:f16dace5e4d3596eaeb8af334b4d2c820d34b8278da633ce4a00020b2eac981c", + "sha256:f8d635cafbbb0c61327f942df2e3f474dde1cff16c3cd0580564774eaba1ee13", + "sha256:fc1530af5c3c275b8524f2e24841cbe2599d74462455e9bae5109e9ff42e9361", + "sha256:ff09cd8c5eec3b9d02d2408db41be150d8891c5566addce57513bf546e3d6c6d" + ], + "version": "==1.2.0" }, "cairocffi": { "hashes": [ @@ -422,88 +342,122 @@ }, "charset-normalizer": { "hashes": [ - "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", - "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", - "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", - "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", - "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", - "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", - "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c", - "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", - "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", - "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", - "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", - "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", - "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", - "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", - "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", - "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", - "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", - "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", - "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4", - "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", - "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", - "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", - "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", - "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", - "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", - "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", - "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b", - "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", - "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", - "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", - "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", - "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", - "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", - "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", - "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", - "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", - "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a", - "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40", - "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", - "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", - "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", - "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", - "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", - "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", - "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", - "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", - "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", - "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", - "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9", - "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", - "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", - "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", - "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b", - "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", - "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942", - "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", - "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", - "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b", - "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", - "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", - "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", - "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", - "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", - "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", - "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", - "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", - "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", - "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", - "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", - "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", - "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", - "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb", - "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", - "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557", - "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", - "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", - "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", - "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", - "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9" + "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad", + "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93", + "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", + "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", + "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc", + "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", + "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63", + "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d", + "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", + "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", + "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0", + "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505", + "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", + "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af", + "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", + "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318", + "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", + "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", + "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", + "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", + "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576", + "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", + "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1", + "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8", + "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1", + "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", + "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", + "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", + "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88", + "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", + "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", + "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", + "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a", + "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", + "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", + "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84", + "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db", + "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", + "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7", + "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", + "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", + "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", + "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", + "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", + "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", + "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2", + "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", + "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d", + "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", + "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", + "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf", + "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6", + "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", + "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", + "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa", + "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", + "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", + "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", + "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", + "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", + "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", + "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", + "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", + "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e", + "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313", + "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", + "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", + "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d", + "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", + "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", + "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3", + "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9", + "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", + "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", + "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", + "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", + "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50", + "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf", + "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", + "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", + "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac", + "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", + "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", + "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c", + "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", + "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6", + "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e", + "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4", + "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84", + "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69", + "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", + "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", + "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", + "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", + "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", + "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", + "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", + "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d", + "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074", + "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3", + "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", + "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", + "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", + "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d", + "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", + "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f", + "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8", + "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", + "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966", + "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", + "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3", + "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e", + "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608" ], "markers": "python_version >= '3.7'", - "version": "==3.4.3" + "version": "==3.4.4" }, "colorama": { "hashes": [ @@ -696,11 +650,11 @@ }, "idna": { "hashes": [ - "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", - "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" + "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", + "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" ], - "markers": "python_version >= '3.6'", - "version": "==3.10" + "markers": "python_version >= '3.8'", + "version": "==3.11" }, "isodate": { "hashes": [ @@ -731,119 +685,155 @@ }, "multidict": { "hashes": [ - "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9", - "sha256:01d0959807a451fe9fdd4da3e139cb5b77f7328baf2140feeaf233e1d777b729", - "sha256:024ce601f92d780ca1617ad4be5ac15b501cc2414970ffa2bb2bbc2bd5a68fa5", - "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e", - "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138", - "sha256:0af5f9dee472371e36d6ae38bde009bd8ce65ac7335f55dcc240379d7bed1495", - "sha256:0b2e886624be5773e69cf32bcb8534aecdeb38943520b240fed3d5596a430f2f", - "sha256:0c5cbac6b55ad69cb6aa17ee9343dfbba903118fd530348c330211dc7aa756d1", - "sha256:0e0558693063c75f3d952abf645c78f3c5dfdd825a41d8c4d8156fc0b0da6e7e", - "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6", - "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8", - "sha256:105245cc6b76f51e408451a844a54e6823bbd5a490ebfe5bdfc79798511ceded", - "sha256:10a68a9191f284fe9d501fef4efe93226e74df92ce7a24e301371293bd4918ae", - "sha256:14616a30fe6d0a48d0a48d1a633ab3b8bec4cf293aac65f32ed116f620adfd69", - "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364", - "sha256:163c7ea522ea9365a8a57832dea7618e6cbdc3cd75f8c627663587459a4e328f", - "sha256:17d2cbbfa6ff20821396b25890f155f40c986f9cfbce5667759696d83504954f", - "sha256:190766dac95aab54cae5b152a56520fd99298f32a1266d66d27fdd1b5ac00f4e", - "sha256:1a0ccbfe93ca114c5d65a2471d52d8829e56d467c97b0e341cf5ee45410033b3", - "sha256:21f216669109e02ef3e2415ede07f4f8987f00de8cdfa0cc0b3440d42534f9f0", - "sha256:22e38b2bc176c5eb9c0a0e379f9d188ae4cd8b28c0f53b52bce7ab0a9e534657", - "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", - "sha256:2a4c6875c37aae9794308ec43e3530e4aa0d36579ce38d89979bbf89582002bb", - "sha256:34d8f2a5ffdceab9dcd97c7a016deb2308531d5f0fced2bb0c9e1df45b3363d7", - "sha256:350f6b0fe1ced61e778037fdc7613f4051c8baf64b1ee19371b42a3acdb016a0", - "sha256:37b7187197da6af3ee0b044dbc9625afd0c885f2800815b228a0e70f9a7f473d", - "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b", - "sha256:3ba5aaf600edaf2a868a391779f7a85d93bed147854925f34edd24cc70a3e141", - "sha256:3bb0eae408fa1996d87247ca0d6a57b7fc1dcf83e8a5c47ab82c558c250d4adf", - "sha256:3f8e2384cb83ebd23fd07e9eada8ba64afc4c759cd94817433ab8c81ee4b403f", - "sha256:40cd05eaeb39e2bc8939451f033e57feaa2ac99e07dbca8afe2be450a4a3b6cf", - "sha256:43868297a5759a845fa3a483fb4392973a95fb1de891605a3728130c52b8f40f", - "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24", - "sha256:467fe64138cfac771f0e949b938c2e1ada2b5af22f39692aa9258715e9ea613a", - "sha256:49517449b58d043023720aa58e62b2f74ce9b28f740a0b5d33971149553d72aa", - "sha256:497a2954adc25c08daff36f795077f63ad33e13f19bfff7736e72c785391534f", - "sha256:4a1fb393a2c9d202cb766c76208bd7945bc194eba8ac920ce98c6e458f0b524b", - "sha256:4bb7627fd7a968f41905a4d6343b0d63244a0623f006e9ed989fa2b78f4438a0", - "sha256:4d09384e75788861e046330308e7af54dd306aaf20eb760eb1d0de26b2bea2cb", - "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d", - "sha256:52e3c8d43cdfff587ceedce9deb25e6ae77daba560b626e97a56ddcad3756879", - "sha256:55624b3f321d84c403cb7d8e6e982f41ae233d85f85db54ba6286f7295dc8a9c", - "sha256:56c6b3652f945c9bc3ac6c8178cd93132b8d82dd581fcbc3a00676c51302bc1a", - "sha256:580b643b7fd2c295d83cad90d78419081f53fd532d1f1eb67ceb7060f61cff0d", - "sha256:59e8d40ab1f5a8597abcef00d04845155a5693b5da00d2c93dbe88f2050f2812", - "sha256:5df8afd26f162da59e218ac0eefaa01b01b2e6cd606cffa46608f699539246da", - "sha256:630f70c32b8066ddfd920350bc236225814ad94dfa493fe1910ee17fe4365cbb", - "sha256:66247d72ed62d5dd29752ffc1d3b88f135c6a8de8b5f63b7c14e973ef5bda19e", - "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287", - "sha256:6bf2f10f70acc7a2446965ffbc726e5fc0b272c97a90b485857e5c70022213eb", - "sha256:6c84378acd4f37d1b507dfa0d459b449e2321b3ba5f2338f9b085cf7a7ba95eb", - "sha256:6d46a180acdf6e87cc41dc15d8f5c2986e1e8739dc25dbb7dac826731ef381a4", - "sha256:756989334015e3335d087a27331659820d53ba432befdef6a718398b0a8493ad", - "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f", - "sha256:7dd57515bebffd8ebd714d101d4c434063322e4fe24042e90ced41f18b6d3395", - "sha256:7f683a551e92bdb7fac545b9c6f9fa2aebdeefa61d607510b3533286fcab67f5", - "sha256:87a32d20759dc52a9e850fe1061b6e41ab28e2998d44168a8a341b99ded1dba0", - "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793", - "sha256:8c91cdb30809a96d9ecf442ec9bc45e8cfaa0f7f8bdf534e082c2443a196727e", - "sha256:8c9854df0eaa610a23494c32a6f44a3a550fb398b6b51a56e8c6b9b3689578db", - "sha256:8e42332cf8276bb7645d310cdecca93a16920256a5b01bebf747365f86a1675b", - "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c", - "sha256:967af5f238ebc2eb1da4e77af5492219fbd9b4b812347da39a7b5f5c72c0fa45", - "sha256:9a950b7cf54099c1209f455ac5970b1ea81410f2af60ed9eb3c3f14f0bfcf987", - "sha256:a1b20a9d56b2d81e2ff52ecc0670d583eaabaa55f402e8d16dd062373dbbe796", - "sha256:a506a77ddee1efcca81ecbeae27ade3e09cdf21a8ae854d766c2bb4f14053f92", - "sha256:a59c63061f1a07b861c004e53869eb1211ffd1a4acbca330e3322efa6dd02978", - "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802", - "sha256:a693fc5ed9bdd1c9e898013e0da4dcc640de7963a371c0bd458e50e046bf6438", - "sha256:aaea28ba20a9026dfa77f4b80369e51cb767c61e33a2d4043399c67bd95fb7c6", - "sha256:ad8850921d3a8d8ff6fbef790e773cecfc260bbfa0566998980d3fa8f520bc4a", - "sha256:ad887a8250eb47d3ab083d2f98db7f48098d13d42eb7a3b67d8a5c795f224ace", - "sha256:ae9408439537c5afdca05edd128a63f56a62680f4b3c234301055d7a2000220f", - "sha256:af7618b591bae552b40dbb6f93f5518328a949dac626ee75927bba1ecdeea9f4", - "sha256:b6819f83aef06f560cb15482d619d0e623ce9bf155115150a85ab11b8342a665", - "sha256:b8aa6f0bd8125ddd04a6593437bad6a7e70f300ff4180a531654aa2ab3f6d58f", - "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402", - "sha256:b95494daf857602eccf4c18ca33337dd2be705bccdb6dddbfc9d513e6addb9d9", - "sha256:b9e5853bbd7264baca42ffc53391b490d65fe62849bf2c690fa3f6273dbcd0cb", - "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7", - "sha256:be5bf4b3224948032a845d12ab0f69f208293742df96dc14c4ff9b09e508fc17", - "sha256:c5c97aa666cf70e667dfa5af945424ba1329af5dd988a437efeb3a09430389fb", - "sha256:c7a0e9b561e6460484318a7612e725df1145d46b0ef57c6b9866441bf6e27e0c", - "sha256:caebafea30ed049c57c673d0b36238b1748683be2593965614d7b0e99125c877", - "sha256:cbbc54e58b34c3bae389ef00046be0961f30fef7cb0dd9c7756aee376a4f7683", - "sha256:cc356250cffd6e78416cf5b40dc6a74f1edf3be8e834cf8862d9ed5265cf9b0e", - "sha256:ce9a40fbe52e57e7edf20113a4eaddfacac0561a0879734e636aa6d4bb5e3fb0", - "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3", - "sha256:d24f351e4d759f5054b641c81e8291e5d122af0fca5c72454ff77f7cbe492de8", - "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd", - "sha256:d8c112f7a90d8ca5d20213aa41eac690bb50a76da153e3afb3886418e61cb22e", - "sha256:d9890d68c45d1aeac5178ded1d1cccf3bc8d7accf1f976f79bf63099fb16e4bd", - "sha256:dadf95aa862714ea468a49ad1e09fe00fcc9ec67d122f6596a8d40caf6cec7d0", - "sha256:db6a3810eec08280a172a6cd541ff4a5f6a97b161d93ec94e6c4018917deb6b7", - "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7", - "sha256:e167bf899c3d724f9662ef00b4f7fef87a19c22b2fead198a6f68b263618df52", - "sha256:e1b93790ed0bc26feb72e2f08299691ceb6da5e9e14a0d13cc74f1869af327a0", - "sha256:e5b1413361cef15340ab9dc61523e653d25723e82d488ef7d60a12878227ed50", - "sha256:ecab51ad2462197a4c000b6d5701fc8585b80eecb90583635d7e327b7b6923eb", - "sha256:ed3b94c5e362a8a84d69642dbeac615452e8af9b8eb825b7bc9f31a53a1051e2", - "sha256:ed8358ae7d94ffb7c397cecb62cbac9578a83ecefc1eba27b9090ee910e2efb6", - "sha256:edfdcae97cdc5d1a89477c436b61f472c4d40971774ac4729c613b4b133163cb", - "sha256:ee25f82f53262f9ac93bd7e58e47ea1bdcc3393cef815847e397cba17e284210", - "sha256:f3be27440f7644ab9a13a6fc86f09cdd90b347c3c5e30c6d6d860de822d7cb53", - "sha256:f46a6e8597f9bd71b31cc708195d42b634c8527fecbcf93febf1052cacc1f16e", - "sha256:f6eb37d511bfae9e13e82cb4d1af36b91150466f24d9b2b8a9785816deb16605", - "sha256:f8d4916a81697faec6cb724a273bd5457e4c6c43d82b29f9dc02c5542fd21fc9", - "sha256:f93b2b2279883d1d0a9e1bd01f312d6fc315c5e4c1f09e112e4736e2f650bc4e", - "sha256:f9867e55590e0855bcec60d4f9a092b69476db64573c9fe17e92b0c50614c16a", - "sha256:f996b87b420995a9174b2a7c1a8daf7db4750be6848b03eb5e639674f7963773" + "sha256:03ca744319864e92721195fa28c7a3b2bc7b686246b35e4078c1e4d0eb5466d3", + "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", + "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", + "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", + "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", + "sha256:08325c9e5367aa379a3496aa9a022fe8837ff22e00b94db256d3a1378c76ab32", + "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", + "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", + "sha256:096f52730c3fb8ed419db2d44391932b63891b2c5ed14850a7e215c0ba9ade36", + "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", + "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff", + "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8", + "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", + "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721", + "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", + "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", + "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", + "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", + "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", + "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", + "sha256:23bfeee5316266e5ee2d625df2d2c602b829435fc3a235c2ba2131495706e4a0", + "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", + "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", + "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6", + "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", + "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", + "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", + "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", + "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", + "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", + "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912", + "sha256:363eb68a0a59bd2303216d2346e6c441ba10d36d1f9969fcb6f1ba700de7bb5c", + "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", + "sha256:3996b50c3237c4aec17459217c1e7bbdead9a22a0fcd3c365564fbd16439dde6", + "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2", + "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", + "sha256:3ba3ef510467abb0667421a286dc906e30eb08569365f5cdb131d7aff7c2dd84", + "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", + "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", + "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", + "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd", + "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", + "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", + "sha256:478cc36476687bac1514d651cbbaa94b86b0732fb6855c60c673794c7dd2da62", + "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", + "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", + "sha256:4b73189894398d59131a66ff157837b1fafea9974be486d036bb3d32331fdbf0", + "sha256:4b7a9db5a870f780220e931d0002bbfd88fb53aceb6293251e2c839415c1b20e", + "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6", + "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc", + "sha256:4d72a9a2d885f5c208b0cb91ff2ed43636bb7e345ec839ff64708e04f69a13cc", + "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", + "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7", + "sha256:521f33e377ff64b96c4c556b81c55d0cfffb96a11c194fd0c3f1e56f3d8dd5a4", + "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", + "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", + "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", + "sha256:661709cdcd919a2ece2234f9bae7174e5220c80b034585d7d8a755632d3e2111", + "sha256:680878b9f3d45c31e1f730eef731f9b0bc1da456155688c6745ee84eb818e90e", + "sha256:6843b28b0364dc605f21481c90fadb5f60d9123b442eb8a726bb74feef588a84", + "sha256:68af405971779d8b37198726f2b6fe3955db846fee42db7a4286fc542203934c", + "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", + "sha256:6bdce131e14b04fd34a809b6380dbfd826065c3e2fe8a50dbae659fa0c390546", + "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", + "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", + "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", + "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", + "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", + "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", + "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", + "sha256:7e73299c99939f089dd9b2120a04a516b95cdf8c1cd2b18c53ebf0de80b1f18f", + "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", + "sha256:7f5170993a0dd3ab871c74f45c0a21a4e2c37a2f2b01b5f722a2ad9c6650469e", + "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", + "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", + "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", + "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", + "sha256:8b55d5497b51afdfde55925e04a022f1de14d4f4f25cdfd4f5d9b0aa96166851", + "sha256:8cfc12a8630a29d601f48d47787bd7eb730e475e83edb5d6c5084317463373eb", + "sha256:9281bf5b34f59afbc6b1e477a372e9526b66ca446f4bf62592839c195a718b32", + "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", + "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", + "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81", + "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", + "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", + "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", + "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", + "sha256:9cf41880c991716f3c7cec48e2f19ae4045fc9db5fc9cff27347ada24d710bb5", + "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb", + "sha256:9f474ad5acda359c8758c8accc22032c6abe6dc87a8be2440d097785e27a9349", + "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", + "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", + "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", + "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", + "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34", + "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c", + "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", + "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", + "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", + "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", + "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff", + "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", + "sha256:afa8a2978ec65d2336305550535c9c4ff50ee527914328c8677b3973ade52b85", + "sha256:b15b3afff74f707b9275d5ba6a91ae8f6429c3ffb29bbfd216b0b375a56f13d7", + "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", + "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", + "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", + "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", + "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", + "sha256:b61189b29081a20c7e4e0b49b44d5d44bb0dc92be3c6d06a11cc043f81bf9329", + "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", + "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", + "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", + "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", + "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", + "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", + "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", + "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", + "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", + "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", + "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", + "sha256:ce8fdc2dca699f8dbf055a61d73eaa10482569ad20ee3c36ef9641f69afa8c91", + "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", + "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", + "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", + "sha256:d874eb056410ca05fed180b6642e680373688efafc7f077b2a2f61811e873a40", + "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7", + "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", + "sha256:df0e3bf7993bdbeca5ac25aa859cf40d39019e015c9c91809ba7093967f7a648", + "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", + "sha256:e2862408c99f84aa571ab462d25236ef9cb12a602ea959ba9c9009a54902fc73", + "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b", + "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", + "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", + "sha256:eb866162ef2f45063acc7a53a88ef6fe8bf121d45c30ea3c9cd87ce7e191a8d4", + "sha256:ec81878ddf0e98817def1e77d4f50dae5ef5b0e4fe796fae3bd674304172416e", + "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", + "sha256:f0e77e3c0008bc9316e662624535b88d360c3a5d3f81e15cf12c139a75250046", + "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", + "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9", + "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", + "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", + "sha256:f8e5c0031b90ca9ce555e2e8fd5c3b02a25f14989cbc310701823832c99eb687", + "sha256:fb287618b9c7aa3bf8d825f02d9201b2f13078a5ed3b293c8f4d953917d84d5e", + "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", + "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7" ], "markers": "python_version >= '3.9'", - "version": "==6.6.4" + "version": "==6.7.0" }, "natural": { "hashes": [ @@ -854,92 +844,96 @@ }, "orjson": { "hashes": [ - "sha256:00f1a271e56d511d1569937c0447d7dce5a99a33ea0dec76673706360a051904", - "sha256:0c212cfdd90512fe722fa9bd620de4d46cda691415be86b2e02243242ae81873", - "sha256:0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d", - "sha256:0e92a4e83341ef79d835ca21b8bd13e27c859e4e9e4d7b63defc6e58462a3710", - "sha256:11c6d71478e2cbea0a709e8a06365fa63da81da6498a53e4c4f065881d21ae8f", - "sha256:124d5ba71fee9c9902c4a7baa9425e663f7f0aecf73d31d54fe3dd357d62c1a7", - "sha256:18bd1435cb1f2857ceb59cfb7de6f92593ef7b831ccd1b9bfb28ca530e539dce", - "sha256:1c0603b1d2ffcd43a411d64797a19556ef76958aef1c182f22dc30860152a98a", - "sha256:2030c01cbf77bc67bee7eef1e7e31ecf28649353987775e3583062c752da0077", - "sha256:2039b7847ba3eec1f5886e75e6763a16e18c68a63efc4b029ddf994821e2e66b", - "sha256:212e67806525d2561efbfe9e799633b17eb668b8964abed6b5319b2f1cfbae1f", - "sha256:215c595c792a87d4407cb72dd5e0f6ee8e694ceeb7f9102b533c5a9bf2a916bb", - "sha256:22724d80ee5a815a44fc76274bb7ba2e7464f5564aacb6ecddaa9970a83e3225", - "sha256:29be5ac4164aa8bdcba5fa0700a3c9c316b411d8ed9d39ef8a882541bd452fae", - "sha256:29cb1f1b008d936803e2da3d7cba726fc47232c45df531b29edf0b232dd737e7", - "sha256:2b7b153ed90ababadbef5c3eb39549f9476890d339cf47af563aea7e07db2451", - "sha256:2d68bf97a771836687107abfca089743885fb664b90138d8761cce61d5625d55", - "sha256:317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804", - "sha256:3782d2c60b8116772aea8d9b7905221437fdf53e7277282e8d8b07c220f96cca", - "sha256:3d721fee37380a44f9d9ce6c701b3960239f4fb3d5ceea7f31cbd43882edaa2f", - "sha256:414f71e3bdd5573893bf5ecdf35c32b213ed20aa15536fe2f588f946c318824f", - "sha256:524b765ad888dc5518bbce12c77c2e83dee1ed6b0992c1790cc5fb49bb4b6667", - "sha256:56afaf1e9b02302ba636151cfc49929c1bb66b98794291afd0e5f20fecaf757c", - "sha256:58533f9e8266cb0ac298e259ed7b4d42ed3fa0b78ce76860626164de49e0d467", - "sha256:5ff835b5d3e67d9207343effb03760c00335f8b5285bfceefd4dc967b0e48f6a", - "sha256:61dcdad16da5bb486d7227a37a2e789c429397793a6955227cedbd7252eb5a27", - "sha256:6890ace0809627b0dff19cfad92d69d0fa3f089d3e359a2a532507bb6ba34efb", - "sha256:6be2f1b5d3dc99a5ce5ce162fc741c22ba9f3443d3dd586e6a1211b7bc87bc7b", - "sha256:6e8e0c3b85575a32f2ffa59de455f85ce002b8bdc0662d6b9c2ed6d80ab5d204", - "sha256:73b92a5b69f31b1a58c0c7e31080aeaec49c6e01b9522e71ff38d08f15aa56de", - "sha256:7909ae2460f5f494fecbcd10613beafe40381fd0316e35d6acb5f3a05bfda167", - "sha256:79b44319268af2eaa3e315b92298de9a0067ade6e6003ddaef72f8e0bedb94f1", - "sha256:828e3149ad8815dc14468f36ab2a4b819237c155ee1370341b91ea4c8672d2ee", - "sha256:84fd82870b97ae3cdcea9d8746e592b6d40e1e4d4527835fc520c588d2ded04f", - "sha256:88dcfc514cfd1b0de038443c7b3e6a9797ffb1b3674ef1fd14f701a13397f82d", - "sha256:8ab962931015f170b97a3dd7bd933399c1bae8ed8ad0fb2a7151a5654b6941c7", - "sha256:8b13974dc8ac6ba22feaa867fc19135a3e01a134b4f7c9c28162fed4d615008a", - "sha256:8c752089db84333e36d754c4baf19c0e1437012242048439c7e80eb0e6426e3b", - "sha256:8e531abd745f51f8035e207e75e049553a86823d189a51809c078412cefb399a", - "sha256:90368277087d4af32d38bd55f9da2ff466d25325bf6167c8f382d8ee40cb2bbc", - "sha256:913f629adef31d2d350d41c051ce7e33cf0fd06a5d1cb28d49b1899b23b903aa", - "sha256:976c6f1975032cc327161c65d4194c549f2589d88b105a5e3499429a54479770", - "sha256:97dceed87ed9139884a55db8722428e27bd8452817fbf1869c58b49fecab1120", - "sha256:9b8761b6cf04a856eb544acdd82fc594b978f12ac3602d6374a7edb9d86fd2c2", - "sha256:9d2ae0cc6aeb669633e0124531f342a17d8e97ea999e42f12a5ad4adaa304c5f", - "sha256:9d8787bdfbb65a85ea76d0e96a3b1bed7bf0fbcb16d40408dc1172ad784a49d2", - "sha256:9dba358d55aee552bd868de348f4736ca5a4086d9a62e2bfbbeeb5629fe8b0cc", - "sha256:9f1587f26c235894c09e8b5b7636a38091a9e6e7fe4531937534749c04face43", - "sha256:a0169ebd1cbd94b26c7a7ad282cf5c2744fce054133f959e02eb5265deae1872", - "sha256:ac9e05f25627ffc714c21f8dfe3a579445a5c392a9c8ae7ba1d0e9fb5333f56e", - "sha256:ae8b756575aaa2a855a75192f356bbda11a89169830e1439cfb1a3e1a6dde7be", - "sha256:af40c6612fd2a4b00de648aa26d18186cd1322330bd3a3cc52f87c699e995810", - "sha256:b67e71e47caa6680d1b6f075a396d04fa6ca8ca09aafb428731da9b3ea32a5a6", - "sha256:b822caf5b9752bc6f246eb08124c3d12bf2175b66ab74bac2ef3bbf9221ce1b2", - "sha256:ba21dbb2493e9c653eaffdc38819b004b7b1b246fb77bfc93dc016fe664eac91", - "sha256:bb93562146120bb51e6b154962d3dadc678ed0fce96513fa6bc06599bb6f6edc", - "sha256:bc779b4f4bba2847d0d2940081a7b6f7b5877e05408ffbb74fa1faf4a136c424", - "sha256:bc8bc85b81b6ac9fc4dae393a8c159b817f4c2c9dee5d12b773bddb3b95fc07e", - "sha256:bd4b909ce4c50faa2192da6bb684d9848d4510b736b0611b6ab4020ea6fd2d23", - "sha256:bfc27516ec46f4520b18ef645864cee168d2a027dbf32c5537cb1f3e3c22dac1", - "sha256:c5189a5dab8b0312eadaf9d58d3049b6a52c454256493a557405e77a3d67ab7f", - "sha256:c9416cc19a349c167ef76135b2fe40d03cea93680428efee8771f3e9fb66079d", - "sha256:cf4b81227ec86935568c7edd78352a92e97af8da7bd70bdfdaa0d2e0011a1ab4", - "sha256:d2489b241c19582b3f1430cc5d732caefc1aaf378d97e7fb95b9e56bed11725f", - "sha256:d61cd543d69715d5fc0a690c7c6f8dcc307bc23abef9738957981885f5f38229", - "sha256:d7d012ebddffcce8c85734a6d9e5f08180cd3857c5f5a3ac70185b43775d043d", - "sha256:d7d18dd34ea2e860553a579df02041845dee0af8985dff7f8661306f95504ddf", - "sha256:d8b11701bc43be92ea42bd454910437b355dfb63696c06fe953ffb40b5f763b4", - "sha256:dd759f75d6b8d1b62012b7f5ef9461d03c804f94d539a5515b454ba3a6588038", - "sha256:e0a23b41f8f98b4e61150a03f83e4f0d566880fe53519d445a962929a4d21045", - "sha256:e44fbe4000bd321d9f3b648ae46e0196d21577cf66ae684a96ff90b1f7c93633", - "sha256:e6fbaf48a744b94091a56c62897b27c31ee2da93d826aa5b207131a1e13d4064", - "sha256:e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc", - "sha256:eabcf2e84f1d7105f84580e03012270c7e97ecb1fb1618bda395061b2a84a049", - "sha256:f5aa4682912a450c2db89cbd92d356fef47e115dffba07992555542f344d301b", - "sha256:f66b001332a017d7945e177e282a40b6997056394e3ed7ddb41fb1813b83e824", - "sha256:f83abab5bacb76d9c821fd5c07728ff224ed0e52d7a71b7b3de822f3df04e15c", - "sha256:f8d902867b699bcd09c176a280b1acdab57f924489033e53d0afe79817da37e6", - "sha256:f9d4a5e041ae435b815e568537755773d05dac031fee6a57b4ba70897a44d9d2", - "sha256:fafb1a99d740523d964b15c8db4eabbfc86ff29f84898262bf6e3e4c9e97e43e", - "sha256:fbecb9709111be913ae6879b07bafd4b0785b44c1eb5cac8ac76da048b3885a1", - "sha256:fd7ff459fb393358d3a155d25b275c60b07a2c83dcd7ea962b1923f5a1134569", - "sha256:ff94112e0098470b665cb0ed06efb187154b63649403b8d5e9aedeb482b4548c" + "sha256:01ee5487fefee21e6910da4c2ee9eef005bee568a0879834df86f888d2ffbdd9", + "sha256:03bfa548cf35e3f8b3a96c4e8e41f753c686ff3d8e182ce275b1751deddab58c", + "sha256:04b69c14615fb4434ab867bf6f38b2d649f6f300af30a6705397e895f7aec67a", + "sha256:09bf242a4af98732db9f9a1ec57ca2604848e16f132e3f72edfd3c5c96de009a", + "sha256:0a54d6635fa3aaa438ae32e8570b9f0de36f3f6562c308d2a2a452e8b0592db1", + "sha256:0b2eba969ea4203c177c7b38b36c69519e6067ee68c34dc37081fac74c796e10", + "sha256:0baa0ea43cfa5b008a28d3c07705cf3ada40e5d347f0f44994a64b1b7b4b5350", + "sha256:1469d254b9884f984026bd9b0fa5bbab477a4bfe558bba6848086f6d43eb5e73", + "sha256:149d95d5e018bdd822e3f38c103b1a7c91f88d38a88aada5c4e9b3a73a244241", + "sha256:1e3704d35e47d5bee811fb1cbd8599f0b4009b14d451c4c57be5a7e25eb89a13", + "sha256:1e539e382cf46edec157ad66b0b0872a90d829a6b71f17cb633d6c160a223155", + "sha256:23ef7abc7fca96632d8174ac115e668c1e931b8fe4dde586e92a500bf1914dcc", + "sha256:26a20f3fbc6c7ff2cb8e89c4c5897762c9d88cf37330c6a117312365d6781d54", + "sha256:2c82e4f0b1c712477317434761fbc28b044c838b6b1240d895607441412371ac", + "sha256:2d6737d0e616a6e053c8b4acc9eccea6b6cce078533666f32d140e4f85002534", + "sha256:3740bffd9816fc0326ddc406098a3a8f387e42223f5f455f2a02a9f834ead80c", + "sha256:38aa9e65c591febb1b0aed8da4d469eba239d434c218562df179885c94e1a3ad", + "sha256:39485f4ab4c9b30a3943cfe99e1a213c4776fb69e8abd68f66b83d5a0b0fdc6d", + "sha256:3b2427ed5791619851c52a1261b45c233930977e7de8cf36de05636c708fa905", + "sha256:3c36e524af1d29982e9b190573677ea02781456b2e537d5840e4538a5ec41907", + "sha256:3d40d46f348c0321df01507f92b95a377240c4ec31985225a6668f10e2676f9a", + "sha256:3e0a700c4b82144b72946b6629968df9762552ee1344bfdb767fecdd634fbd5a", + "sha256:405261b0a8c62bcbd8e2931c26fdc08714faf7025f45531541e2b29e544b545b", + "sha256:41bf25fb39a34cf8edb4398818523277ee7096689db352036a9e8437f2f3ee6b", + "sha256:42d43a1f552be1a112af0b21c10a5f553983c2a0938d2bbb8ecd8bc9fb572803", + "sha256:4806363144bb6e7297b8e95870e78d30a649fdc4e23fc84daa80c8ebd366ce44", + "sha256:525021896afef44a68148f6ed8a8bf8375553d6066c7f48537657f64823565b9", + "sha256:5c3aedecfc1beb988c27c79d52ebefab93b6c3921dbec361167e6559aba2d36d", + "sha256:5c8b2769dc31883c44a9cd126560327767f848eb95f99c36c9932f51090bfce9", + "sha256:5d7feb0741ebb15204e748f26c9638e6665a5fa93c37a2c73d64f1669b0ddc63", + "sha256:5e59d23cd93ada23ec59a96f215139753fbfe3a4d989549bcb390f8c00370b39", + "sha256:600e0e9ca042878c7fdf189cf1b028fe2c1418cc9195f6cb9824eb6ed99cb938", + "sha256:622463ab81d19ef3e06868b576551587de8e4d518892d1afab71e0fbc1f9cffc", + "sha256:624f3951181eb46fc47dea3d221554e98784c823e7069edb5dbd0dc826ac909b", + "sha256:639c3735b8ae7f970066930e58cf0ed39a852d417c24acd4a25fc0b3da3c39a6", + "sha256:65fd2f5730b1bf7f350c6dc896173d3460d235c4be007af73986d7cd9a2acd23", + "sha256:68e44722541983614e37117209a194e8c3ad07838ccb3127d96863c95ec7f1e0", + "sha256:6bb6bb41b14c95d4f2702bce9975fda4516f1db48e500102fc4d8119032ff045", + "sha256:6c13879c0d2964335491463302a6ca5ad98105fc5db3565499dcb80b1b4bd839", + "sha256:6e18a5c15e764e5f3fc569b47872450b4bcea24f2a6354c0a0e95ad21045d5a9", + "sha256:6e3f20be9048941c7ffa8fc523ccbd17f82e24df1549d1d1fe9317712d19938e", + "sha256:724ca721ecc8a831b319dcd72cfa370cc380db0bf94537f08f7edd0a7d4e1780", + "sha256:78b999999039db3cf58f6d230f524f04f75f129ba3d1ca2ed121f8657e575d3d", + "sha256:7bbf9b333f1568ef5da42bc96e18bf30fd7f8d54e9ae066d711056add508e415", + "sha256:80fd082f5dcc0e94657c144f1b2a3a6479c44ad50be216cf0c244e567f5eae19", + "sha256:842289889de515421f3f224ef9c1f1efb199a32d76d8d2ca2706fa8afe749549", + "sha256:87255b88756eab4a68ec61837ca754e5d10fa8bc47dc57f75cedfeaec358d54c", + "sha256:8873812c164a90a79f65368f8f96817e59e35d0cc02786a5356f0e2abed78040", + "sha256:89216ff3dfdde0e4070932e126320a1752c9d9a758d6a32ec54b3b9334991a6a", + "sha256:8e7805fda9672c12be2f22ae124dcd7b03928d6c197544fe12174b86553f3196", + "sha256:94f206766bf1ea30e1382e4890f763bd1eefddc580e08fec1ccdc20ddd95c827", + "sha256:95713e5fc8af84d8edc75b785d2386f653b63d62b16d681687746734b4dfc0be", + "sha256:977c393f2e44845ce1b540e19a786e9643221b3323dae190668a98672d43fb23", + "sha256:97eb5942c7395a171cbfecc4ef6701fc3c403e762194683772df4c54cfbb2210", + "sha256:9daa26ca8e97fae0ce8aa5d80606ef8f7914e9b129b6b5df9104266f764ce436", + "sha256:9fdc3ae730541086158d549c97852e2eea6820665d4faf0f41bf99df41bc11ea", + "sha256:a69ab657a4e6733133a3dca82768f2f8b884043714e8d2b9ba9f52b6efef5c44", + "sha256:a85f0adf63319d6c1ba06fb0dbf997fced64a01179cf17939a6caca662bf92de", + "sha256:aac364c758dc87a52e68e349924d7e4ded348dedff553889e4d9f22f74785316", + "sha256:ad355e8308493f527d41154e9053b86a5be892b3b359a5c6d5d95cda23601cb2", + "sha256:ad73ede24f9083614d6c4ca9a85fe70e33be7bf047ec586ee2363bc7418fe4d7", + "sha256:af02ff34059ee9199a3546f123a6ab4c86caf1708c79042caf0820dc290a6d4f", + "sha256:afb14052690aa328cc118a8e09f07c651d301a72e44920b887c519b313d892ff", + "sha256:b13c478fa413d4b4ee606ec8e11c3b2e52683a640b006bb586b3041c2ca5f606", + "sha256:b58430396687ce0f7d9eeb3dd47761ca7d8fda8e9eb92b3077a7a353a75efefa", + "sha256:bba5118143373a86f91dadb8df41d9457498226698ebdf8e11cbb54d5b0e802d", + "sha256:bfc2a484cad3585e4ba61985a6062a4c2ed5c7925db6d39f1fa267c9d166487f", + "sha256:c6dbf422894e1e3c80a177133c0dda260f81428f9de16d61041949f6a2e5c140", + "sha256:c8a7517482667fb9f0ff1b2f16fe5829296ed7a655d04d68cd9711a4d8a4e708", + "sha256:caa447f2b5356779d914658519c874cf3b7629e99e63391ed519c28c8aea4919", + "sha256:d38d2bc06d6415852224fcc9c0bfa834c25431e466dc319f0edd56cca81aa96e", + "sha256:d4371de39319d05d3f482f372720b841c841b52f5385bd99c61ed69d55d9ab50", + "sha256:d58c166a18f44cc9e2bad03a327dc2d1a3d2e85b847133cfbafd6bfc6719bd79", + "sha256:d5c54a6d76e3d741dcc3f2707f8eeb9ba2a791d3adbf18f900219b62942803b1", + "sha256:d63076d625babab9db5e7836118bdfa086e60f37d8a174194ae720161eb12394", + "sha256:da9e5301f1c2caa2a9a4a303480d79c9ad73560b2e7761de742ab39fe59d9175", + "sha256:e10b4d65901da88845516ce9f7f9736f9638d19a1d483b3883dc0182e6e5edba", + "sha256:e2985ce8b8c42d00492d0ed79f2bd2b6460d00f2fa671dfde4bf2e02f49bf5c6", + "sha256:e2d5d5d798aba9a0e1fede8d853fa899ce2cb930ec0857365f700dffc2c7af6a", + "sha256:e34dbd508cb91c54f9c9788923daca129fe5b55c5b4eebe713bf5ed3791280cf", + "sha256:e3aa2118a3ece0d25489cbe48498de8a5d580e42e8d9979f65bf47900a15aba1", + "sha256:e41fd3b3cac850eaae78232f37325ed7d7436e11c471246b87b2cd294ec94853", + "sha256:f28485bdca8617b79d44627f5fb04336897041dfd9fa66d383a49d09d86798bc", + "sha256:f2cf4dfaf9163b0728d061bebc1e08631875c51cd30bf47cb9e3293bfbd7dcd5", + "sha256:fa9627eba4e82f99ca6d29bc967f09aba446ee2b5a1ea728949ede73d313f5d3", + "sha256:fb1c37c71cad991ef4d89c7a634b5ffb4447dbd7ae3ae13e8f5ee7f1775e7ab1", + "sha256:fb6a03a678085f64b97f9d4a9ae69376ce91a3a9e9b56a82b1580d8e1d501aff" ], "markers": "python_version >= '3.9'", - "version": "==3.11.3" + "version": "==3.11.4" }, "packaging": { "hashes": [ @@ -960,243 +954,228 @@ }, "pillow": { "hashes": [ - "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", - "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", - "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e", - "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", - "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", - "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", - "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06", - "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", - "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", - "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", - "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", - "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", - "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", - "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", - "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", - "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f", - "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", - "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860", - "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", - "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", - "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", - "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4", - "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", - "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", - "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", - "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", - "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", - "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", - "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", - "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967", - "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", - "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", - "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", - "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae", - "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", - "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", - "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f", - "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", - "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", - "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", - "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27", - "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", - "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", - "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", - "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc", - "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", - "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad", - "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", - "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", - "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978", - "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb", - "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", - "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0", - "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9", - "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", - "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", - "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", - "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081", - "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", - "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", - "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", - "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", - "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f", - "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", - "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", - "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", - "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", - "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6", - "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f", - "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", - "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", - "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", - "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", - "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d", - "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", - "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", - "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", - "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", - "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", - "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", - "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", - "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", - "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", - "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", - "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe", - "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a", - "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", - "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", - "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", - "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a", - "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b", - "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", - "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25", - "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", - "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada", - "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c", - "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71", - "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", - "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", - "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", - "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", - "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50", - "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", - "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", - "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", - "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3" + "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", + "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e", + "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", + "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc", + "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642", + "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", + "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1", + "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", + "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", + "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", + "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", + "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", + "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739", + "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", + "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", + "sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10", + "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", + "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", + "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b", + "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", + "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", + "sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d", + "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", + "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", + "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", + "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3", + "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", + "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", + "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", + "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", + "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", + "sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7", + "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", + "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", + "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", + "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d", + "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", + "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", + "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", + "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", + "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a", + "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", + "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", + "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", + "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", + "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b", + "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", + "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", + "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", + "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", + "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", + "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257", + "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", + "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", + "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c", + "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c", + "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", + "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", + "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8", + "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5", + "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", + "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e", + "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", + "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e", + "sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275", + "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", + "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76", + "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227", + "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", + "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", + "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", + "sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca", + "sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa", + "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", + "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", + "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197", + "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", + "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", + "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", + "sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363", + "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", + "sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e", + "sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782", + "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", + "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", + "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", + "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", + "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", + "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", + "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", + "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1" ], - "markers": "python_version >= '3.9'", - "version": "==11.3.0" + "markers": "python_version >= '3.10'", + "version": "==12.0.0" }, "propcache": { "hashes": [ - "sha256:009093c9b5dbae114a5958e6a649f8a5d94dd6866b0f82b60395eb92c58002d4", - "sha256:015b2ca2f98ea9e08ac06eecc409d5d988f78c5fd5821b2ad42bc9afcd6b1557", - "sha256:01c0ebc172ca28e9d62876832befbf7f36080eee6ed9c9e00243de2a8089ad57", - "sha256:02e071548b6a376e173b0102c3f55dc16e7d055b5307d487e844c320e38cacf2", - "sha256:0363a696a9f24b37a04ed5e34c2e07ccbe92798c998d37729551120a1bb744c4", - "sha256:0596d2ae99d74ca436553eb9ce11fe4163dc742fcf8724ebe07d7cb0db679bb1", - "sha256:075ca32384294434344760fdcb95f7833e1d7cf7c4e55f0e726358140179da35", - "sha256:077a32977399dc05299b16e793210341a0b511eb0a86d1796873e83ce47334cc", - "sha256:082a643479f49a6778dcd68a80262fc324b14fd8e9b1a5380331fe41adde1738", - "sha256:087e2d3d7613e1b59b2ffca0daabd500c1a032d189c65625ee05ea114afcad0b", - "sha256:0964c55c95625193defeb4fd85f8f28a9a754ed012cab71127d10e3dc66b1373", - "sha256:0b04ac2120c161416c866d0b6a4259e47e92231ff166b518cc0efb95777367c3", - "sha256:0b12df77eb19266efd146627a65b8ad414f9d15672d253699a50c8205661a820", - "sha256:0cd30341142c68377cf3c4e2d9f0581e6e528694b2d57c62c786be441053d2fc", - "sha256:0ea11fceb31fa95b0fa2007037f19e922e2caceb7dc6c6cac4cb56e2d291f1a2", - "sha256:184c779363740d6664982ad05699f378f7694220e2041996f12b7c2a4acdcad0", - "sha256:1927b78dd75fc31a7fdc76cc7039e39f3170cb1d0d9a271e60f0566ecb25211a", - "sha256:1cdabd60e109506462e6a7b37008e57979e737dc6e7dfbe1437adcfe354d1a0a", - "sha256:1e7fa29c71ffa8d6a37324258737d09475f84715a6e8c350f67f0bc8e5e44993", - "sha256:1e7fd82d4a5b7583588f103b0771e43948532f1292105f13ee6f3b300933c4ca", - "sha256:2015218812ee8f13bbaebc9f52b1e424cc130b68d4857bef018e65e3834e1c4d", - "sha256:213eb0d3bc695a70cffffe11a1c2e1c2698d89ffd8dba35a49bc44a035d45c93", - "sha256:2166466a666a5bebc332cd209cad77d996fad925ca7e8a2a6310ba9e851ae641", - "sha256:227892597953611fce2601d49f1d1f39786a6aebc2f253c2de775407f725a3f6", - "sha256:22f589652ee38de96aa58dd219335604e09666092bc250c1d9c26a55bcef9932", - "sha256:236c8da353ea7c22a8e963ab78cddb1126f700ae9538e2c4c6ef471e5545494b", - "sha256:24403152e41abf09488d3ae9c0c3bf7ff93e2fb12b435390718f21810353db28", - "sha256:26692850120241a99bb4a4eec675cd7b4fdc431144f0d15ef69f7f8599f6165f", - "sha256:2a4bf309d057327f1f227a22ac6baf34a66f9af75e08c613e47c4d775b06d6c7", - "sha256:2af6de831a26f42a3f94592964becd8d7f238551786d7525807f02e53defbd13", - "sha256:2c46d37955820dd883cf9156ceb7825b8903e910bdd869902e20a5ac4ecd2c8b", - "sha256:33ad7d37b9a386f97582f5d042cc7b8d4b3591bb384cf50866b749a17e4dba90", - "sha256:34000e31795bdcda9826e0e70e783847a42e3dcd0d6416c5d3cb717905ebaec0", - "sha256:381c84a445efb8c9168f1393a5a7c566de22edc42bfe207a142fff919b37f5d9", - "sha256:399c73201d88c856a994916200d7cba41d7687096f8eb5139eb68f02785dc3f7", - "sha256:39f0f6a3b56e82dc91d84c763b783c5c33720a33c70ee48a1c13ba800ac1fa69", - "sha256:4596c12aa7e3bb2abf158ea8f79eb0fb4851606695d04ab846b2bb386f5690a1", - "sha256:4a52c25a51d5894ba60c567b0dbcf73de2f3cd642cf5343679e07ca3a768b085", - "sha256:4bf95be277fbb51513895c2cecc81ab12a421cdbd8837f159828a919a0167f96", - "sha256:4c2735d3305e6cecab6e53546909edf407ad3da5b9eeaf483f4cf80142bb21be", - "sha256:4c491462e1dc80f9deb93f428aad8d83bb286de212837f58eb48e75606e7726c", - "sha256:515b610a364c8cdd2b72c734cc97dece85c416892ea8d5c305624ac8734e81db", - "sha256:545987971b2aded25ba4698135ea0ae128836e7deb6e18c29a581076aaef44aa", - "sha256:55a54de5266bc44aa274915cdf388584fa052db8748a869e5500ab5993bac3f4", - "sha256:566552ed9b003030745e5bc7b402b83cf3cecae1bade95262d78543741786db5", - "sha256:5710b1c01472542bb024366803812ca13e8774d21381bcfc1f7ae738eeb38acc", - "sha256:5a531d29d7b873b12730972237c48b1a4e5980b98cf21b3f09fa4710abd3a8c3", - "sha256:5b113feeda47f908562d9a6d0e05798ad2f83d4473c0777dafa2bc7756473218", - "sha256:5e0a5bc019014531308fb67d86066d235daa7551baf2e00e1ea7b00531f6ea85", - "sha256:626ec13592928b677f48ff5861040b604b635e93d8e2162fb638397ea83d07e8", - "sha256:659a0ea6d9017558ed7af00fb4028186f64d0ba9adfc70a4d2c85fcd3d026321", - "sha256:65ff56a31f25925ef030b494fe63289bf07ef0febe6da181b8219146c590e185", - "sha256:681a168d06284602d56e97f09978057aa88bcc4177352b875b3d781df4efd4cb", - "sha256:6a6a36b94c09711d6397d79006ca47901539fbc602c853d794c39abd6a326549", - "sha256:6d1f67dad8cc36e8abc2207a77f3f952ac80be7404177830a7af4635a34cbc16", - "sha256:6ebc6e2e65c31356310ddb6519420eaa6bb8c30fbd809d0919129c89dcd70f4c", - "sha256:71a400b2f0b079438cc24f9a27f02eff24d8ef78f2943f949abc518b844ade3d", - "sha256:71c45f02ffbb8a21040ae816ceff7f6cd749ffac29fc0f9daa42dc1a9652d577", - "sha256:728d98179e92d77096937fdfecd2c555a3d613abe56c9909165c24196a3b5012", - "sha256:72b51340047ac43b3cf388eebd362d052632260c9f73a50882edbb66e589fd44", - "sha256:779aaae64089e2f4992e993faea801925395d26bb5de4a47df7ef7f942c14f80", - "sha256:783e91595cf9b66c2deda17f2e8748ae8591aa9f7c65dcab038872bfe83c5bb1", - "sha256:790286d3d542c0ef9f6d0280d1049378e5e776dcba780d169298f664c39394db", - "sha256:7aa8cc5c94e682dce91cb4d12d7b81c01641f4ef5b3b3dc53325d43f0e3b9f2e", - "sha256:7d51f70f77950f8efafed4383865d3533eeee52d8a0dd1c35b65f24de41de4e0", - "sha256:7da5c4c72ae40fd3ce87213ab057db66df53e55600d0b9e72e2b7f5a470a2cc4", - "sha256:7dfa60953169d2531dd8ae306e9c27c5d4e5efe7a2ba77049e8afdaece062937", - "sha256:7ea86eb32e74f9902df57e8608e8ac66f1e1e1d24d1ed2ddeb849888413b924d", - "sha256:7f088e21d15b3abdb9047e4b7b7a0acd79bf166893ac2b34a72ab1062feb219e", - "sha256:83ae2f5343f6f06f4c91ae530d95f56b415f768f9c401a5ee2a10459cf74370b", - "sha256:84f847e64f4d1a232e50460eebc1196642ee9b4c983612f41cd2d44fd2fe7c71", - "sha256:858eaabd2191dd0da5272993ad08a748b5d3ae1aefabea8aee619b45c2af4a64", - "sha256:8659f995b19185179474b18de8755689e1f71e1334d05c14e1895caa4e409cf7", - "sha256:88d50d662c917ec2c9d3858920aa7b9d5bfb74ab9c51424b775ccbe683cb1b4e", - "sha256:892a072e5b19c3f324a4f8543c9f7e8fc2b0aa08579e46f69bdf0cfc1b440454", - "sha256:8d18d796ffecdc8253742fd53a94ceee2e77ad149eb9ed5960c2856b5f692f71", - "sha256:92bc43a1ab852310721ce856f40a3a352254aa6f5e26f0fad870b31be45bba2e", - "sha256:944de70384c62d16d4a00c686b422aa75efbc67c4addaebefbb56475d1c16034", - "sha256:94a278c45e6463031b5a8278e40a07edf2bcc3b5379510e22b6c1a6e6498c194", - "sha256:94b0f7407d18001dbdcbb239512e753b1b36725a6e08a4983be1c948f5435f79", - "sha256:96153e037ae065bb71cae889f23c933190d81ae183f3696a030b47352fd8655d", - "sha256:9ba68c57cde9c667f6b65b98bc342dfa7240b1272ffb2c24b32172ee61b6d281", - "sha256:a1d5e474d43c238035b74ecf997f655afa67f979bae591ac838bb3fbe3076392", - "sha256:a4efbaf10793fd574c76a5732c75452f19d93df6e0f758c67dd60552ebd8614b", - "sha256:a60634a9de41f363923c6adfb83105d39e49f7a3058511563ed3de6748661af6", - "sha256:a7f06f077fc4ef37e8a37ca6bbb491b29e29db9fb28e29cf3896aad10dbd4137", - "sha256:a8ef2ea819549ae2e8698d2ec229ae948d7272feea1cb2878289f767b6c585a4", - "sha256:a9725d96a81e17e48a0fe82d0c3de2f5e623d7163fec70a6c7df90753edd1bec", - "sha256:ab9c1bd95ebd1689f0e24f2946c495808777e9e8df7bb3c1dfe3e9eb7f47fe0d", - "sha256:abe04e7aa5ab2e4056fcf3255ebee2071e4a427681f76d4729519e292c46ecc1", - "sha256:ae3adf88a66f5863cf79394bc359da523bb27a2ed6ba9898525a6a02b723bfc5", - "sha256:b2f29697d1110e8cdf7a39cc630498df0082d7898b79b731c1c863f77c6e8cfc", - "sha256:b730048ae8b875e2c0af1a09ca31b303fc7b5ed27652beec03fa22b29545aec9", - "sha256:bcb5bfac5b9635e6fc520c8af6efc7a0a56f12a1fe9e9d3eb4328537e316dd6a", - "sha256:bd6c6dba1a3b8949e08c4280071c86e38cb602f02e0ed6659234108c7a7cd710", - "sha256:c0e1c218fff95a66ad9f2f83ad41a67cf4d0a3f527efe820f57bde5fda616de4", - "sha256:c1443fa4bb306461a3a8a52b7de0932a2515b100ecb0ebc630cc3f87d451e0a9", - "sha256:c1ad731253eb738f9cadd9fa1844e019576c70bca6a534252e97cf33a57da529", - "sha256:c20d796210720455086ef3f85adc413d1e41d374742f9b439354f122bbc3b528", - "sha256:c2e274f3d1cbb2ddcc7a55ce3739af0f8510edc68a7f37981b2258fa1eedc833", - "sha256:c3f4b125285d354a627eb37f3ea7c13b8842c7c0d47783581d0df0e272dbf5f0", - "sha256:c9b8119244d122241a9c4566bce49bb20408a6827044155856735cf14189a7da", - "sha256:cd6e22255ed73efeaaeb1765505a66a48a9ec9ebc919fce5ad490fe5e33b1555", - "sha256:cd8684f628fe285ea5c86f88e1c30716239dc9d6ac55e7851a4b7f555b628da3", - "sha256:cdb0cecafb528ab15ed89cdfed183074d15912d046d3e304955513b50a34b907", - "sha256:d74aa60b1ec076d4d5dcde27c9a535fc0ebb12613f599681c438ca3daa68acac", - "sha256:d7f008799682e8826ce98f25e8bc43532d2cd26c187a1462499fa8d123ae054f", - "sha256:d9a8d277dc218ddf04ec243a53ac309b1afcebe297c0526a8f82320139b56289", - "sha256:da47070e1340a1639aca6b1c18fe1f1f3d8d64d3a1f9ddc67b94475f44cd40f3", - "sha256:da584d917a1a17f690fc726617fd2c3f3006ea959dae5bb07a5630f7b16f9f5f", - "sha256:de536cf796abc5b58d11c0ad56580215d231d9554ea4bb6b8b1b3bed80aa3234", - "sha256:de8e310d24b5a61de08812dd70d5234da1458d41b059038ee7895a9e4c8cae79", - "sha256:df7107a91126a495880576610ae989f19106e1900dd5218d08498391fa43b31d", - "sha256:e0ce7f3d1faf7ad58652ed758cc9753049af5308b38f89948aa71793282419c5", - "sha256:e2d01fd53e89cb3d71d20b8c225a8c70d84660f2d223afc7ed7851a4086afe6d", - "sha256:e5227da556b2939da6125cda1d5eecf9e412e58bc97b41e2f192605c3ccbb7c2", - "sha256:e6229ad15366cd8b6d6b4185c55dd48debf9ca546f91416ba2e5921ad6e210a6", - "sha256:e878553543ece1f8006d0ba4d096b40290580db173bfb18e16158045b9371335", - "sha256:eb77a85253174bf73e52c968b689d64be62d71e8ac33cabef4ca77b03fb4ef92", - "sha256:f114a3e1f8034e2957d34043b7a317a8a05d97dfe8fddb36d9a2252c0117dbbc", - "sha256:f495007ada16a4e16312b502636fafff42a9003adf1d4fb7541e0a0870bc056f", - "sha256:f5c82af8e329c3cdc3e717dd3c7b2ff1a218b6de611f6ce76ee34967570a9de9" + "sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e", + "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", + "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", + "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", + "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", + "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", + "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", + "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", + "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", + "sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888", + "sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37", + "sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8", + "sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60", + "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", + "sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4", + "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", + "sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7", + "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", + "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", + "sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb", + "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", + "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", + "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", + "sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff", + "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", + "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", + "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", + "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", + "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", + "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", + "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", + "sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc", + "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", + "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", + "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", + "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", + "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", + "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", + "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", + "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", + "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", + "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", + "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", + "sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5", + "sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938", + "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", + "sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925", + "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", + "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", + "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", + "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", + "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", + "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", + "sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0", + "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", + "sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db", + "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", + "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", + "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", + "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", + "sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900", + "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", + "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", + "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", + "sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f", + "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", + "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", + "sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183", + "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", + "sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21", + "sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db", + "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", + "sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb", + "sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19", + "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", + "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", + "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", + "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", + "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", + "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", + "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", + "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", + "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", + "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", + "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", + "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", + "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", + "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", + "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", + "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", + "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", + "sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac", + "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", + "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", + "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", + "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", + "sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581", + "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", + "sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00", + "sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a", + "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", + "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", + "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", + "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", + "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", + "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", + "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", + "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", + "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", + "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", + "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", + "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", + "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", + "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", + "sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c", + "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", + "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", + "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", + "sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f", + "sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88", + "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", + "sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781" ], "markers": "python_version >= '3.9'", - "version": "==0.4.0" + "version": "==0.4.1" }, "pycares": { "hashes": [ @@ -1309,80 +1288,80 @@ "srv" ], "hashes": [ - "sha256:024e735127e7f39763eb3043c628a857cbf6cdfabd9bf5a1825f3597bab74352", - "sha256:03bd7284fd299c7df09cebeb53f3251e0b4850fba71bf63cbbff1ddf20cc569d", - "sha256:05b9eab3bc049f8fd150869375eff3a85ceab606531b6226b60f054daf7d1368", - "sha256:05e96219d1acca15643042478103241771e46a3f5331bae3e19d2ea2756968b1", - "sha256:0ad7ec297e8999b0f984c998e2c1c605f11e9b8c7682256bbbc53c24a195f76e", - "sha256:1393e7e9d2fc291e0d72f8583ef58e1999e84f7cd01d5a72db53b4ed1ae44686", - "sha256:18bc73e47d21cabfde719d0cc5aa6b556856993397c9433d934089c86732e3d3", - "sha256:1b5c61e32c6afbf35a9c6638db892f75dc53ebcd45a9a1bf992ffff0ec28aaaa", - "sha256:1db14e952ceb574cb8acacf063040e2a6e9570bd50671fa903fb47adb7cf49cc", - "sha256:1f2af4b98fc6d54489d187c0faa12bfbf0ef6c56c3e735eeb837ac8ff235b490", - "sha256:20ee2722ac45fba2c502edbc5281b6efcd8601d94ae1900a48c106459a1715d7", - "sha256:21b1d1d33bdbc87c1a082b747aa9ab40a30638c4e58e799d8fe9f5cb15feb38f", - "sha256:22ad78ac0222b8c5f5a28cdf6300cf19481fff193110506768c9915c8cd3396b", - "sha256:29645a9a8166f20b3fc6aa05095af6caf8ee9af9a4cf23cd857576084e29cc9c", - "sha256:2968cf01e2257f2f5193aba259116c1e9e56f739a16eceef36e85a55edc91604", - "sha256:2b6c8588b04e304bb4670e5409b3def2d9daedb8f719d47780a59de7227f1d3f", - "sha256:2c816a9e9d4aaaa0e4e9fb2534b72957666d262f3ce874a0408f8b925cfd4d99", - "sha256:2daa9434828a5e5638b9d78f0031c9e19b5bc84ce9f5e69cf6083f58aa3e3901", - "sha256:2fad596a092ab9cd821c98d75b48dd6a9c3fc52df8b1453d2f10d8219676269a", - "sha256:338b29d89f92c665a1038d53c7cc68869e2a04e171dd4fb2d416d7ad263dc50a", - "sha256:38785ba507a019edb742e333c6bf2fa3644043f1ce79ef4d20a4f7bb2180ee74", - "sha256:3ab5ba56b868c56a38cfeb3202ee78dcdd4152bc364d24b71aaf1ee3994c7f96", - "sha256:3dc0ec9d78d4f28a24bd965e06c0a77459086522005aa199a8e4fc652ed1ce8e", - "sha256:3fafe5ef96943ab9b837f89b6abe779951102bee44d21c743259d43cfc1d9f6e", - "sha256:42acd45f7030743eed3d5e66a03dd3e9c12c7869301d123bffa1f71dc0e3f882", - "sha256:45103766c3f1bf1f5fc2da43a48dbe03a343389a334eb1d02ef39024957cdc91", - "sha256:475a97d48be850140f2455ed4a2a9920f70538b0824c53ffa5deeb940f49fdb3", - "sha256:50307e2403f0cfdf4fd0f5c6c9a45edbb4c5fa63196e1671b7fed5bbcd884109", - "sha256:50325282876a263ece78371319e78518dd034e434c11e3ab12402547292b8fd5", - "sha256:557611de3fa33bd5b8e5d38a7056b15d5c38361af50378ff5cf8b9cbf371913b", - "sha256:587202db4a64d5c091bc39695095af461a6a08b2a52ddd881a6e5cb34244d672", - "sha256:597dce90bc607b3180735a6692abcf75c111d7f6169b2b1cca1db85086ee980c", - "sha256:5b72de1a2f8cc52561c65a5062ade72e06da76e0899d4f11ae1c1bced1534ff8", - "sha256:5fa558bc6320e1183965db06e069973c9642b971a37729a8ae23c37f1c13ce21", - "sha256:6462763611c5fb97b56fcd3a62c325bc8111c686c7768f50668882d21b4f28f4", - "sha256:68fbc920409bd96e6a63b651254baa45e27473c4b73232a3fb5662279383a622", - "sha256:69515e1042a2fb4fadf6384918be34703aa2c792b9a8d3d406ad43e07cb095a2", - "sha256:6d797730d07bff953d05693e75d9575e7357739a5eb2747521987d2f99b9899f", - "sha256:7089a1f2d5883f5137f1c2766691db904741985bb7e7a400ed50c3b370507b17", - "sha256:7466840413fbd23605e9f95b702374b061525e85ea7f47dca6a88981455490ec", - "sha256:75f6f8363a57ba8a6bb1076114dc9aa29336f525c8b621cc1e4cfccae4ff546a", - "sha256:76c1c013bc577c7fb2c9a69d52ee335672eac1bdbfb9c37a432bb155bc69ffdc", - "sha256:780447f9112f0e57d821ced8d593657b45616f3821becb0740e6c0fc38b0e91e", - "sha256:82ba58edb6f6112aac543214ac22fc8e3d569372a7b3a180511cf4a70bd4c0ef", - "sha256:9fa833908d94b5869e6c9a53b778dc8235caca6fcda03aac8410b8f067cd8a6f", - "sha256:a15ad3f11556a30e5dd86344567e85eb46550b09e0ea8d3297476788f0c76d77", - "sha256:a244e27c034707f48f979fdcebe0df47ea000fd52ee1b2b2d2d2cb5b7b0e24dd", - "sha256:a33e118e14bd350bef6127a000c8d08e6bade8b9045bcd70d09a665434035705", - "sha256:a42ad84dfab44218f264e2d68b79e0e684c03c66fe8180a7961d6eb670eec4a3", - "sha256:a4a0d3cf68f9bf84a7ee737ba0b29265cfeeaf586a856c6d7773491c545e5230", - "sha256:a775371086ff63da1ae97f676bcb5556c86e4e281ccac998d49d6e24efa50ca1", - "sha256:a98f67df7aae325c0476aa453877475f9a1160f84b7e6e24e4804498ef99178e", - "sha256:a994b40542ba44748af9e382fd54e69428f40c1728ae06bc649c87a1135d1cfb", - "sha256:b5fe426128a03393d2e7f10169e1f10cf6a6355f40876f52b51a03721c12e6e5", - "sha256:bf646006bfce5e153cc838adaee319ff8a3d625978d491208cc290e89f9c2a21", - "sha256:c434219d66bf20f46011cc11b28e0dbfeb965f7a7cfd1e4b8e733a5f642ae1c2", - "sha256:c95a8d0ca11d16e325749fbd9f7d9aeb9a90241245e419007a941f446ff94dd6", - "sha256:cedfd1be19c8f7b41a1f5fbaea299303087b5d40605e956ffbcfe2adc76de0ec", - "sha256:d54b8139979e6e2ee6fec91b189e948ee2d83f125957793cf191c5e33be567e7", - "sha256:d9410537204bb9e83f1c5e43f6e5df2c0d3fe092dbd8d30bd883736818a6d786", - "sha256:ddf9face1dadf4cce4578dda29547ca2af6df09d44e7dd1bd6fe185f7c18dfc9", - "sha256:de0c88d7229a96a5bfe2827170578bcd871ee16843c47e5cb3290edf1aaf62ca", - "sha256:dece75a28450fa813040b13f7fbe80a614d02e04f7ff84255a2600c440bf227a", - "sha256:e6a22f0349142c92bb2ccbd35a8a0b7dc5a2eeac14217fb28cfa9956bcfee139", - "sha256:eb1423432631994d965e92ee63e448627d57793fd780c56c49570f12d4be1ff4", - "sha256:ebd6f6eed7c6c92af3d3fa375ecd0e730da628c59a95aca5b2445fbb3d1eb874", - "sha256:ee0ab602d309c6f903c002f8705b92459d885349f1f9561040f34a2a06c84891", - "sha256:f03716cfd4c86e3a8537ab8e1169cec26d532cc70fcd02e30027820ac587d28b", - "sha256:f5bfbde2ccc88b96d56cdc6bd104b856d9b039aa209b491311f8012e611d9f58", - "sha256:f736f1a6d85f3b1c182018ae0e6c387bb342935e3b97637c258b9b46e0509af2", - "sha256:f9d3bbb4741a6ab81dbcd73b0754725f304b118c4c738449639fd060ee8b5da9" + "sha256:07bcc36d11252f24fe671e7e64044d39a13d997b0502c6401161f28cc144f584", + "sha256:09440e78dff397b2f34a624f445ac8eb44c9756a2688b85b3bf344d351d198e1", + "sha256:1246a82fa6dd73ac2c63aa7e463752d5d1ca91e0c7a23396b78f21273befd3a7", + "sha256:17d13458baf4a6a9f2e787d95adf8ec50d412accb9926a044bd1c41029c323b2", + "sha256:17fc94d1e067556b122eeb09e25c003268e8c0ea1f2f78e745b33bb59a1209c4", + "sha256:1f681722c9f27e86c49c2e8a838e61b6ecf2285945fd1798bd01458134257834", + "sha256:21c0a95a4db72562fd0805e2f76496bf432ba2e27a5651f4b9c670466260c258", + "sha256:292fd5a3f045751a823a54cdea75809b2216a62cc5f74a1a96b337db613d46a8", + "sha256:2c96dde79bdccd167b930a709875b0cd4321ac32641a490aebfa10bdcd0aa99b", + "sha256:2f3d66f7c495efc3cfffa611b36075efe86da1860a7df75522a6fe499ee10383", + "sha256:2fd3b99520f2bb013960ac29dece1b43f2f1b6d94351ca33ba1b1211ecf79a09", + "sha256:300eaf83ad053e51966be1839324341b08eaf880d3dc63ada7942d5912e09c49", + "sha256:3561fa96c3123275ec5ccf919e595547e100c412ec0894e954aa0da93ecfdb9e", + "sha256:390c4954c774eda280898e73aea36482bf20cba3ecb958dbb86d6a68b9ecdd68", + "sha256:39a13d8f7141294404ce46dfbabb2f2d17e9b1192456651ae831fa351f86fbeb", + "sha256:446417a34ff6c2411ce3809e17ce9a67269c9f1cb4966b01e49e0c590cc3c6b3", + "sha256:45aebbd369ca79b7c46eaea5b04d2e4afca4eda117b68965a07a9da05d774e4d", + "sha256:47ffb068e16ae5e43580d5c4e3b9437f05414ea80c32a1e5cac44a835859c259", + "sha256:482ca9b775747562ce1589df10c97a0e62a604ce5addf933e5819dd967c5e23c", + "sha256:49fd6e158cf75771b2685a8a221a40ab96010ae34dd116abd06371dc6c38ab60", + "sha256:4a0a054e9937ec8fdb465835509b176f6b032851c8648f6a5d1b19932d0eacd6", + "sha256:52f40c4b8c00bc53d4e357fe0de13d031c4cddb5d201e1a027db437e8d2887f8", + "sha256:58d0f4123855f05c0649f9b8ee083acc5b26e7f4afde137cd7b8dc03e9107ff3", + "sha256:5bf879a6ed70264574d4d8fb5a467c2a64dc76ecd72c0cb467c4464f849c8c77", + "sha256:5c78237e878e0296130e398151b0d4aa6c9eaf82e38fb6e0aaae2029bc7ef0ce", + "sha256:5c85a4c72b7965033f95c94c42dac27d886c01dbc23fe337ccb14f052a0ccc29", + "sha256:5f6feb678f26171f2a6b2cbb340949889154c7067972bd4cc129b62161474f08", + "sha256:6a054d282dd922ac400b6f47ea3ef58d8b940968d76d855da831dc739b7a04de", + "sha256:71413cd8f091ae25b1fec3af7c2e531cf9bdb88ce4079470e64835f6a664282a", + "sha256:76a8d4de8dceb69f6e06736198ff6f7e1149515ef946f192ff2594d2cc98fc53", + "sha256:77353978be9fc9e5fe56369682efed0aac5f92a2a1570704d62b62a3c9e1a24f", + "sha256:7a981271347623b5319932796690c2d301668ac3a1965974ac9f5c3b8a22cea5", + "sha256:7c0fd3de3a12ff0a8113a3f64cedb01f87397ab8eaaffa88d7f18ca66cd39385", + "sha256:7dd2a49f088890ca08930bbf96121443b48e26b02b84ba0a3e1ae2bf2c5a9b48", + "sha256:82a490f1ade4ec6a72068e3676b04c126e3043e69b38ec474a87c6444cf79098", + "sha256:86b1b5b63f4355adffc329733733a9b71fdad88f37a9dc41e163aed2130f9abc", + "sha256:89e45d7fa987f4e246cdf43ff001e3f911f73eb19ba9dabc2a6d80df5c97883b", + "sha256:8bd6dd736f5d07a825caf52c38916d5452edc0fac7aee43ec67aba6f61c2dbb7", + "sha256:8d4b01a48369ea6d5bc83fea535f56279f806aa3e4991189f0477696dd736289", + "sha256:90ad56bd1d769d2f44af74f0fd0c276512361644a3c636350447994412cbc9a1", + "sha256:9483521c03f6017336f54445652ead3145154e8d3ea06418e52cea57fee43292", + "sha256:959ef69c5e687b6b749fbf2140c7062abdb4804df013ae0507caabf30cba6875", + "sha256:97f9babdb98c31676f97d468f7fe2dc49b8a66fb6900effddc4904c1450196c8", + "sha256:982107c667921e896292f4be09c057e2f1a40c645c9bfc724af5dd5fb8398094", + "sha256:9897a837677e3814873d0572f7e5d53c23ce18e274f3b5b87f05fb6eea22615b", + "sha256:9b03db2fe37c950aff94b29ded5c349b23729bccd90a0a5907bbf807d8c77298", + "sha256:9bc9f99e7702fdb0dcc3ff1dd490adc5d20b3941ad41e58f887d4998b9922a14", + "sha256:9df2db6bd91b07400879b6ec89827004c0c2b55fc606bb62db93cafb7677c340", + "sha256:a47a3218f7900f65bf0f36fcd1f2485af4945757360e7e143525db9d715d2010", + "sha256:b33d59bf6fa1ca1d7d96d4fccff51e41312358194190d53ef70a84c070f5287e", + "sha256:b3a0ec660d61efb91c16a5962ec937011fe3572c4338216831f102e53d294e5c", + "sha256:b63bac343b79bd209e830aac1f5d9d552ff415f23a924d3e51abbe3041265436", + "sha256:bd0497c564b0ae34fb816464ffc09986dd9ca29e2772a0f7af989e472fecc2ad", + "sha256:c4fdd8e6eab8ff77c1c8041792b5f760d48508623cd10b50d5639e73f1eec049", + "sha256:c57dad9f289d72af1d7c47a444c4d9fa401f951cedbbcc54c7dd0c2107d6d786", + "sha256:c7eb497519f42ac89c30919a51f80e68a070cfc2f3b0543cac74833cd45a6b9c", + "sha256:cfa4a0a0f024a0336640e1201994e780a17bda5e6a7c0b4d23841eb9152e868b", + "sha256:d09d895c7f08bcbed4d2e96a00e52e9e545ae5a37b32d2dc10099b205a21fc6d", + "sha256:d2d4ca446348d850ac4a5c3dc603485640ae2e7805dbb90765c3ba7d79129b37", + "sha256:d66da207ccb0d68c5792eaaac984a0d9c6c8ec609c6bcfa11193a35200dc5992", + "sha256:dc583a1130e2516440b93bb2ecb55cfdac6d5373615ae472a9d1f26801f58749", + "sha256:dcff15b9157c16bc796765d4d3d151df669322acfb0357e4c3ccd056153f0ff4", + "sha256:de3bc878c3be54ae41c2cabc9e9407549ed4fec41f4e279c04e840dddd7c630c", + "sha256:e7cde58ef6470c0da922b65e885fb1ffe04deef81e526bd5dea429290fa358ca", + "sha256:e84dec392cf5f72d365e0aac73f627b0a3170193ebb038c3f7e7df11b7983ee7", + "sha256:f6b0513e5765fdde39f36e6a29a36c67071122b5efa748940ae51075beb5e4bc", + "sha256:fae552767d8e5153ed498f1bca92d905d0d46311d831eefb0f06de38f7695c95", + "sha256:fb384623ece34db78d445dd578a52d28b74e8319f4d9535fbaff79d0eae82b3d", + "sha256:fe4bcb8acfb288e238190397d4a699aeb4adb70e8545a6f4e44f99d4e8096ab1", + "sha256:ff99864085d2c7f4bb672c7167680ceb7d273e9a93c1a8074c986a36dbb71cc6", + "sha256:ffe217d2502f3fba4e2b0dc015ce3b34f157b66dfe96835aa64432e909dd0d95" ], "markers": "python_version >= '3.9'", - "version": "==4.15.2" + "version": "==4.15.3" }, "python-dateutil": { "hashes": [ @@ -1427,6 +1406,14 @@ "markers": "python_version >= '3.8'", "version": "==1.4.0" }, + "typing-extensions": { + "hashes": [ + "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", + "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" + ], + "markers": "python_version >= '3.9'", + "version": "==4.15.0" + }, "urllib3": { "hashes": [ "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", @@ -1437,46 +1424,58 @@ }, "uvloop": { "hashes": [ - "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", - "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", - "sha256:10da8046cc4a8f12c91a1c39d1dd1585c41162a15caaef165c2174db9ef18bdc", - "sha256:17df489689befc72c39a08359efac29bbee8eee5209650d4b9f34df73d22e414", - "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", - "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", - "sha256:221f4f2a1f46032b403bf3be628011caf75428ee3cc204a22addf96f586b19fd", - "sha256:2d1f581393673ce119355d56da84fe1dd9d2bb8b3d13ce792524e1607139feff", - "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", - "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", - "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", - "sha256:460def4412e473896ef179a1671b40c039c7012184b627898eea5072ef6f017a", - "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", - "sha256:46923b0b5ee7fc0020bef24afe7836cb068f5050ca04caf6b487c513dc1a20b2", - "sha256:53e420a3afe22cdcf2a0f4846e377d16e718bc70103d7088a4f7623567ba5fb0", - "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", - "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", - "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", - "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", - "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", - "sha256:88cb67cdbc0e483da00af0b2c3cdad4b7c61ceb1ee0f33fe00e09c81e3a6cb75", - "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", - "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", - "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", - "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", - "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", - "sha256:bc09f0ff191e61c2d592a752423c767b4ebb2986daa9ed62908e2b1b9a9ae206", - "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", - "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", - "sha256:c097078b8031190c934ed0ebfee8cc5f9ba9642e6eb88322b9958b649750f72b", - "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", - "sha256:e678ad6fe52af2c58d2ae3c73dc85524ba8abe637f134bf3564ed07f555c5e79", - "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", - "sha256:f0ce1b49560b1d2d8a2977e3ba4afb2414fb46b86a1b64056bc4ab929efdafbe", - "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", - "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", - "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2" + "sha256:017bd46f9e7b78e81606329d07141d3da446f8798c6baeec124260e22c262772", + "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", + "sha256:05e4b5f86e621cf3927631789999e697e58f0d2d32675b67d9ca9eb0bca55743", + "sha256:0ae676de143db2b2f60a9696d7eca5bb9d0dd6cc3ac3dad59a8ae7e95f9e1b54", + "sha256:1489cf791aa7b6e8c8be1c5a080bae3a672791fcb4e9e12249b05862a2ca9cec", + "sha256:17d4e97258b0172dfa107b89aa1eeba3016f4b1974ce85ca3ef6a66b35cbf659", + "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", + "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", + "sha256:286322a90bea1f9422a470d5d2ad82d38080be0a29c4dd9b3e6384320a4d11e7", + "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", + "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", + "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", + "sha256:3b7f102bf3cb1995cfeaee9321105e8f5da76fdb104cdad8986f85461a1b7b77", + "sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733", + "sha256:481c990a7abe2c6f4fc3d98781cc9426ebd7f03a9aaa7eb03d3bfc68ac2a46bd", + "sha256:4a968a72422a097b09042d5fa2c5c590251ad484acf910a651b4b620acd7f193", + "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", + "sha256:512fec6815e2dd45161054592441ef76c830eddaad55c8aa30952e6fe1ed07c0", + "sha256:51eb9bd88391483410daad430813d982010f9c9c89512321f5b60e2cddbdddd6", + "sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473", + "sha256:53c85520781d84a4b8b230e24a5af5b0778efdb39142b424990ff1ef7c48ba21", + "sha256:55502bc2c653ed2e9692e8c55cb95b397d33f9f2911e929dc97c4d6b26d04242", + "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", + "sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702", + "sha256:57df59d8b48feb0e613d9b1f5e57b7532e97cbaf0d61f7aa9aa32221e84bc4b6", + "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", + "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", + "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", + "sha256:700e674a166ca5778255e0e1dc4e9d79ab2acc57b9171b79e65feba7184b3370", + "sha256:7b5b1ac819a3f946d3b2ee07f09149578ae76066d70b44df3fa990add49a82e4", + "sha256:7cd375a12b71d33d46af85a3343b35d98e8116134ba404bd657b3b1d15988792", + "sha256:80eee091fe128e425177fbd82f8635769e2f32ec9daf6468286ec57ec0313efa", + "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", + "sha256:a592b043a47ad17911add5fbd087c76716d7c9ccc1d64ec9249ceafd735f03c2", + "sha256:ac33ed96229b7790eb729702751c0e93ac5bc3bcf52ae9eccbff30da09194b86", + "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", + "sha256:b45649628d816c030dba3c80f8e2689bab1c89518ed10d426036cdc47874dfc4", + "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", + "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", + "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", + "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", + "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", + "sha256:c3e5c6727a57cb6558592a95019e504f605d1c54eb86463ee9f7a2dbd411c820", + "sha256:c60ebcd36f7b240b30788554b6f0782454826a0ed765d8430652621b5de674b9", + "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", + "sha256:e047cc068570bac9866237739607d1313b9253c3051ad84738cbb095be0537b2", + "sha256:ea721dd3203b809039fcc2983f14608dae82b212288b346e0bfe46ec2fab0b7c", + "sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c", + "sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42" ], "markers": "sys_platform != 'win32'", - "version": "==0.21.0" + "version": "==0.22.1" }, "webencodings": { "hashes": [ @@ -1487,131 +1486,139 @@ }, "yarl": { "hashes": [ - "sha256:019c2798df9d74fe8fb9cc916702966dad7e2e3eef66b4c19f8084ba5e0b6ecd", - "sha256:01ef0d7f1dd60d241529dc79a3fa647451056394f9a5ed05fbceeb5009de6122", - "sha256:028c59136b65fccfe5578520a3fb2a94e06601c545ca0125b7e07b3a39f238a5", - "sha256:0416fde6dc89866f4ff494a0ffcc4b2da984cf61aaa279c14a53495e8520c809", - "sha256:056fc431f10ae35aa2375c9de2b68176b34f54fb7de8bc2e830564e2a3d29efa", - "sha256:069cfc781f5d68389c8a4228f720cab453e1b6fa606bcd710a9cc01e38ffe2c1", - "sha256:06c71f698ac5b5bfdde1ce3d58d262235b3c1109f083286c96c01cee64ebf705", - "sha256:0a9454d4c513a3aa2fd87471126e0d32b01f1bf58d49309a84431521488b30c4", - "sha256:0a94664fe3c6dd44c36e875af0f338769dc9f80a1ccd58f53cf5f5b8341e8627", - "sha256:0aaa36261a1279b03fa0655a9bd879cc42e06406adaae0150fde25c778393fcb", - "sha256:0ab4e81b455dd8beb2537648be972eb63351bbe34fb55457054392fee759ac9c", - "sha256:0b16c889a7168ecf7242946dec013c9fb82ade70ab8e6b5d3290383390083a2b", - "sha256:0cc3eeea8f527119aac1b0c874bbb8092675da85fd6d9d91946cf7be7d59477b", - "sha256:0d37bf6f601c714b536159715d9ec6e69bf8a94dc593abe54c1b43ac339eb5e7", - "sha256:0e485c4f9f5b5b9fc10b4bb0ba5baf145ed0a702756da126c9f62f8a89b391a8", - "sha256:10580c7d9b50c883b93cc0ab5c91df5cc1e5b18713736471d622776b01c36810", - "sha256:1107b93c32cf7d7e2ece9bbb1b1820ecb923cfea24c8aa599a309434ed37d707", - "sha256:13c9b91e2e1224a8d33addc1bd58bb097396519c4c49524843947776b8dd45da", - "sha256:140402fef1f482840fcd4d2ee9bfd07f08bfb2c80dd215220bd47f6f3566b882", - "sha256:14872677213d96552268f927982d4c83f5d0674b0d54b623d8e909710460ab14", - "sha256:16957642c0594feba56a4bb430eea5f9132bb589ebb8b4740c0d47f022a5d976", - "sha256:1743d35529a8b9b2b6a9e5f00076c2c146726453051621b739b081dda382ee70", - "sha256:1754b3380ffef931b8eae3bbe6fc0b249db56294ffeb6e6124c2d031a82a3a92", - "sha256:178860382595f3b1fab2596b19570adc495c6211eee8b10a4112ce96342f6515", - "sha256:18e8272a4166d2bb68d51f86445f061aac21fcfc9c1d5b1187f9703f362d85dd", - "sha256:190356a39fed15109ab95600f8ff59c1a0665625f4cfe910388c82b965edaf87", - "sha256:19df967a905f2f9a09733dfb397baa6807772502931000f881943d7cfc6e9f47", - "sha256:1a0ba7cd4eabb7433e69737f33333d9e79d8ab6dbaa2f4d7313ad6611200cc65", - "sha256:1b5d29c1a86cc63e55f69253b8c817091884c4e1b79ee762a8643de834e70a64", - "sha256:1bff86850033508af0a7f9973ced23a16de7ba4ce30521080e2330475b8711b5", - "sha256:1e0b01fa225ec12e54c73be383326ae2a4a59a4a465a0e6cac679f314ed85d1f", - "sha256:20b2dca6588f65b5def8e8eae4a087d504eacf34b5b435c021cc233ce82f6c15", - "sha256:212a5c72d551f94b7799b5de1cc55ddcf3c69ac462f7c0df1beee7e47edb9fef", - "sha256:221aa7c16055e8b9f2eba718cbbf10f174e47f02e659156804d9679654c5cbb0", - "sha256:2227fcc88bebdc90ed87d924bdf8a76a730fc91796641e41ca747aabd13a5074", - "sha256:2584651c047718ec4a863ee81a5432f6f68974e6f0c58975f0aab408ff839798", - "sha256:26940710eece6b5b08a108e81d6325b47610990cd8bb28886e27d4a0d6d60930", - "sha256:2a05a5e018de23c4d2d75c8fbd8b58aba5199f752326f60a22aa37ef28d987bd", - "sha256:2b2f8e0bbdf49530ed09b2bc988082cab6ce24f4c49a0efd2ff5d9477cb29084", - "sha256:2b841c5529f9ca28cf23ed34c8040547ca6530b968a482c14de96a6ade470ee5", - "sha256:30b6a56388963ebe5428d835112439563bcaa9c8349742aeac68a8ad5a231221", - "sha256:37b5e7bba1f6df45058cff626c83a0e8a1259363095e768046a3da40b24e9c4f", - "sha256:3b539230fd64f283594a56633a9751d299cde5ab9c2791452ccb47a865842fa8", - "sha256:3cbae81bff4014ca7745fa11f7015f784198fadba8935cf5a71e139b0b124ff0", - "sha256:430e162d961af58f3dcac58aed038ba974ec7a73803ac6545db2338fbd0f4ed3", - "sha256:45aa7711e1933bac1679f9534f112767f1fe64c97a8576294b760015d0fb65e7", - "sha256:45f17adf1b8bc56becb1bc38f293b1714866786c9d79e245fb3d3731788622a6", - "sha256:4b449296e2ba009481385349138130f209bb502c4f890b3298bf3ea13d43a6d5", - "sha256:4d5af10c9f580002c0ea6c8f345c8cadb2e0c53dce77d3f2639b9e31e5f24d3d", - "sha256:4ee80f79c928ce7c18cf3ad18a5da7f3f0f1b08923e08d87143d628a6d5d2dba", - "sha256:4fcce63c1117ef0630a92a0bda3028a96dc17feed2c78c713de4c963d13d1881", - "sha256:5110ebfe3cbf892b41590fcf4aa70a17ac0a5e9a73b4a8945010bdb970ff1b93", - "sha256:52a8b7541c5d8240ae32d12014f8448e29e1ae794f9443ea020b926cff8691e1", - "sha256:56ead8d62b346c1ec67a6e8b2f66885180ea5bec05821d309ac1cb99ff4aacf5", - "sha256:5c0123db2d86d169554d5fb19421e8e455efcfe2e8e254328b85c77e712ab506", - "sha256:5e7d24e9c3b638f046fcd9a5374818257a8c6d1c3fc7542887521b81a970fbc2", - "sha256:6074904025bc462b0b3f7230b36d8942d9a611b783ce1431ade5ad6a8867b73d", - "sha256:60dcb45a3d762460ac5014755c190db36acf127f68d68643cde7d6d7ce0e5627", - "sha256:61bf6233d04ccba7906f5261ff3628fa97a68fc526cda3d9dd092d2f49926933", - "sha256:63157d66cf7682dec8b3117491cb87a5d8e1cd56df59156d5553ab9721895d19", - "sha256:6378871775e0feb225693cbdad3d997327af0ab4c7e39d93849008c73b867134", - "sha256:6614325ef69d8a53c731ed5e4bd55449ffc5fe86ad652789c0afc853099662ad", - "sha256:66248832212957d8bad28e8d9d307be1d987b94ffaf7e7cca658a349d52d3572", - "sha256:692603a8f82e7baa86bb3921d5002b711788cec547b626030f1f6cf017290ab7", - "sha256:701cd0ee20fe9087c21229db579f2222a75c229b44840a7df7b2d795522068c3", - "sha256:7331a7d2683e644b7830c924ac634fa3ec52257f5098f6415d8ad765d6bc29a8", - "sha256:74b2e94d3e410ed49c7a4cb2c3a5089a6632f7ab68e49bb612b972577e26e771", - "sha256:780313d2a1877adef0e3839ef9596ad53ab640715e7f453e7304c121cd7f262d", - "sha256:7a9d0efd6ff6f4f55ff7a37852e4fcdc24b1feb3b09e204df3dda990171fe725", - "sha256:7b7d46a6ca781a336c7317d9c1d381bebb3b0da5309c2293dd1c4fe3d62942bf", - "sha256:7d271fed8a4b46723db5001619c36192d94a3bd49d76ef186f13abb6897ff8e5", - "sha256:7d5d8eeb1051fac562d80aad7b6b496e2901f41fc2b0988c61016a1426996f66", - "sha256:7d8917677a64304db00ec46629aff335c935c788a10a164b29464b7e2d707463", - "sha256:7da21f0d9bebdc8ac1dde69b3c0951b339984883e2a751790f0f72cbfd1dd007", - "sha256:863d7401d3a109f75c7a5ca0e33e8fb7704a61007f4bda03e08e05f3bf1af40f", - "sha256:866c17223f7d734377a260a2800e14791cb5e55ec252de624e053a0b36b8568a", - "sha256:884d4f3509dfc810299d14faed24c0fbcac82ae2a9737b0cb1d8f7a5e8a291f8", - "sha256:88ff0c0bea02ce78af8a91b173fb43aad5f1945221182f77ba7816fd01bcbc4c", - "sha256:8910f022242c0a15f6d77d781c6ba16bb88d9fed3bff8964de652ee2580029ac", - "sha256:8bfdb95a85404a943197264461b904a2e9e228fd28cb86e4e57321f5b4d5be07", - "sha256:8d39e71705dccdcdf077752d4dc0fcc9554bf797f8af0c1db59f0025a72d4ed2", - "sha256:92a719bb1118f302f6fc3c7638e78e152de8bf279c0200325af831afa1b60f1a", - "sha256:9618070bb76a064c13020323b7fc23c332930604dfbc96b77e7ad7baca960c12", - "sha256:973d630c00bbaf07045870d331c8596bf4fa07aa8eb10d69a02c542af714f128", - "sha256:99febd7a9efab236d798d72ca878ae0d92fffadcc2e472636d6e093ce2677980", - "sha256:9eaf0f28ed19919bdeb02cfa541daaee8a05c070227eaab8d9732f1eebfe2869", - "sha256:9ee84156656d4a09010c280f41011f0a317c62e745f7a2cfafabd8035823fe2d", - "sha256:a999c5c50af0e564cab5bbbbbee97d494eb0e09f99481385108ddfd90049b3fe", - "sha256:ac210d628b9a50699189ec09f0f73630c78e60027d81d75c461deebf7aed752c", - "sha256:ac487adb2e838d03aed0c1a9df4ba348ca2c215bf2afa2f6e1d9449c7029971f", - "sha256:ad6775f8bd57e2c4068246e03c00e212e01b27ea0e96a4b4f17f9d45d80cd5d8", - "sha256:aef7e9b60b371f4d3c3ea80c0ef2d841623dd64aad7718ab815a3205bd4bdf08", - "sha256:b0e38cf49c17e35831ec38029854b772717d6071f0419b74b80be57571a83d0a", - "sha256:b68c0c9deb2fcd183376600df99e88032a9c192d352b0f781e130b09220ef1cf", - "sha256:b846a17f810708f1beff6ad088121fd35334729df3e520412163c74ef49433f7", - "sha256:bc8a06f7bc45219b2c191d68e779e6b3f62e32d09d2f8cf7b381ba1dcb7a68f9", - "sha256:bd6ca6e66b4fee5e879207854f125b94f6ad77e98ddae4d7778d2e96be94ede4", - "sha256:c115756cb1cad49862aa0c2687922ed10da6be7689cf35e3ab602c4a6da2d8fb", - "sha256:c2c4da0802f6897f7fb766c4f0e7f55c96b103981265fcf12b648d088bee3744", - "sha256:c464852c531e44abc5ba05d0c0c97a8fa63719106b3dca46fedae14daedf46ae", - "sha256:c48477c6ff32032624aa122323adc343055bb7e347e01146a86e652b06281731", - "sha256:c6dfa317e4b87052589253f50119211b801146ff7214b8684830e9084fa6eb0a", - "sha256:c763e42a29ac98e7240004e36b7ce231046054393182f1f630c897ce049579ed", - "sha256:c7fab0120e4ea5a2c170382bd27345b2b56e22b6270b40e4231a68f090ce17ed", - "sha256:cb56dcaf10bac9713fff133074d2460b0b217f27760a2b642efb2bc4179bfde6", - "sha256:cfcca979b72f240bac7c73564026eae4c97639151a415e6ced6392d120022d2d", - "sha256:d070756da822a538231d519ce290a1423ab108d6174ad1497cd020bee503d818", - "sha256:d5c35188fac7e448b52eb3916365fe5f59eb27fecec21ba757eea4f650584ca5", - "sha256:d8da09e318a2916da7110d1147355056ee89d61b4ded49ba3ada717517f2fc71", - "sha256:d957259a15e45e5fa5d51ce59ab7519cff8d3de0109d404627276ec68412c718", - "sha256:de1ab4f48fbcb4c2e578951338cc1c8245e510be061d2773a2d47616fb0d6470", - "sha256:de9f7a51f828f73ea0ca2e856a7cac8766752f336241abdb6c5f45f402dd59ea", - "sha256:e00aaf1574075439ccb0b827ca822c5a97c0103351ead292c42a9f17bd2eae0a", - "sha256:e6df05c2234786b15632cd154d60122c302fd860d89c3ee47c166ad92eb6ae55", - "sha256:e7a8f70c7c283d0b4af90314ff8d969c9ab2c7ee522bfb612f42c542935f6e11", - "sha256:ec1f6129c1175d15da7b7c13ae5d4226acf6b5fe362c5b01ac9787fa88c64781", - "sha256:ececd833be7fd8390371c082103916702170e81a1b22beb989452f934def78d6", - "sha256:ee77d3c82576baae66a3281c9a6431fc84281443a7e36a8490a45b3dbbb60446", - "sha256:f0a6cd797394761692cc6f33b10f2ea46789ac0b7fba82b6df737f51e1297122", - "sha256:f1b3930f0934057825227016a141ce16aad4b2a3805fb4e2de71064d042d72e9", - "sha256:f9dae6ef584d3241571674ed7bcd1a28b003a5f0c3a6ca561ab42e5ce0c482e3", - "sha256:fb09731156f54dfd8bb097ce80f9436c2a1a282061ba29e526c375c69086b764" + "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", + "sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8", + "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b", + "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", + "sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf", + "sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890", + "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", + "sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6", + "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", + "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", + "sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed", + "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", + "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", + "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", + "sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b", + "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", + "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511", + "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", + "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", + "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", + "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", + "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", + "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", + "sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba", + "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", + "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", + "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", + "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", + "sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748", + "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7", + "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", + "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503", + "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d", + "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", + "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", + "sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737", + "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", + "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", + "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", + "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", + "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", + "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", + "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d", + "sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b", + "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", + "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6", + "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", + "sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea", + "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", + "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", + "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", + "sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f", + "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", + "sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba", + "sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9", + "sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0", + "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6", + "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", + "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967", + "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", + "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", + "sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda", + "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", + "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", + "sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c", + "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", + "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028", + "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", + "sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147", + "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", + "sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca", + "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", + "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", + "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", + "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", + "sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60", + "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", + "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", + "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", + "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", + "sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e", + "sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467", + "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca", + "sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859", + "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", + "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e", + "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", + "sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054", + "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376", + "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", + "sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b", + "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", + "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65", + "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", + "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", + "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", + "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", + "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", + "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", + "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", + "sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e", + "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", + "sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca", + "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", + "sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb", + "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", + "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed", + "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", + "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", + "sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2", + "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", + "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", + "sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a", + "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", + "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", + "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", + "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", + "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", + "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e", + "sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b", + "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", + "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", + "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", + "sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc", + "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", + "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", + "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", + "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", + "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", + "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249" ], "markers": "python_version >= '3.9'", - "version": "==1.21.0" + "version": "==1.22.0" }, "zstandard": { "hashes": [ @@ -1837,11 +1844,11 @@ }, "platformdirs": { "hashes": [ - "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", - "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf" + "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", + "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3" ], - "markers": "python_version >= '3.9'", - "version": "==4.4.0" + "markers": "python_version >= '3.10'", + "version": "==4.5.0" }, "pygments": { "hashes": [ @@ -1941,11 +1948,11 @@ }, "rich": { "hashes": [ - "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", - "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8" + "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", + "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd" ], "markers": "python_full_version >= '3.8.0'", - "version": "==14.1.0" + "version": "==14.2.0" }, "stevedore": { "hashes": [ @@ -2004,12 +2011,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", + "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==4.8.0" + "markers": "python_version >= '3.9'", + "version": "==4.15.0" } } } diff --git a/requirements.txt b/requirements.txt index 8530e8e0d5..36d9778da2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,14 +2,13 @@ aiodns==3.5.0; python_version >= '3.9' aiohttp==3.9.0; python_version >= '3.8' aiosignal==1.4.0; python_version >= '3.9' -attrs==25.3.0; python_version >= '3.8' -audioop-lts==0.2.2; python_version >= '3.13' -brotli==1.1.0 +attrs==25.4.0; python_version >= '3.9' +brotli==1.2.0 cairocffi==1.7.1; python_version >= '3.8' cairosvg==2.8.2; python_version >= '3.9' certifi==2025.10.5; python_version >= '3.7' cffi==2.0.0; python_version >= '3.9' -charset-normalizer==3.4.3; python_version >= '3.7' +charset-normalizer==3.4.4; python_version >= '3.7' colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' cssselect2==0.8.0; python_version >= '3.9' defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' @@ -17,27 +16,28 @@ discord.py[speed]==2.6.3; python_version >= '3.8' dnspython==2.8.0; python_version >= '3.10' emoji==2.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' frozenlist==1.8.0; python_version >= '3.9' -idna==3.10; python_version >= '3.6' +idna==3.11; python_version >= '3.8' isodate==0.6.1 lottie[pdf]==0.7.0; python_version >= '3' motor==3.3.2; python_version >= '3.7' -multidict==6.6.4; python_version >= '3.9' +multidict==6.7.0; python_version >= '3.9' natural==0.2.0 -orjson==3.11.3; python_version >= '3.9' +orjson==3.11.4; python_version >= '3.9' packaging==23.2; python_version >= '3.7' parsedatetime==2.6 -pillow==11.3.0; python_version >= '3.9' -propcache==0.4.0; python_version >= '3.9' +pillow==12.0.0; python_version >= '3.10' +propcache==0.4.1; python_version >= '3.9' pycares==4.11.0; python_version >= '3.9' pycparser==2.23; python_version >= '3.8' -pymongo[srv]==4.15.2; python_version >= '3.9' +pymongo[srv]==4.15.3; python_version >= '3.9' python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' python-dotenv==1.0.0; python_version >= '3.8' requests==2.31.0; python_version >= '3.7' six==1.17.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' tinycss2==1.4.0; python_version >= '3.8' +typing-extensions==4.15.0; python_version >= '3.9' urllib3==2.5.0; python_version >= '3.9' -uvloop==0.21.0; sys_platform != 'win32' +uvloop==0.22.1; sys_platform != 'win32' webencodings==0.5.1 -yarl==1.21.0; python_version >= '3.9' +yarl==1.22.0; python_version >= '3.9' zstandard==0.25.0; python_version >= '3.9' From 98cb126d1ee09965bad89a4b77176227591ec6be Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Tue, 11 Nov 2025 04:10:35 -0800 Subject: [PATCH 691/705] Bump aiohttp and motor deps, fixed pipenv dependency errors --- Pipfile | 13 +- Pipfile.lock | 308 ++++++++++++++++++++++++++++++++--------------- requirements.txt | 12 +- 3 files changed, 228 insertions(+), 105 deletions(-) diff --git a/Pipfile b/Pipfile index 8fe5bd40c8..daa0e60698 100644 --- a/Pipfile +++ b/Pipfile @@ -7,24 +7,27 @@ verify_ssl = true bandit = ">=1.7.5" black = "==23.11.0" pylint = "==3.0.2" -typing-extensions = "==4.8.0" tomli = "==2.2.1" # Needed for black on Python < 3.11 [packages] -aiohttp = "==3.9.0" +aiohttp = "==3.13.2" +async-timeout = {version = "==5.0.1", markers = "python_version < '3.11'"} # Required by aiohttp +typing-extensions = ">=4.12.2" # Required by aiohttp colorama = "==0.4.6" "discord.py" = {version = "==2.6.3", extras = ["speed"]} emoji = "==2.8.0" isodate = "==0.6.1" -motor = "==3.3.2" +motor = "==3.7.1" natural = "==0.2.0" # Why is this needed? packaging = "==23.2" parsedatetime = "==2.6" -pymongo = {extras = ["srv"], version = "*"} # Required by motor +dnspython = ">=2.8,<3" # Required by pymongo +pymongo = ">=4.9,<5" # Required by motor python-dateutil = "==2.8.2" python-dotenv = "==1.0.0" uvloop = {version = ">=0.19.0", markers = "sys_platform != 'win32'"} -lottie = {version = "==0.7.0", extras = ["pdf"]} +lottie = {version = "==0.7.2", extras = ["pdf"]} +setuptools = "*" # Needed for lottie requests = "==2.31.0" [scripts] diff --git a/Pipfile.lock b/Pipfile.lock index 5c4310d52e..39cd6c33e2 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "93bdedec9b82ac210253d3424e48f3af9e79dca6c44b5b941ec446709de27409" + "sha256": "b9e47a4bb95c39f0d11eeffe03c9229ef1751eec0e412c1a9b4c1f6dc47ed754" }, "pipfile-spec": 6, "requires": {}, @@ -22,88 +22,140 @@ "markers": "python_version >= '3.9'", "version": "==3.5.0" }, + "aiohappyeyeballs": { + "hashes": [ + "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", + "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8" + ], + "markers": "python_version >= '3.9'", + "version": "==2.6.1" + }, "aiohttp": { "hashes": [ - "sha256:05857848da443c8c12110d99285d499b4e84d59918a21132e45c3f0804876994", - "sha256:05a183f1978802588711aed0dea31e697d760ce9055292db9dc1604daa9a8ded", - "sha256:09f23292d29135025e19e8ff4f0a68df078fe4ee013bca0105b2e803989de92d", - "sha256:11ca808f9a6b63485059f5f6e164ef7ec826483c1212a44f268b3653c91237d8", - "sha256:1736d87dad8ef46a8ec9cddd349fa9f7bd3a064c47dd6469c0d6763d3d49a4fc", - "sha256:1df43596b826022b14998f0460926ce261544fedefe0d2f653e1b20f49e96454", - "sha256:23170247ef89ffa842a02bbfdc425028574d9e010611659abeb24d890bc53bb8", - "sha256:2779f5e7c70f7b421915fd47db332c81de365678180a9f3ab404088f87ba5ff9", - "sha256:28185e36a78d247c55e9fbea2332d16aefa14c5276a582ce7a896231c6b1c208", - "sha256:2cbc14a13fb6b42d344e4f27746a4b03a2cb0c1c3c5b932b0d6ad8881aa390e3", - "sha256:2d71abc15ff7047412ef26bf812dfc8d0d1020d664617f4913df2df469f26b76", - "sha256:2d820162c8c2bdbe97d328cd4f417c955ca370027dce593345e437b2e9ffdc4d", - "sha256:317719d7f824eba55857fe0729363af58e27c066c731bc62cd97bc9c3d9c7ea4", - "sha256:35a68cd63ca6aaef5707888f17a70c36efe62b099a4e853d33dc2e9872125be8", - "sha256:3607375053df58ed6f23903aa10cf3112b1240e8c799d243bbad0f7be0666986", - "sha256:366bc870d7ac61726f32a489fbe3d1d8876e87506870be66b01aeb84389e967e", - "sha256:3abf0551874fecf95f93b58f25ef4fc9a250669a2257753f38f8f592db85ddea", - "sha256:3d7f6235c7475658acfc1769d968e07ab585c79f6ca438ddfecaa9a08006aee2", - "sha256:3dd8119752dd30dd7bca7d4bc2a92a59be6a003e4e5c2cf7e248b89751b8f4b7", - "sha256:42fe4fd9f0dfcc7be4248c162d8056f1d51a04c60e53366b0098d1267c4c9da8", - "sha256:45820ddbb276113ead8d4907a7802adb77548087ff5465d5c554f9aa3928ae7d", - "sha256:4790e44f46a4aa07b64504089def5744d3b6780468c4ec3a1a36eb7f2cae9814", - "sha256:4afa8f71dba3a5a2e1e1282a51cba7341ae76585345c43d8f0e624882b622218", - "sha256:4b777c9286b6c6a94f50ddb3a6e730deec327e9e2256cb08b5530db0f7d40fd8", - "sha256:4ee1b4152bc3190cc40ddd6a14715e3004944263ea208229ab4c297712aa3075", - "sha256:51a4cd44788ea0b5e6bb8fa704597af3a30be75503a7ed1098bc5b8ffdf6c982", - "sha256:536b01513d67d10baf6f71c72decdf492fb7433c5f2f133e9a9087379d4b6f31", - "sha256:571760ad7736b34d05597a1fd38cbc7d47f7b65deb722cb8e86fd827404d1f6b", - "sha256:5a2eb5311a37fe105aa35f62f75a078537e1a9e4e1d78c86ec9893a3c97d7a30", - "sha256:5ab16c254e2312efeb799bc3c06897f65a133b38b69682bf75d1f1ee1a9c43a9", - "sha256:65b0a70a25456d329a5e1426702dde67be0fb7a4ead718005ba2ca582d023a94", - "sha256:673343fbc0c1ac44d0d2640addc56e97a052504beacd7ade0dc5e76d3a4c16e8", - "sha256:6777a390e41e78e7c45dab43a4a0196c55c3b8c30eebe017b152939372a83253", - "sha256:6896b8416be9ada4d22cd359d7cb98955576ce863eadad5596b7cdfbf3e17c6c", - "sha256:694df243f394629bcae2d8ed94c589a181e8ba8604159e6e45e7b22e58291113", - "sha256:70e851f596c00f40a2f00a46126c95c2e04e146015af05a9da3e4867cfc55911", - "sha256:7276fe0017664414fdc3618fca411630405f1aaf0cc3be69def650eb50441787", - "sha256:76a86a9989ebf82ee61e06e2bab408aec4ea367dc6da35145c3352b60a112d11", - "sha256:7a94bde005a8f926d0fa38b88092a03dea4b4875a61fbcd9ac6f4351df1b57cd", - "sha256:7ae5f99a32c53731c93ac3075abd3e1e5cfbe72fc3eaac4c27c9dd64ba3b19fe", - "sha256:7e8a3b79b6d186a9c99761fd4a5e8dd575a48d96021f220ac5b5fa856e5dd029", - "sha256:816f4db40555026e4cdda604a1088577c1fb957d02f3f1292e0221353403f192", - "sha256:8303531e2c17b1a494ffaeba48f2da655fe932c4e9a2626c8718403c83e5dd2b", - "sha256:8488519aa05e636c5997719fe543c8daf19f538f4fa044f3ce94bee608817cff", - "sha256:87c8b0a6487e8109427ccf638580865b54e2e3db4a6e0e11c02639231b41fc0f", - "sha256:8c9e5f4d7208cda1a2bb600e29069eecf857e6980d0ccc922ccf9d1372c16f4b", - "sha256:94697c7293199c2a2551e3e3e18438b4cba293e79c6bc2319f5fd652fccb7456", - "sha256:9623cfd9e85b76b83ef88519d98326d4731f8d71869867e47a0b979ffec61c73", - "sha256:98d21092bf2637c5fa724a428a69e8f5955f2182bff61f8036827cf6ce1157bf", - "sha256:99ae01fb13a618b9942376df77a1f50c20a281390dad3c56a6ec2942e266220d", - "sha256:9c196b30f1b1aa3363a69dd69079ae9bec96c2965c4707eaa6914ba099fb7d4f", - "sha256:a00ce44c21612d185c5275c5cba4bab8d7c1590f248638b667ed8a782fa8cd6f", - "sha256:a1b66dbb8a7d5f50e9e2ea3804b01e766308331d0cac76eb30c563ac89c95985", - "sha256:a1d7edf74a36de0e5ca50787e83a77cf352f5504eb0ffa3f07000a911ba353fb", - "sha256:a1e3b3c107ccb0e537f309f719994a55621acd2c8fdf6d5ce5152aed788fb940", - "sha256:a486ddf57ab98b6d19ad36458b9f09e6022de0381674fe00228ca7b741aacb2f", - "sha256:ac9669990e2016d644ba8ae4758688534aabde8dbbc81f9af129c3f5f01ca9cd", - "sha256:b1a2ea8252cacc7fd51df5a56d7a2bb1986ed39be9397b51a08015727dfb69bd", - "sha256:c5b7bf8fe4d39886adc34311a233a2e01bc10eb4e842220235ed1de57541a896", - "sha256:c67a51ea415192c2e53e4e048c78bab82d21955b4281d297f517707dc836bf3d", - "sha256:ca4fddf84ac7d8a7d0866664936f93318ff01ee33e32381a115b19fb5a4d1202", - "sha256:d5b9345ab92ebe6003ae11d8092ce822a0242146e6fa270889b9ba965457ca40", - "sha256:d97c3e286d0ac9af6223bc132dc4bad6540b37c8d6c0a15fe1e70fb34f9ec411", - "sha256:db04d1de548f7a62d1dd7e7cdf7c22893ee168e22701895067a28a8ed51b3735", - "sha256:dcf71c55ec853826cd70eadb2b6ac62ec577416442ca1e0a97ad875a1b3a0305", - "sha256:de3cc86f4ea8b4c34a6e43a7306c40c1275e52bfa9748d869c6b7d54aa6dad80", - "sha256:deac0a32aec29608eb25d730f4bc5a261a65b6c48ded1ed861d2a1852577c932", - "sha256:e18d92c3e9e22553a73e33784fcb0ed484c9874e9a3e96c16a8d6a1e74a0217b", - "sha256:eb6dfd52063186ac97b4caa25764cdbcdb4b10d97f5c5f66b0fa95052e744eb7", - "sha256:f09960b5bb1017d16c0f9e9f7fc42160a5a49fa1e87a175fd4a2b1a1833ea0af", - "sha256:f1e4f254e9c35d8965d377e065c4a8a55d396fe87c8e7e8429bcfdeeb229bfb3", - "sha256:f32c86dc967ab8c719fd229ce71917caad13cc1e8356ee997bf02c5b368799bf", - "sha256:f50b4663c3e0262c3a361faf440761fbef60ccdde5fe8545689a4b3a3c149fb4", - "sha256:f8e05f5163528962ce1d1806fce763ab893b1c5b7ace0a3538cd81a90622f844", - "sha256:f929f4c9b9a00f3e6cc0587abb95ab9c05681f8b14e0fe1daecfa83ea90f8318", - "sha256:f9e09a1c83521d770d170b3801eea19b89f41ccaa61d53026ed111cb6f088887" + "sha256:04c3971421576ed24c191f610052bcb2f059e395bc2489dd99e397f9bc466329", + "sha256:05c4dd3c48fb5f15db31f57eb35374cb0c09afdde532e7fb70a75aede0ed30f6", + "sha256:070599407f4954021509193404c4ac53153525a19531051661440644728ba9a7", + "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", + "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", + "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", + "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", + "sha256:0e87dff73f46e969af38ab3f7cb75316a7c944e2e574ff7c933bc01b10def7f5", + "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", + "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", + "sha256:1f9b2c2d4b9d958b1f9ae0c984ec1dd6b6689e15c75045be8ccb4011426268ca", + "sha256:204ffff2426c25dfda401ba08da85f9c59525cdc42bda26660463dd1cbcfec6f", + "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", + "sha256:20db2d67985d71ca033443a1ba2001c4b5693fe09b0e29f6d9358a99d4d62a8a", + "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", + "sha256:2372b15a5f62ed37789a6b383ff7344fc5b9f243999b0cd9b629d8bc5f5b4155", + "sha256:23ad365e30108c422d0b4428cf271156dd56790f6dd50d770b8e360e6c5ab2e6", + "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", + "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", + "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", + "sha256:29562998ec66f988d49fb83c9b01694fa927186b781463f376c5845c121e4e0b", + "sha256:2adebd4577724dcae085665f294cc57c8701ddd4d26140504db622b8d566d7aa", + "sha256:2ca6ffef405fc9c09a746cb5d019c1672cd7f402542e379afc66b370833170cf", + "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", + "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", + "sha256:364f55663085d658b8462a1c3f17b2b84a5c2e1ba858e1b79bff7b2e24ad1514", + "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", + "sha256:3a92cf4b9bea33e15ecbaa5c59921be0f23222608143d025c989924f7e3e0c07", + "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", + "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", + "sha256:43dff14e35aba17e3d6d5ba628858fb8cb51e30f44724a2d2f0c75be492c55e9", + "sha256:4647d02df098f6434bafd7f32ad14942f05a9caa06c7016fdcc816f343997dd0", + "sha256:47f438b1a28e926c37632bff3c44df7d27c9b57aaf4e34b1def3c07111fdb782", + "sha256:4dd3db9d0f4ebca1d887d76f7cdbcd1116ac0d05a9221b9dad82c64a62578c4d", + "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", + "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", + "sha256:53b07472f235eb80e826ad038c9d106c2f653584753f3ddab907c83f49eedead", + "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", + "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", + "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", + "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", + "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", + "sha256:6315fb6977f1d0dd41a107c527fee2ed5ab0550b7d885bc15fee20ccb17891da", + "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", + "sha256:6c00dbcf5f0d88796151e264a8eab23de2997c9303dd7c0bf622e23b24d3ce22", + "sha256:6e7352512f763f760baaed2637055c49134fd1d35b37c2dedfac35bfe5cf8725", + "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", + "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", + "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", + "sha256:7c3a50345635a02db61792c85bb86daffac05330f6473d524f1a4e3ef9d0046d", + "sha256:7fbdf5ad6084f1940ce88933de34b62358d0f4a0b6ec097362dcd3e5a65a4989", + "sha256:7fd19df530c292542636c2a9a85854fab93474396a52f1695e799186bbd7f24c", + "sha256:868e195e39b24aaa930b063c08bb0c17924899c16c672a28a65afded9c46c6ec", + "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", + "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", + "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", + "sha256:8b2f1414f6a1e0683f212ec80e813f4abef94c739fd090b66c9adf9d2a05feac", + "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", + "sha256:939ced4a7add92296b0ad38892ce62b98c619288a081170695c6babe4f50e636", + "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", + "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", + "sha256:960c2fc686ba27b535f9fd2b52d87ecd7e4fd1cf877f6a5cba8afb5b4a8bd204", + "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", + "sha256:97a0895a8e840ab3520e2288db7cace3a1981300d48babeb50e7425609e2e0ab", + "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", + "sha256:99c5280a329d5fa18ef30fd10c793a190d996567667908bef8a7f81f8202b948", + "sha256:9acda8604a57bb60544e4646a4615c1866ee6c04a8edef9b8ee6fd1d8fa2ddc8", + "sha256:9c705601e16c03466cb72011bd1af55d68fa65b045356d8f96c216e5f6db0fa5", + "sha256:9e8f8afb552297aca127c90cb840e9a1d4bfd6a10d7d8f2d9176e1acc69bad30", + "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", + "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", + "sha256:9f377d0a924e5cc94dc620bc6366fc3e889586a7f18b748901cf016c916e2084", + "sha256:a09a6d073fb5789456545bdee2474d14395792faa0527887f2f4ec1a486a59d3", + "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", + "sha256:a3b6fb0c207cc661fa0bf8c66d8d9b657331ccc814f4719468af61034b478592", + "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", + "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", + "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", + "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", + "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", + "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", + "sha256:b395bbca716c38bef3c764f187860e88c724b342c26275bc03e906142fc5964f", + "sha256:b59d13c443f8e049d9e94099c7e412e34610f1f49be0f230ec656a10692a5802", + "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", + "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", + "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", + "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", + "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", + "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", + "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", + "sha256:d7bc4b7f9c4921eba72677cd9fedd2308f4a4ca3e12fab58935295ad9ea98700", + "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", + "sha256:dacd50501cd017f8cccb328da0c90823511d70d24a323196826d923aad865901", + "sha256:e036a3a645fe92309ec34b918394bb377950cbb43039a97edae6c08db64b23e2", + "sha256:e09a0a06348a2dd73e7213353c90d709502d9786219f69b731f6caa0efeb46f5", + "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", + "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", + "sha256:e2a9ea08e8c58bb17655630198833109227dea914cd20be660f52215f6de5613", + "sha256:e3403f24bcb9c3b29113611c3c16a2a447c3953ecf86b79775e7be06f7ae7ccb", + "sha256:e574a7d61cf10351d734bcddabbe15ede0eaa8a02070d85446875dc11189a251", + "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", + "sha256:e736c93e9c274fce6419af4aac199984d866e55f8a4cec9114671d0ea9688780", + "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", + "sha256:e7f8659a48995edee7229522984bd1009c1213929c769c2daa80b40fe49a180c", + "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", + "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", + "sha256:ed2f9c7216e53c3df02264f25d824b079cc5914f9e2deba94155190ef648ee40", + "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", + "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", + "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", + "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", + "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", + "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", + "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", + "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", + "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", + "sha256:fed38a5edb7945f4d1bcabe2fcd05db4f6ec7e0e82560088b754f7e08d93772d", + "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", + "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", + "sha256:ff5e771f5dcbc81c64898c597a434f7682f2259e0cd666932a913d53d1341d1a" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==3.9.0" + "markers": "python_version >= '3.9'", + "version": "==3.13.2" }, "aiosignal": { "hashes": [ @@ -113,6 +165,14 @@ "markers": "python_version >= '3.9'", "version": "==1.4.0" }, + "async-timeout": { + "hashes": [ + "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", + "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3" + ], + "markers": "python_version < '3.11'", + "version": "==5.0.1" + }, "attrs": { "hashes": [ "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", @@ -121,6 +181,61 @@ "markers": "python_version >= '3.9'", "version": "==25.4.0" }, + "audioop-lts": { + "hashes": [ + "sha256:0337d658f9b81f4cd0fdb1f47635070cc084871a3d4646d9de74fdf4e7c3d24a", + "sha256:03f061a1915538fd96272bac9551841859dbb2e3bf73ebe4a23ef043766f5449", + "sha256:068aa17a38b4e0e7de771c62c60bbca2455924b67a8814f3b0dee92b5820c0b3", + "sha256:088327f00488cdeed296edd9215ca159f3a5a5034741465789cad403fcf4bec0", + "sha256:0d9385e96f9f6da847f4d571ce3cb15b5091140edf3db97276872647ce37efd7", + "sha256:106753a83a25ee4d6f473f2be6b0966fc1c9af7e0017192f5531a3e7463dce58", + "sha256:143fad0311e8209ece30a8dbddab3b65ab419cbe8c0dde6e8828da25999be911", + "sha256:15ab25dd3e620790f40e9ead897f91e79c0d3ce65fe193c8ed6c26cffdd24be7", + "sha256:167d3b62586faef8b6b2275c3218796b12621a60e43f7e9d5845d627b9c9b80e", + "sha256:2b267b70747d82125f1a021506565bdc5609a2b24bcb4773c16d79d2bb260bbd", + "sha256:3bcddaaf6cc5935a300a8387c99f7a7fbbe212a11568ec6cf6e4bc458c048636", + "sha256:3fc38008969796f0f689f1453722a0f463da1b8a6fbee11987830bfbb664f623", + "sha256:47eba38322370347b1c47024defbd36374a211e8dd5b0dcbce7b34fdb6f8847b", + "sha256:48159d96962674eccdca9a3df280e864e8ac75e40a577cc97c5c42667ffabfc5", + "sha256:49ee1a41738a23e98d98b937a0638357a2477bc99e61b0f768a8f654f45d9b7a", + "sha256:4a53aa7c16a60a6857e6b0b165261436396ef7293f8b5c9c828a3a203147ed4a", + "sha256:4b4cd51a57b698b2d06cb9993b7ac8dfe89a3b2878e96bc7948e9f19ff51dba6", + "sha256:51c916108c56aa6e426ce611946f901badac950ee2ddaf302b7ed35d9958970d", + "sha256:550c114a8df0aafe9a05442a1162dfc8fec37e9af1d625ae6060fed6e756f303", + "sha256:58cf54380c3884fb49fdd37dfb7a772632b6701d28edd3e2904743c5e1773602", + "sha256:5b00be98ccd0fc123dcfad31d50030d25fcf31488cde9e61692029cd7394733b", + "sha256:5f93a5db13927a37d2d09637ccca4b2b6b48c19cd9eda7b17a2e9f77edee6a6f", + "sha256:64d0c62d88e67b98a1a5e71987b7aa7b5bcffc7dcee65b635823dbdd0a8dbbd0", + "sha256:73f80bf4cd5d2ca7814da30a120de1f9408ee0619cc75da87d0641273d202a09", + "sha256:752d76472d9804ac60f0078c79cdae8b956f293177acd2316cd1e15149aee132", + "sha256:83c381767e2cc10e93e40281a04852facc4cd9334550e0f392f72d1c0a9c5753", + "sha256:8fefe5868cd082db1186f2837d64cfbfa78b548ea0d0543e9b28935ccce81ce9", + "sha256:9191d68659eda01e448188f60364c7763a7ca6653ed3f87ebb165822153a8547", + "sha256:96f19de485a2925314f5020e85911fb447ff5fbef56e8c7c6927851b95533a1c", + "sha256:9a13dc409f2564de15dd68be65b462ba0dde01b19663720c68c1140c782d1d75", + "sha256:a2c2a947fae7d1062ef08c4e369e0ba2086049a5e598fda41122535557012e9e", + "sha256:a2d4f1513d63c795e82948e1305f31a6d530626e5f9f2605408b300ae6095093", + "sha256:a5bf613e96f49712073de86f20dbdd4014ca18efd4d34ed18c75bd808337851b", + "sha256:a6d2e0f9f7a69403e388894d4ca5ada5c47230716a03f2847cfc7bd1ecb589d6", + "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", + "sha256:ba7c3a7e5f23e215cb271516197030c32aef2e754252c4c70a50aaff7031a2c8", + "sha256:c0022283e9556e0f3643b7c3c03f05063ca72b3063291834cca43234f20c60bb", + "sha256:c174e322bb5783c099aaf87faeb240c8d210686b04bd61dfd05a8e5a83d88969", + "sha256:c9c8e68d8b4a56fda8c025e538e639f8c5953f5073886b596c93ec9b620055e7", + "sha256:cfcac6aa6f42397471e4943e0feb2244549db5c5d01efcd02725b96af417f3fe", + "sha256:d5e73fa573e273e4f2e5ff96f9043858a5e9311e94ffefd88a3186a910c70917", + "sha256:def246fe9e180626731b26e89816e79aae2276f825420a07b4a647abaa84becc", + "sha256:dfbbc74ec68a0fd08cfec1f4b5e8cca3d3cd7de5501b01c4b5d209995033cde9", + "sha256:e160bf9df356d841bb6c180eeeea1834085464626dc1b68fa4e1d59070affdc3", + "sha256:e541c3ef484852ef36545f66209444c48b28661e864ccadb29daddb6a4b8e5f5", + "sha256:f9b0b8a03ef474f56d1a842af1a2e01398b8f7654009823c6d9e0ecff4d5cfbf", + "sha256:f9ee9b52f5f857fbaf9d605a360884f034c92c1c23021fb90b2e39b8e64bede6", + "sha256:fbdd522624141e40948ab3e8cdae6e04c748d78710e9f0f8d4dae2750831de19", + "sha256:fd3d4602dc64914d462924a08c1a9816435a2155d74f325853c1f1ac3b2d9800" + ], + "markers": "python_version >= '3.13'", + "version": "==0.2.2" + }, "brotli": { "hashes": [ "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24", @@ -500,6 +615,7 @@ "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f" ], + "index": "pypi", "markers": "python_version >= '3.10'", "version": "==2.8.0" }, @@ -669,19 +785,19 @@ "pdf" ], "hashes": [ - "sha256:a3242f8ba37051fbdd7503ecd168203a08e4af26f17be2ecca08a64af1e7d3c1" + "sha256:85304ac152cd042c9fe98a527b5d136a31c6fe2aacd859ce1c58189bb946d127" ], "markers": "python_version >= '3'", - "version": "==0.7.0" + "version": "==0.7.2" }, "motor": { "hashes": [ - "sha256:6fe7e6f0c4f430b9e030b9d22549b732f7c2226af3ab71ecc309e4a1b7d19953", - "sha256:d2fc38de15f1c8058f389c1a44a4d4105c0405c48c061cd492a654496f7bc26a" + "sha256:27b4d46625c87928f331a6ca9d7c51c2f518ba0e270939d395bc1ddc89d64526", + "sha256:8a63b9049e38eeeb56b4fdd57c3312a6d1f25d01db717fe7d82222393c410298" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==3.3.2" + "markers": "python_version >= '3.9'", + "version": "==3.7.1" }, "multidict": { "hashes": [ @@ -1284,9 +1400,6 @@ "version": "==2.23" }, "pymongo": { - "extras": [ - "srv" - ], "hashes": [ "sha256:07bcc36d11252f24fe671e7e64044d39a13d997b0502c6401161f28cc144f584", "sha256:09440e78dff397b2f34a624f445ac8eb44c9756a2688b85b3bf344d351d198e1", @@ -1360,6 +1473,7 @@ "sha256:ff99864085d2c7f4bb672c7167680ceb7d273e9a93c1a8074c986a36dbb71cc6", "sha256:ffe217d2502f3fba4e2b0dc015ce3b34f157b66dfe96835aa64432e909dd0d95" ], + "index": "pypi", "markers": "python_version >= '3.9'", "version": "==4.15.3" }, @@ -1390,6 +1504,15 @@ "markers": "python_version >= '3.7'", "version": "==2.31.0" }, + "setuptools": { + "hashes": [ + "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", + "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==80.9.0" + }, "six": { "hashes": [ "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", @@ -1411,6 +1534,7 @@ "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" ], + "index": "pypi", "markers": "python_version >= '3.9'", "version": "==4.15.0" }, @@ -2008,14 +2132,6 @@ ], "markers": "python_version >= '3.8'", "version": "==0.13.3" - }, - "typing-extensions": { - "hashes": [ - "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", - "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" - ], - "markers": "python_version >= '3.9'", - "version": "==4.15.0" } } } diff --git a/requirements.txt b/requirements.txt index 36d9778da2..9c07172039 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,11 @@ -i https://pypi.org/simple aiodns==3.5.0; python_version >= '3.9' -aiohttp==3.9.0; python_version >= '3.8' +aiohappyeyeballs==2.6.1; python_version >= '3.9' +aiohttp==3.13.2; python_version >= '3.9' aiosignal==1.4.0; python_version >= '3.9' +async-timeout==5.0.1; python_version < '3.11' attrs==25.4.0; python_version >= '3.9' +audioop-lts==0.2.2; python_version >= '3.13' brotli==1.2.0 cairocffi==1.7.1; python_version >= '3.8' cairosvg==2.8.2; python_version >= '3.9' @@ -18,8 +21,8 @@ emoji==2.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, frozenlist==1.8.0; python_version >= '3.9' idna==3.11; python_version >= '3.8' isodate==0.6.1 -lottie[pdf]==0.7.0; python_version >= '3' -motor==3.3.2; python_version >= '3.7' +lottie[pdf]==0.7.2; python_version >= '3' +motor==3.7.1; python_version >= '3.9' multidict==6.7.0; python_version >= '3.9' natural==0.2.0 orjson==3.11.4; python_version >= '3.9' @@ -29,10 +32,11 @@ pillow==12.0.0; python_version >= '3.10' propcache==0.4.1; python_version >= '3.9' pycares==4.11.0; python_version >= '3.9' pycparser==2.23; python_version >= '3.8' -pymongo[srv]==4.15.3; python_version >= '3.9' +pymongo==4.15.3; python_version >= '3.9' python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' python-dotenv==1.0.0; python_version >= '3.8' requests==2.31.0; python_version >= '3.7' +setuptools==80.9.0; python_version >= '3.9' six==1.17.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' tinycss2==1.4.0; python_version >= '3.8' typing-extensions==4.15.0; python_version >= '3.9' From 829a3642405e4c3536b42338f18fe9a6577a548c Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Thu, 20 Nov 2025 20:32:37 +0100 Subject: [PATCH 692/705] fix: Remove thread-only restriction from logs command (#3397) The logs command can be used anywhere again. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> --- cogs/modmail.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index d7d9d7b010..fa6c01666b 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1200,7 +1200,6 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) - @checks.thread_only() async def logs(self, ctx, *, user: User = None): """ Get previous Modmail thread logs of a member. From 124669d462db41e41216d71d164e00c3dbf36e4c Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 28 Nov 2025 09:31:52 +0100 Subject: [PATCH 693/705] modmail update QOL (#3392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add (truncated) preview to snippets command (#3342) * Add (truncated) preview to snippets command * Add old view as option with "compact" * Fix black formatting * Fix: Image url regex in thread send method (#3378) * feat minimum character requirement for thread creation. (#3380) * update: dpy, snoozing. This pull request updated discord.py to 2.5.2. This also brings a new few features. - snooze - snoozed - unsnooze - clearsnoozed Aswell as a few new config options. - max_snooze_time - snooze_title - snooze_text - unsnooze_tex - unsnooze_notify_channel Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * remove: unneeded import Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Formatting black Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix?: internal messages on restoration Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * formatting Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: internal messages. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: internals Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: use same logkey after restoration Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Add files via upload Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: show who send which internal message. * Black formatting. * Update Pipfile Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update Pipfile.lock Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: unsnooze bug * feat: CV2 * update: black * fix: duplicates in logs, notes. * feat: dpy 2.6.3, forwarded messages, bug fixes. * Fix jump_url not being displayed * Update pipfile for new dpy version * fix: bug in note title/color * Update snooze arg * Update Pipfile to include tomli package Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * auto detect dpy version Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Remove crlf terminators * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * fix: ignore typing failures (#3389) * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * Lock pipenv * Fix: closing with timed words/ command in reply. * Fix: typing in changelog command. * Fix: closing with timed words (additional)) * Fix changelog entry for command reply issue Corrected wording in the changelog entry regarding command inclusion in replies. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update CHANGELOG for v4.2.0 enhancements Forwarded messages now display correctly in threads. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Fix: closing with timed words/ command in reply. (#3391) * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * Fix: closing with timed words/ command in reply. * Fix: typing in changelog command. * Fix: closing with timed words (additional)) * Fix changelog entry for command reply issue Corrected wording in the changelog entry regarding command inclusion in replies. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update CHANGELOG for v4.2.0 enhancements Forwarded messages now display correctly in threads. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Remove disutil, undo lowercasing escape seq * Add back uvloop * Add config help for snooze configs Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * fix; raceconditions, thread duplication on unsnooze, message queue for accurasy on high load * Update package versions in requirements.txt Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * snooze(move): auto-unsnooze on reply/any mod message; enforce hidden permissions on auto-created Snoozed Threads and sync perms on move; restore original overwrites on unsnooze; add capacity guard and config docs * unsnooze: suppress mentions during restore (AllowedMentions.none on replay and notifications) * Remove base64 snooze/unsnooze logic, fix notification crash, clean up replay logic * fix: escape mentions on unsnooze * Fix: Only create log URL button if valid, and robust channel restore for snooze * black formatting * Unsnooze: prefix username (user_id) for plain-text replay messages * feat: command queue during unsnooze process. feat(config): `unsnooze_history_limit`: Limits the number of messages replayed when unsnoozing (genesis message and notes are always shown). * fix: contact while snooze returned as invalid channel * Update thread.py * fix: snooze timing * change: rename default snooze time config * fix: parsing * fix: cache for snooze timer * fix: Properly accessing nested data * rename: default_snooze_time -> snooze_default_duration * improve unsnooze notify * fix: id extraction for clean database. * improve: support for user-friendly time input for snooze_default_duration * reflect config help snooze_default_duration for userfriendly time * fix: anonreply showing None This fixes a bug where, if no `anon_username` is set and the moderator has no roles, the `anon_username` is not showing as `None` anymore, and will show as intended. The logic now works as follows: - If a config anon_username is set → use it - Else, if a mod_tag is set → use it - Else, if the moderator has a top role → use that - Else → use "Anonymous" * black formatting * feat: thread creation menu Credits to Sebkuip(https://github.com/sebkuip) for the original idea and populair plugin.(advanced-menu) This now is a core feature. * Update requirements.txt * fixes This solves: - `config get`: invalid form body - restores functionality after menu timeout. * feat: thread_creation_menu_precreate_channel adds a new: thread_creation_menu_precreate_channel to create the threads, even when nothing is selected yet. * core Fully merged `threadmenu config` into the main bot’s config system. Added threadmenu embed customization capability. * Change thread_creation_menu config Moves thread_creation_menu_options, thread_creation_menu_submenus and thread_creation_menu_enabled to the private config keys to avoid changes via ?config set as they can be changed via ?threadmenu * Change Option Description/Emoji Changes the description and emoji making it possible to be None (optional) * fix: disable menu after closure * feats/fixes configs added: thread_creation_send_dm_embed fix: snooze while no option was selected, after snoozing selecting option first errored. This is now solved * forgot to add help * rely on config for precreating. fix error with unknown channels * feat: large images in threadmenu embed * feat: threadmenu reset * cleanup * codereviews response. Formatting (ruff) * log instead of pass on exception * format * higher delays * black formatting, smoothen menu closure * smoothen which selecetion was made * solves the command from showing in the replies in rare cases * Update CHANGELOG.md * Update sponsors and bmac links * fix: typeerror * fix: Remove thread-only restriction from logs command The logs command can be used anywhere again. * Remove commands from being saved in DB. * fix: correct guildpfp with sepserver setup - made by martin This PR fixes displaying the wrong guild icon in the thread_creation_response embed. When servers having a seperate server setup, the guild icon from the main guild should be displayed instead of the inbox guild. * fix: robust channel deletion handling, skip audit log attribution if permission is missing * update: use current reqs.txt as masterbranch * sync: pip&pip lock with master * Patch Thread Menu Editing Crash * bump version * Missing a newline Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Missing a newline Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Sebastian <61157793+sebkuip@users.noreply.github.com> Co-authored-by: Zallom <Yg75nWkHX7jBHcqRPUbb783c54xSa9+github63384893@gmail.com> Co-authored-by: Martin <box152535@gmail.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- CHANGELOG.md | 26 + bot.py | 307 ++++++- cogs/modmail.py | 423 ++++++++-- cogs/plugins.py | 28 +- cogs/threadmenu.py | 830 ++++++++++++++++++ cogs/utility.py | 150 +++- core/clients.py | 26 +- core/config.py | 90 +- core/config_help.json | 289 ++++++- core/models.py | 26 +- core/paginator.py | 2 +- core/thread.py | 1876 +++++++++++++++++++++++++++++++++++++---- core/time.py | 20 +- core/utils.py | 17 +- pyproject.toml | 2 +- 15 files changed, 3765 insertions(+), 347 deletions(-) create mode 100644 cogs/threadmenu.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 83c4f1bdd4..536680ad2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,32 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.2.1 + +### Added +* `unsnooze_history_limit`: Limits the number of messages replayed when unsnoozing (genesis message and notes are always shown). +* `snooze_behavior`: Choose between `delete` (legacy) or `move` behavior for snoozing. +* `snoozed_category_id`: Target category for `move` snoozing; required when `snooze_behavior` is `move`. +* Thread-creation menu: Adds an interactive select step before a thread channel is created. + * Commands: + * `threadmenu toggle`: Enable/disable the menu. + * `threadmenu show`: List current top-level options. + * `threadmenu option add`: Interactive wizard to create an option. + * `threadmenu option edit/remove/show`: Manage or inspect an existing option. + * `threadmenu submenu create/delete/list/show`: Manage submenus. + * `threadmenu submenu option add/edit/remove`: Manage options inside a submenu. + * Configuration / Behavior: + * Per-option `category` targeting when creating a thread; falls back to `main_category_id` if invalid/missing. + * Optional selection logging (`thread_creation_menu_selection_log`) posts the chosen option in the new thread. + * Anonymous prompt support (`thread_creation_menu_anonymous_menu`). + +### Changed +- Renamed `max_snooze_time` to `snooze_default_duration`. The old config will be invalidated. +- When `snooze_behavior` is set to `move`, the snoozed category now has a hard limit of 49 channels. New snoozes are blocked once it’s full until space is freed. +- When switching `snooze_behavior` to `move` via `?config set`, the bot reminds admins to set `snoozed_category_id` if it’s missing. +- Thread-creation menu options & submenu options now support an optional per-option `category` target. The interactive wizards (`threadmenu option add` / `threadmenu submenu option add`) and edit commands allow specifying or updating a category. If the stored category is missing or invalid at selection time, channel creation automatically falls back to `main_category_id`. + + # v4.2.0 Upgraded discord.py to version 2.6.3, added support for CV2. diff --git a/bot.py b/bot.py index 671d9ab9c4..6176ac5824 100644 --- a/bot.py +++ b/bot.py @@ -1,10 +1,9 @@ -__version__ = "4.2.0" +__version__ = "4.2.1" import asyncio import copy import hashlib -import logging import os import re import string @@ -12,7 +11,7 @@ import sys import platform import typing -from datetime import datetime, timezone, timedelta +from datetime import datetime, timezone from subprocess import PIPE from types import SimpleNamespace @@ -84,12 +83,18 @@ def __init__(self): self.session = None self._api = None self.formatter = SafeFormatter() - self.loaded_cogs = ["cogs.modmail", "cogs.plugins", "cogs.utility"] + self.loaded_cogs = [ + "cogs.modmail", + "cogs.plugins", + "cogs.utility", + "cogs.threadmenu", + ] self._connected = None self.start_time = discord.utils.utcnow() self._started = False self.threads = ThreadManager(self) + self._message_queues = {} # User ID -> asyncio.Queue for message ordering log_dir = os.path.join(temp_dir, "logs") if not os.path.exists(log_dir): @@ -101,7 +106,10 @@ def __init__(self): self.startup() def get_guild_icon( - self, guild: typing.Optional[discord.Guild], *, size: typing.Optional[int] = None + self, + guild: typing.Optional[discord.Guild], + *, + size: typing.Optional[int] = None, ) -> str: if guild is None: guild = self.guild @@ -316,7 +324,10 @@ def log_channel(self) -> typing.Optional[discord.TextChannel]: try: channel = self.main_category.channels[0] self.config["log_channel_id"] = channel.id - logger.warning("No log channel set, setting #%s to be the log channel.", channel.name) + logger.warning( + "No log channel set, setting #%s to be the log channel.", + channel.name, + ) return channel except IndexError: pass @@ -569,7 +580,11 @@ async def on_ready(self): logger.debug("Closing thread for recipient %s.", recipient_id) after = 0 else: - logger.debug("Thread for recipient %s will be closed after %s seconds.", recipient_id, after) + logger.debug( + "Thread for recipient %s will be closed after %s seconds.", + recipient_id, + after, + ) thread = await self.threads.find(recipient_id=int(recipient_id)) @@ -590,7 +605,7 @@ async def on_ready(self): ) for log in await self.api.get_open_logs(): - if self.get_channel(int(log["channel_id"])) is None: + if log.get("channel_id") is None or self.get_channel(int(log["channel_id"])) is None: logger.debug("Unable to resolve thread with channel %s.", log["channel_id"]) log_data = await self.api.post_log( log["channel_id"], @@ -611,7 +626,10 @@ async def on_ready(self): if log_data: logger.debug("Successfully closed thread with channel %s.", log["channel_id"]) else: - logger.debug("Failed to close thread with channel %s, skipping.", log["channel_id"]) + logger.debug( + "Failed to close thread with channel %s, skipping.", + log["channel_id"], + ) other_guilds = [guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild}] if any(other_guilds): @@ -870,7 +888,8 @@ async def get_thread_cooldown(self, author: discord.Member): @staticmethod async def add_reaction( - msg, reaction: typing.Union[discord.Emoji, discord.Reaction, discord.PartialEmoji, str] + msg, + reaction: typing.Union[discord.Emoji, discord.Reaction, discord.PartialEmoji, str], ) -> bool: if reaction != "disable": try: @@ -880,6 +899,36 @@ async def add_reaction( return False return True + async def _queue_dm_message(self, message: discord.Message) -> None: + """Queue DM messages to ensure they're processed in order per user.""" + user_id = message.author.id + + if user_id not in self._message_queues: + self._message_queues[user_id] = asyncio.Queue() + # Start processing task for this user + self.loop.create_task(self._process_user_messages(user_id)) + + await self._message_queues[user_id].put(message) + + async def _process_user_messages(self, user_id: int) -> None: + """Process messages for a specific user in order.""" + queue = self._message_queues[user_id] + + while True: + try: + # Wait for a message with timeout to clean up inactive queues + message = await asyncio.wait_for(queue.get(), timeout=300) # 5 minutes + await self.process_dm_modmail(message) + queue.task_done() + except asyncio.TimeoutError: + # Clean up inactive queue + if queue.empty(): + self._message_queues.pop(user_id, None) + break + except Exception as e: + logger.error(f"Error processing message for user {user_id}: {e}", exc_info=True) + queue.task_done() + async def process_dm_modmail(self, message: discord.Message) -> None: """Processes messages sent to the bot.""" blocked = await self._process_blocked(message) @@ -1055,13 +1104,33 @@ def __init__(self, original_message, ref_message): if thread and thread.snoozed: await thread.restore_from_snooze() self.threads.cache[thread.id] = thread - # Update the DB with the new channel_id after restoration - if thread.channel: - await self.api.logs.update_one( - {"recipient.id": str(thread.id)}, {"$set": {"channel_id": str(thread.channel.id)}} + # No need to re-fetch the thread - it's already restored and cached properly + + # If the previous thread was closed with delete_channel=True the channel object + # stored on the thread will now be invalid (deleted). In some rare race cases + # the thread can still be returned from the cache (or reconstructed) while the + # channel lookup returns None, causing downstream relay attempts to raise + # discord.NotFound ("Channel not found when trying to send message."). Treat + # this situation as "no active thread" so the user's new DM starts a fresh + # thread instead of silently failing. + try: + if ( + thread + and thread.channel + and isinstance(thread.channel, discord.TextChannel) + and self.get_channel(getattr(thread.channel, "id", None)) is None + ): + logger.info( + "Stale thread detected for %s (channel deleted). Purging cache entry and creating new thread.", + message.author, ) - # Re-fetch the thread object to ensure channel is valid - thread = await self.threads.find(recipient=message.author) + # Best-effort removal; ignore if already gone. + self.threads.cache.pop(thread.id, None) + thread = None + except Exception: + # If any attribute access fails, fall back to treating it as closed. + self.threads.cache.pop(getattr(thread, "id", None), None) + thread = None if thread is None: delta = await self.get_thread_cooldown(message.author) @@ -1075,7 +1144,10 @@ def __init__(self, original_message, ref_message): ) return - if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): + if self.config["dm_disabled"] in ( + DMDisabled.NEW_THREADS, + DMDisabled.ALL_THREADS, + ): embed = discord.Embed( title=self.config["disabled_new_thread_title"], color=self.error_color, @@ -1085,11 +1157,17 @@ def __init__(self, original_message, ref_message): text=self.config["disabled_new_thread_footer"], icon_url=self.get_guild_icon(guild=message.guild, size=128), ) - logger.info("A new thread was blocked from %s due to disabled Modmail.", message.author) + logger.info( + "A new thread was blocked from %s due to disabled Modmail.", + message.author, + ) await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) thread = await self.threads.create(message.author, message=message) + # If thread menu is enabled, thread creation is deferred until user selects an option. + if getattr(thread, "_pending_menu", False): + return else: if self.config["dm_disabled"] == DMDisabled.ALL_THREADS: embed = discord.Embed( @@ -1101,7 +1179,10 @@ def __init__(self, original_message, ref_message): text=self.config["disabled_current_thread_footer"], icon_url=self.get_guild_icon(guild=message.guild, size=128), ) - logger.info("A message was blocked from %s due to disabled Modmail.", message.author) + logger.info( + "A message was blocked from %s due to disabled Modmail.", + message.author, + ) await self.add_reaction(message, blocked_emoji) return await message.channel.send(embed=embed) @@ -1111,6 +1192,49 @@ def __init__(self, original_message, ref_message): except Exception: logger.error("Failed to send message:", exc_info=True) await self.add_reaction(message, blocked_emoji) + + try: + # Re-check channel existence + if thread and thread.channel and isinstance(thread.channel, discord.TextChannel): + if self.get_channel(thread.channel.id) is None: + logger.info( + "Relay failed due to deleted channel for %s; creating new thread.", + message.author, + ) + self.threads.cache.pop(thread.id, None) + new_thread = await self.threads.create(message.author, message=message) + if not getattr(new_thread, "_pending_menu", False) and not new_thread.cancelled: + try: + await new_thread.send(message) + except Exception: + logger.error( + "Failed to relay message after creating new thread:", + exc_info=True, + ) + else: + for user in new_thread.recipients: + if user != message.author: + try: + await new_thread.send(message, user) + except Exception: + logger.error( + "Failed to send message to additional recipient:", + exc_info=True, + ) + await self.add_reaction(message, sent_emoji) + self.dispatch( + "thread_reply", + new_thread, + False, + message, + False, + False, + ) + except Exception: + logger.warning( + "Unexpected failure in DM relay/new-thread follow-up block.", + exc_info=True, + ) else: for user in thread.recipients: # send to all other recipients @@ -1223,7 +1347,12 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if trigger: invoker = re.search(trigger, message.content).group(0) else: - trigger = next(filter(lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys())) + trigger = next( + filter( + lambda x: x.lower() in message.content.lower(), + self.auto_triggers.keys(), + ) + ) if trigger: invoker = trigger.lower() @@ -1356,7 +1485,7 @@ async def process_commands(self, message): return if isinstance(message.channel, discord.DMChannel): - return await self.process_dm_modmail(message) + return await self._queue_dm_message(message) ctxs = await self.get_contexts(message) for ctx in ctxs: @@ -1368,11 +1497,44 @@ async def process_commands(self, message): ) checks.has_permissions(PermissionLevel.INVALID)(ctx.command) + # Check if thread is unsnoozing and queue command if so + thread = await self.threads.find(channel=ctx.channel) + if thread and thread._unsnoozing: + queued = await thread.queue_command(ctx, ctx.command) + if queued: + # Send a brief acknowledgment that command is queued + try: + await ctx.message.add_reaction("⏳") + except Exception as e: + logger.warning("Failed to add queued-reaction: %s", e) + continue + await self.invoke(ctx) continue thread = await self.threads.find(channel=ctx.channel) if thread is not None: + # If thread is snoozed (moved), auto-unsnooze when a mod sends a message directly in channel + behavior = (self.config.get("snooze_behavior") or "delete").lower() + if thread.snoozed and behavior == "move": + if not thread.snooze_data: + try: + log_entry = await self.api.logs.find_one( + {"recipient.id": str(thread.id), "snoozed": True} + ) + if log_entry: + thread.snooze_data = log_entry.get("snooze_data") + except Exception: + logger.debug( + "Failed to add queued command reaction (⏳).", + exc_info=True, + ) + try: + await thread.restore_from_snooze() + # refresh local cache + self.threads.cache[thread.id] = thread + except Exception as e: + logger.warning("Auto-unsnooze on direct message failed: %s", e) anonymous = False plain = False if self.config.get("anon_reply_without_command"): @@ -1385,7 +1547,9 @@ async def process_commands(self, message): or self.config.get("anon_reply_without_command") or self.config.get("plain_reply_without_command") ): - await thread.reply(message, anonymous=anonymous, plain=plain) + # When replying without a command in a thread channel, use the raw content + # from the sent message as reply text while still preserving attachments. + await thread.reply(message, message.content, anonymous=anonymous, plain=plain) elif ctx.invoked_with: exc = commands.CommandNotFound('Command "{}" is not found'.format(ctx.invoked_with)) self.dispatch("command_error", ctx, exc) @@ -1406,7 +1570,10 @@ async def on_typing(self, channel, user, _): try: await thread.channel.typing() except Exception: - pass + logger.debug( + "Failed to trigger typing indicator in recipient DM.", + exc_info=True, + ) else: if not self.config.get("mod_typing"): return @@ -1419,7 +1586,11 @@ async def on_typing(self, channel, user, _): try: await user.typing() except Exception: - pass + logger.debug( + "Failed to trigger typing for recipient %s.", + getattr(user, "id", "?"), + exc_info=True, + ) async def handle_reaction_events(self, payload): user = self.get_user(payload.user_id) @@ -1492,7 +1663,7 @@ async def handle_reaction_events(self, payload): logger.warning("Failed to find linked message for reactions: %s", e) return - if self.config["transfer_reactions"] and linked_messages is not [None]: + if self.config["transfer_reactions"] and linked_messages != [None]: if payload.event_type == "REACTION_ADD": for msg in linked_messages: await self.add_reaction(msg, reaction) @@ -1525,7 +1696,10 @@ async def handle_react_to_contact(self, payload): await message.remove_reaction(payload.emoji, member) await message.add_reaction(emoji_fmt) # bot adds as well - if self.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): + if self.config["dm_disabled"] in ( + DMDisabled.NEW_THREADS, + DMDisabled.ALL_THREADS, + ): embed = discord.Embed( title=self.config["disabled_new_thread_title"], color=self.error_color, @@ -1541,6 +1715,19 @@ async def handle_react_to_contact(self, payload): ) return await member.send(embed=embed) + # Check if user has a snoozed thread + existing_thread = await self.threads.find(recipient=member) + if existing_thread and existing_thread.snoozed: + # Unsnooze the thread + await existing_thread.restore_from_snooze() + self.threads.cache[existing_thread.id] = existing_thread + # Send notification to the thread channel + if existing_thread.channel: + await existing_thread.channel.send( + f"ℹ️ {member.mention} reacted to contact and their snoozed thread has been unsnoozed." + ) + return + ctx = await self.get_context(message) await ctx.invoke(self.get_command("contact"), users=[member], manual_trigger=False) @@ -1574,12 +1761,30 @@ async def on_guild_channel_delete(self, channel): await self.config.update() return - audit_logs = self.modmail_guild.audit_logs(limit=10, action=discord.AuditLogAction.channel_delete) - found_entry = False - async for entry in audit_logs: - if int(entry.target.id) == channel.id: - found_entry = True - break + # Attempt to attribute channel deletion to a moderator via audit logs. + # This requires the "View Audit Log" permission; if missing, skip silently. + if not self.modmail_guild.me.guild_permissions.view_audit_log: + logger.debug( + "Skipping audit log lookup for deleted channel %d: missing view_audit_log permission.", + channel.id, + ) + return + + try: + audit_logs = self.modmail_guild.audit_logs(limit=10, action=discord.AuditLogAction.channel_delete) + found_entry = False + async for entry in audit_logs: + if int(entry.target.id) == channel.id: + found_entry = True + break + except discord.Forbidden: + logger.debug( + "Forbidden when fetching audit logs for deleted channel %d (missing permission).", channel.id + ) + return + except discord.HTTPException as e: + logger.debug("HTTPException when fetching audit logs for deleted channel %d: %s", channel.id, e) + return if not found_entry: logger.debug("Cannot find the audit log entry for channel delete of %d.", channel.id) @@ -1676,7 +1881,12 @@ async def on_message_delete(self, message): await thread.delete_message(message, note=False) embed = discord.Embed(description="Successfully deleted message.", color=self.main_color) except ValueError as e: - if str(e) not in {"DM message not found.", "Malformed thread message."}: + # Treat common non-fatal cases as benign: relay counterpart not present, note embeds, etc. + if str(e) not in { + "DM message not found.", + "Malformed thread message.", + "Thread message not found.", + }: logger.debug("Failed to find linked message to delete: %s", e) embed = discord.Embed(description="Failed to delete message.", color=self.error_color) else: @@ -1715,7 +1925,11 @@ async def on_error(self, event_method, *args, **kwargs): logger.error("Unexpected exception:", exc_info=sys.exc_info()) async def on_command_error( - self, context: commands.Context, exception: Exception, *, unhandled_by_cog: bool = False + self, + context: commands.Context, + exception: Exception, + *, + unhandled_by_cog: bool = False, ) -> None: if not unhandled_by_cog: command = context.command @@ -1729,7 +1943,10 @@ async def on_command_error( try: await context.typing() except Exception: - pass + logger.debug( + "Failed to start typing context for command error feedback.", + exc_info=True, + ) await context.send(embed=discord.Embed(color=self.error_color, description=str(exception))) elif isinstance(exception, commands.CommandNotFound): logger.warning("CommandNotFound: %s", exception) @@ -1760,7 +1977,10 @@ async def on_command_error( ) logger.warning("CheckFailure: %s", exception) elif isinstance(exception, commands.DisabledCommand): - logger.info("DisabledCommand: %s is trying to run eval but it's disabled", context.author.name) + logger.info( + "DisabledCommand: %s is trying to run eval but it's disabled", + context.author.name, + ) else: logger.error("Unexpected exception:", exc_info=exception) @@ -1792,7 +2012,13 @@ async def post_metadata(self): } ) else: - data.update({"owner_name": info.owner.name, "owner_id": info.owner.id, "team": False}) + data.update( + { + "owner_name": info.owner.name, + "owner_id": info.owner.id, + "team": False, + } + ) async with self.session.post("https://api.modmail.dev/metadata", json=data): logger.debug("Uploading metadata to Modmail server.") @@ -1845,7 +2071,7 @@ async def autoupdate(self): user = data["user"] embed.add_field( name="Merge Commit", - value=f"[`{short_sha}`]({html_url}) " f"{message} - {user['username']}", + value=f"[`{short_sha}`]({html_url}) {message} - {user['username']}", ) embed.set_author( name=user["username"] + " - Updating Bot", @@ -1892,7 +2118,10 @@ async def autoupdate(self): logger.info("Bot has been updated.") channel = self.update_channel - if self.hosting_method in (HostingMethod.PM2, HostingMethod.SYSTEMD): + if self.hosting_method in ( + HostingMethod.PM2, + HostingMethod.SYSTEMD, + ): embed = discord.Embed(title="Bot has been updated", color=self.main_color) embed.set_footer( text=f"Updating Modmail v{self.version} " f"-> v{latest.version} {message}" diff --git a/cogs/modmail.py b/cogs/modmail.py index fa6c01666b..0a97888646 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -7,6 +7,7 @@ import discord from discord.ext import commands +from discord.ext import tasks from discord.ext.commands.view import StringView from discord.ext.commands.cooldowns import BucketType from discord.role import Role @@ -29,6 +30,74 @@ class Modmail(commands.Cog): def __init__(self, bot): self.bot = bot + self._snoozed_cache = [] + self._auto_unsnooze_task = self.bot.loop.create_task(self.auto_unsnooze_task()) + + async def auto_unsnooze_task(self): + await self.bot.wait_until_ready() + last_db_query = 0 + while not self.bot.is_closed(): + now = datetime.now(timezone.utc) + try: + # Query DB every 2 minutes + if (now.timestamp() - last_db_query) > 120: + snoozed_threads = await self.bot.api.logs.find( + {"snooze_until": {"$gte": now.isoformat()}} + ).to_list(None) + self._snoozed_cache = snoozed_threads or [] + last_db_query = now.timestamp() + # Check cache every 10 seconds + to_unsnooze = [] + for thread_data in list(self._snoozed_cache): + snooze_until = thread_data.get("snooze_until") + recipient = thread_data.get("recipient") + if not recipient or not recipient.get("id"): + continue + thread_id = int(recipient.get("id")) + if snooze_until: + try: + dt = parser.isoparse(snooze_until) + except Exception: + continue + if now >= dt: + to_unsnooze.append(thread_data) + for thread_data in to_unsnooze: + recipient = thread_data.get("recipient") + if not recipient or not recipient.get("id"): + continue + thread_id = int(recipient.get("id")) + thread = self.bot.threads.cache.get(thread_id) or await self.bot.threads.find( + id=thread_id + ) + if thread and thread.snoozed: + await thread.restore_from_snooze() + logging.info(f"[AUTO-UNSNOOZE] Thread {thread_id} auto-unsnoozed.") + try: + channel = thread.channel + if channel: + await channel.send("⏰ This thread has been automatically unsnoozed.") + except Exception as e: + logger.info( + "Failed to notify channel after auto-unsnooze: %s", + e, + ) + self._snoozed_cache.remove(thread_data) + except Exception as e: + logging.error(f"Error in auto_unsnooze_task: {e}") + await asyncio.sleep(10) + + def _resolve_user(self, user_str): + """Helper to resolve a user from mention, ID, or username.""" + import re + + if not user_str: + return None + if user_str.isdigit(): + return int(user_str) + match = re.match(r"<@!?(\d+)>", user_str) + if match: + return int(match.group(1)) + return None def _resolve_user(self, user_str): """Helper to resolve a user from mention, ID, or username.""" @@ -179,16 +248,22 @@ async def snippet(self, ctx, *, name: str.lower = None): else: val = self.bot.snippets[snippet_name] embed = discord.Embed( - title=f'Snippet - "{snippet_name}":', description=val, color=self.bot.main_color + title=f'Snippet - "{snippet_name}":', + description=val, + color=self.bot.main_color, ) return await ctx.send(embed=embed) if not self.bot.snippets: embed = discord.Embed( - color=self.bot.error_color, description="You dont have any snippets at the moment." + color=self.bot.error_color, + description="You dont have any snippets at the moment.", ) embed.set_footer(text=f'Check "{self.bot.prefix}help snippet add" to add a snippet.') - embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) + embed.set_author( + name="Snippets", + icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128), + ) return await ctx.send(embed=embed) embeds = [discord.Embed(color=self.bot.main_color) for _ in range((len(self.bot.snippets) // 10) + 1)] @@ -448,7 +523,10 @@ async def move(self, ctx, *, arguments): silent = any(word in silent_words for word in options.split()) await thread.channel.move( - category=category, end=True, sync_permissions=True, reason=f"{ctx.author} moved this thread." + category=category, + end=True, + sync_permissions=True, + reason=f"{ctx.author} moved this thread.", ) if self.bot.config["thread_move_notify"] and not silent: @@ -471,21 +549,24 @@ async def move(self, ctx, *, arguments): await self.bot.add_reaction(ctx.message, sent_emoji) async def send_scheduled_close_message(self, ctx, after, silent=False): - human_delta = human_timedelta(after.dt) + """Send a scheduled close notice only to the staff thread channel. + Uses Discord relative timestamp formatting for better UX. + """ + ts = int((after.dt if after.dt.tzinfo else after.dt.replace(tzinfo=timezone.utc)).timestamp()) embed = discord.Embed( title="Scheduled close", - description=f"This thread will{' silently' if silent else ''} close in {human_delta}.", + description=f"This thread will{' silently' if silent else ''} close <t:{ts}:R>.", color=self.bot.error_color, ) - if after.arg and not silent: embed.add_field(name="Message", value=after.arg) - embed.set_footer(text="Closing will be cancelled if a thread message is sent.") embed.timestamp = after.dt - await ctx.send(embed=embed) + thread = getattr(ctx, "thread", None) + if thread and ctx.channel == thread.channel: + await thread.channel.send(embed=embed) @commands.command(usage="[after] [close message]") @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -526,7 +607,8 @@ async def close( if thread.close_task is not None or thread.auto_close_task is not None: await thread.cancel_closure(all=True) embed = discord.Embed( - color=self.bot.error_color, description="Scheduled close has been cancelled." + color=self.bot.error_color, + description="Scheduled close has been cancelled.", ) else: embed = discord.Embed( @@ -625,7 +707,8 @@ async def unnotify(self, ctx, *, user_or_role: Union[discord.Role, User, str.low mentions.remove(mention) await self.bot.config.update() embed = discord.Embed( - color=self.bot.main_color, description=f"{mention} will no longer be notified." + color=self.bot.main_color, + description=f"{mention} will no longer be notified.", ) return await ctx.send(embed=embed) @@ -736,7 +819,8 @@ async def msglink(self, ctx, message_id: int): continue if not found: embed = discord.Embed( - color=self.bot.error_color, description="Message not found or no longer exists." + color=self.bot.error_color, + description="Message not found or no longer exists.", ) else: embed = discord.Embed(color=self.bot.main_color, description=message.jump_url) @@ -968,7 +1052,8 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role, to_exec = [] if not silent: description = self.bot.formatter.format( - self.bot.config["private_removed_from_group_response"], moderator=ctx.author + self.bot.config["private_removed_from_group_response"], + moderator=ctx.author, ) em = discord.Embed( title=self.bot.config["private_removed_from_group_title"], @@ -1072,7 +1157,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, tag = str(get_top_role(ctx.author, self.bot.config["use_hoisted_top_role"])) name = self.bot.config["anon_username"] if name is None: - name = tag + name = "Anonymous" avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) @@ -1163,7 +1248,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro tag = str(get_top_role(ctx.author, self.bot.config["use_hoisted_top_role"])) name = self.bot.config["anon_username"] if name is None: - name = tag + name = "Anonymous" avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) @@ -1370,10 +1455,10 @@ async def reply(self, ctx, *, msg: str = ""): automatically embedding image URLs. """ + # Ensure logs record only the reply text, not the command. ctx.message.content = msg - async with safe_typing(ctx): - await ctx.thread.reply(ctx.message) + await ctx.thread.reply(ctx.message, msg) @commands.command(aliases=["formatreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1391,11 +1476,15 @@ async def freply(self, ctx, *, msg: str = ""): automatically embedding image URLs. """ msg = self.bot.formatter.format( - msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + msg, + channel=ctx.channel, + recipient=ctx.thread.recipient, + author=ctx.message.author, ) + # Ensure logs record only the reply text, not the command. ctx.message.content = msg async with safe_typing(ctx): - await ctx.thread.reply(ctx.message) + await ctx.thread.reply(ctx.message, msg) @commands.command(aliases=["formatanonreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1413,11 +1502,15 @@ async def fareply(self, ctx, *, msg: str = ""): automatically embedding image URLs. """ msg = self.bot.formatter.format( - msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + msg, + channel=ctx.channel, + recipient=ctx.thread.recipient, + author=ctx.message.author, ) + # Ensure logs record only the reply text, not the command. ctx.message.content = msg async with safe_typing(ctx): - await ctx.thread.reply(ctx.message, anonymous=True) + await ctx.thread.reply(ctx.message, msg, anonymous=True) @commands.command(aliases=["formatplainreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1435,11 +1528,15 @@ async def fpreply(self, ctx, *, msg: str = ""): automatically embedding image URLs. """ msg = self.bot.formatter.format( - msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + msg, + channel=ctx.channel, + recipient=ctx.thread.recipient, + author=ctx.message.author, ) + # Ensure logs record only the reply text, not the command. ctx.message.content = msg async with safe_typing(ctx): - await ctx.thread.reply(ctx.message, plain=True) + await ctx.thread.reply(ctx.message, msg, plain=True) @commands.command(aliases=["formatplainanonreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1457,11 +1554,15 @@ async def fpareply(self, ctx, *, msg: str = ""): automatically embedding image URLs. """ msg = self.bot.formatter.format( - msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + msg, + channel=ctx.channel, + recipient=ctx.thread.recipient, + author=ctx.message.author, ) + # Ensure logs record only the reply text, not the command. ctx.message.content = msg async with safe_typing(ctx): - await ctx.thread.reply(ctx.message, anonymous=True, plain=True) + await ctx.thread.reply(ctx.message, msg, anonymous=True, plain=True) @commands.command(aliases=["anonreply", "anonymousreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1476,9 +1577,10 @@ async def areply(self, ctx, *, msg: str = ""): Edit the `anon_username`, `anon_avatar_url` and `anon_tag` config variables to do so. """ + # Ensure logs record only the reply text, not the command. ctx.message.content = msg async with safe_typing(ctx): - await ctx.thread.reply(ctx.message, anonymous=True) + await ctx.thread.reply(ctx.message, msg, anonymous=True) @commands.command(aliases=["plainreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1490,9 +1592,10 @@ async def preply(self, ctx, *, msg: str = ""): Supports attachments and images as well as automatically embedding image URLs. """ + # Ensure logs record only the reply text, not the command. ctx.message.content = msg async with safe_typing(ctx): - await ctx.thread.reply(ctx.message, plain=True) + await ctx.thread.reply(ctx.message, msg, plain=True) @commands.command(aliases=["plainanonreply", "plainanonymousreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1504,9 +1607,10 @@ async def pareply(self, ctx, *, msg: str = ""): Supports attachments and images as well as automatically embedding image URLs. """ + # Ensure logs record only the reply text, not the command. ctx.message.content = msg async with safe_typing(ctx): - await ctx.thread.reply(ctx.message, anonymous=True, plain=True) + await ctx.thread.reply(ctx.message, msg, anonymous=True, plain=True) @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1521,6 +1625,13 @@ async def note(self, ctx, *, msg: str = ""): async with safe_typing(ctx): msg = await ctx.thread.note(ctx.message) await msg.pin() + # Acknowledge and clean up the invoking command message + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + try: + await ctx.message.delete(delay=3) + except (discord.Forbidden, discord.NotFound): + pass @note.command(name="persistent", aliases=["persist"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1534,6 +1645,13 @@ async def note_persistent(self, ctx, *, msg: str = ""): msg = await ctx.thread.note(ctx.message, persistent=True) await msg.pin() await self.bot.api.create_note(recipient=ctx.thread.recipient, message=ctx.message, message_id=msg.id) + # Acknowledge and clean up the invoking command message + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + try: + await ctx.message.delete(delay=3) + except (discord.Forbidden, discord.NotFound) as e: + logger.debug(f"Failed to delete note command message: {e}") @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) @@ -1567,6 +1685,29 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): @checks.has_permissions(PermissionLevel.REGULAR) async def selfcontact(self, ctx): """Creates a thread with yourself""" + # Check if user already has a thread + existing_thread = await self.bot.threads.find(recipient=ctx.author) + if existing_thread: + if existing_thread.snoozed: + # Unsnooze the thread + msg = await ctx.send("ℹ️ You had a snoozed thread. Unsnoozing now...") + await existing_thread.restore_from_snooze() + self.bot.threads.cache[existing_thread.id] = existing_thread + try: + await msg.delete(delay=10) + except (discord.Forbidden, discord.NotFound): + pass + return + else: + # Thread already exists and is active + embed = discord.Embed( + title="Thread not created", + description=f"A thread for you already exists in {existing_thread.channel.mention}.", + color=self.bot.error_color, + ) + await ctx.send(embed=embed, delete_after=10) + return + await ctx.invoke(self.contact, users=[ctx.author]) @commands.command(usage="<user> [category] [options]") @@ -1575,7 +1716,12 @@ async def contact( self, ctx, users: commands.Greedy[ - Union[Literal["silent", "silently"], discord.Member, discord.User, discord.Role] + Union[ + Literal["silent", "silently"], + discord.Member, + discord.User, + discord.Role, + ] ], *, category: SimilarCategoryConverter = None, @@ -1625,9 +1771,14 @@ async def contact( users += u.members users.remove(u) + snoozed_users = [] for u in list(users): exists = await self.bot.threads.find(recipient=u) if exists: + # Check if thread is snoozed + if exists.snoozed: + snoozed_users.append(u) + continue errors.append(f"A thread for {u} already exists.") if exists.channel: errors[-1] += f" in {exists.channel.mention}" @@ -1641,6 +1792,21 @@ async def contact( errors.append(f"{ref} currently blocked from contacting {self.bot.user.name}.") users.remove(u) + # Handle snoozed users - unsnooze them and return early + if snoozed_users: + for u in snoozed_users: + thread = await self.bot.threads.find(recipient=u) + if thread and thread.snoozed: + msg = await ctx.send(f"ℹ️ {u.mention} had a snoozed thread. Unsnoozing now...") + await thread.restore_from_snooze() + self.bot.threads.cache[thread.id] = thread + try: + await msg.delete(delay=10) + except (discord.Forbidden, discord.NotFound) as e: + logger.debug(f"Failed to delete message (likely already deleted or lacking permissions): {e}") + # Don't try to create a new thread - we just unsnoozed existing ones + return + if len(users) > 5: errors.append("Group conversations only support 5 users.") users = [] @@ -1653,11 +1819,14 @@ async def contact( title = None if manual_trigger: # not react to contact - embed = discord.Embed(title=title, color=self.bot.error_color, description="\n".join(errors)) + embed = discord.Embed( + title=title, + color=self.bot.error_color, + description="\n".join(errors), + ) await ctx.send(embed=embed, delete_after=10) if not users: - # end return creator = ctx.author if manual_trigger else users[0] @@ -1673,7 +1842,10 @@ async def contact( if thread.cancelled: return - if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): + if self.bot.config["dm_disabled"] in ( + DMDisabled.NEW_THREADS, + DMDisabled.ALL_THREADS, + ): logger.info("Contacting user %s when Modmail DM is disabled.", users[0]) if not silent and not self.bot.config.get("thread_contact_silently"): @@ -1713,8 +1885,10 @@ async def contact( if manual_trigger: sent_emoji, _ = await self.bot.retrieve_emoji() await self.bot.add_reaction(ctx.message, sent_emoji) - await asyncio.sleep(5) - await ctx.message.delete() + try: + await ctx.message.delete(delay=5) + except (discord.Forbidden, discord.NotFound): + pass @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.MODERATOR) @@ -2015,7 +2189,9 @@ async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): ) else: embed = discord.Embed( - title="Error", description=f"{mention} is not blocked.", color=self.bot.error_color + title="Error", + description=f"{mention} is not blocked.", + color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -2155,7 +2331,9 @@ async def repair(self, ctx): thread.ready = True logger.info("Setting current channel's topic to User ID and created new thread.") await ctx.channel.edit( - reason="Fix broken Modmail thread", name=name, topic=f"User ID: {user.id}" + reason="Fix broken Modmail thread", + name=name, + topic=f"User ID: {user.id}", ) return await self.bot.add_reaction(ctx.message, sent_emoji) @@ -2267,31 +2445,129 @@ async def isenable(self, ctx): @checks.thread_only() async def snooze(self, ctx, *, duration: UserFriendlyTime = None): """ - Snooze this thread: deletes the channel, keeps the ticket open in DM, and restores it when the user replies or a moderator unsnoozes it. - Optionally specify a duration, e.g. 'snooze 2d' for 2 days. - Uses config: max_snooze_time, snooze_title, snooze_text + Snooze this thread. Behavior depends on config: + - delete (default): deletes the channel and restores it later + - move: moves the channel to the configured snoozed category + Optionally specify a duration, e.g. 'snooze 2d' for 2 days. + Uses config: snooze_default_duration, snooze_title, snooze_text """ thread = ctx.thread if thread.snoozed: await ctx.send("This thread is already snoozed.") logging.info(f"[SNOOZE] Thread for {getattr(thread.recipient, 'id', None)} already snoozed.") return - max_snooze = self.bot.config.get("max_snooze_time") - if max_snooze is None: - max_snooze = 604800 - max_snooze = int(max_snooze) + # Default snooze duration with safe fallback + try: + default_snooze = int(self.bot.config.get("snooze_default_duration", 604800)) + except (ValueError, TypeError): + default_snooze = 604800 if duration: snooze_for = int((duration.dt - duration.now).total_seconds()) - if snooze_for > max_snooze: - snooze_for = max_snooze + snooze_for = min(snooze_for, default_snooze) else: - snooze_for = max_snooze + snooze_for = default_snooze + + # Capacity pre-check: if behavior is move, ensure snoozed category has room (<49 channels) + behavior = (self.bot.config.get("snooze_behavior") or "delete").lower() + if behavior == "move": + snoozed_cat_id = self.bot.config.get("snoozed_category_id") + target_category = None + if snoozed_cat_id: + try: + target_category = self.bot.modmail_guild.get_channel(int(snoozed_cat_id)) + except Exception: + target_category = None + # Auto-create snoozed category if missing + if not isinstance(target_category, discord.CategoryChannel): + try: + logging.info("Auto-creating snoozed category for move-based snoozing.") + # Hide category by default; only bot can view/manage + overwrites = { + self.bot.modmail_guild.default_role: discord.PermissionOverwrite(view_channel=False) + } + bot_member = self.bot.modmail_guild.me + if bot_member is not None: + overwrites[bot_member] = discord.PermissionOverwrite( + view_channel=True, + send_messages=True, + read_message_history=True, + manage_channels=True, + manage_messages=True, + attach_files=True, + embed_links=True, + add_reactions=True, + ) + target_category = await self.bot.modmail_guild.create_category( + name="Snoozed Threads", + overwrites=overwrites, + reason="Auto-created snoozed category for move-based snoozing", + ) + try: + await self.bot.config.set("snoozed_category_id", target_category.id) + await self.bot.config.update() + except Exception as e: + logging.warning("Failed to persist snoozed_category_id: %s", e) + try: + await ctx.send( + "⚠️ Created snoozed category but failed to save it to config. Please set `snoozed_category_id` manually." + ) + except Exception as e: + logging.info( + "Failed to notify about snoozed category persistence issue: %s", + e, + ) + await ctx.send( + embed=discord.Embed( + title="Snoozed category created", + description=( + f"Created category {target_category.mention if hasattr(target_category, 'mention') else target_category.name} " + "and set it as `snoozed_category_id`." + ), + color=self.bot.main_color, + ) + ) + except Exception as e: + await ctx.send( + embed=discord.Embed( + title="Could not create snoozed category", + description=( + "I couldn't create a category automatically. Please ensure I have Manage Channels " + "permission, or set `snoozed_category_id` manually." + ), + color=self.bot.error_color, + ) + ) + logging.warning("Failed to auto-create snoozed category: %s", e) + # Capacity check after ensuring category exists + if isinstance(target_category, discord.CategoryChannel): + try: + if len(target_category.channels) >= 49: + await ctx.send( + embed=discord.Embed( + title="Snooze unavailable", + description=( + "The configured snoozed category is full (49 channels). " + "Unsnooze or move some channels out before snoozing more." + ), + color=self.bot.error_color, + ) + ) + return + except Exception as e: + logging.debug("Failed to check snoozed category channel count: %s", e) - # Storing snooze_start and snooze_for in the log entry + # Store snooze_until timestamp for reliable auto-unsnooze now = datetime.now(timezone.utc) + snooze_until = now + timedelta(seconds=snooze_for) await self.bot.api.logs.update_one( {"recipient.id": str(thread.id)}, - {"$set": {"snooze_start": now.isoformat(), "snooze_for": snooze_for}}, + { + "$set": { + "snooze_start": now.isoformat(), + "snooze_for": snooze_for, + "snooze_until": snooze_until.isoformat(), + } + }, ) embed = discord.Embed( title=self.bot.config.get("snooze_title") or "Thread Snoozed", @@ -2327,6 +2603,11 @@ async def unsnooze(self, ctx, *, user: str = None): try: user_obj = await self.bot.get_or_fetch_user(user_id) except Exception: + logger.debug( + "Failed fetching user during unsnooze; falling back to partial object (%s).", + user_id, + exc_info=True, + ) user_obj = discord.Object(user_id) if user_obj: thread = await self.bot.threads.find(recipient=user_obj) @@ -2411,32 +2692,30 @@ async def snoozed(self, ctx): await ctx.send("Snoozed threads:\n" + "\n".join(lines)) async def cog_load(self): - self.bot.loop.create_task(self.snooze_auto_unsnooze_task()) + self.snooze_auto_unsnooze.start() - async def snooze_auto_unsnooze_task(self): + @tasks.loop(seconds=10) + async def snooze_auto_unsnooze(self): + now = datetime.now(timezone.utc) + snoozed = await self.bot.api.logs.find({"snoozed": True}).to_list(None) + for entry in snoozed: + snooze_until = entry.get("snooze_until") + if snooze_until: + try: + until_dt = datetime.fromisoformat(snooze_until) + if now >= until_dt: + thread = await self.bot.threads.find(recipient_id=int(entry["recipient"]["id"])) + if thread and thread.snoozed: + await thread.restore_from_snooze() + except (ValueError, TypeError) as e: + logger.debug( + "Failed parsing snooze_until timestamp for auto-unsnooze loop: %s", + e, + ) + + @snooze_auto_unsnooze.before_loop + async def _snooze_auto_unsnooze_before(self): await self.bot.wait_until_ready() - while True: - now = datetime.now(timezone.utc) - snoozed = await self.bot.api.logs.find({"snoozed": True}).to_list(None) - for entry in snoozed: - start = entry.get("snooze_start") - snooze_for = entry.get("snooze_for") - if not start: - continue - start_dt = datetime.fromisoformat(start) - if snooze_for is not None: - duration = int(snooze_for) - else: - max_snooze = self.bot.config.get("max_snooze_time") - if max_snooze is None: - max_snooze = 604800 - duration = int(max_snooze) - if (now - start_dt).total_seconds() > duration: - # Auto-unsnooze - thread = await self.bot.threads.find(recipient_id=int(entry["recipient"]["id"])) - if thread and thread.snoozed: - await thread.restore_from_snooze() - await asyncio.sleep(60) async def process_dm_modmail(self, message: discord.Message) -> None: # ... existing code ... diff --git a/cogs/plugins.py b/cogs/plugins.py index c7dceb7283..aa4ad5a65c 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -251,7 +251,11 @@ async def load_plugin(self, plugin): if stderr: logger.debug("[stderr]\n%s.", stderr.decode()) - logger.error("Failed to download requirements for %s.", plugin.ext_string, exc_info=True) + logger.error( + "Failed to download requirements for %s.", + plugin.ext_string, + exc_info=True, + ) raise InvalidPluginError(f"Unable to download requirements: ```\n{stderr.decode()}\n```") if os.path.exists(USER_SITE): @@ -361,7 +365,10 @@ async def plugins_add(self, ctx, *, plugin_name: str): return if str(plugin) in self.bot.config["plugins"]: - embed = discord.Embed(description="This plugin is already installed.", color=self.bot.error_color) + embed = discord.Embed( + description="This plugin is already installed.", + color=self.bot.error_color, + ) return await ctx.send(embed=embed) if plugin.name in self.bot.cogs: @@ -470,7 +477,8 @@ async def plugins_remove(self, ctx, *, plugin_name: str): pass # dir not empty embed = discord.Embed( - description="The plugin is successfully uninstalled.", color=self.bot.main_color + description="The plugin is successfully uninstalled.", + color=self.bot.main_color, ) await ctx.send(embed=embed) @@ -486,7 +494,8 @@ async def update_plugin(self, ctx, plugin_name): async with safe_typing(ctx): embed = discord.Embed( - description=f"Successfully updated {plugin.name}.", color=self.bot.main_color + description=f"Successfully updated {plugin.name}.", + color=self.bot.main_color, ) await self.download_plugin(plugin, force=True) if self.bot.config.get("enable_plugins"): @@ -570,7 +579,8 @@ async def plugins_reset(self, ctx): logger.warning("Removing %s.", entry.name) embed = discord.Embed( - description="Successfully purged all plugins from the bot.", color=self.bot.main_color + description="Successfully purged all plugins from the bot.", + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -598,7 +608,8 @@ async def plugins_loaded(self, ctx): if not self.loaded_plugins: embed = discord.Embed( - description="There are no plugins currently loaded.", color=self.bot.error_color + description="There are no plugins currently loaded.", + color=self.bot.error_color, ) return await ctx.send(embed=embed) @@ -666,7 +677,10 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N matches = get_close_matches(plugin_name, self.registry.keys()) if matches: - embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{m}`" for m in matches)) + embed.add_field( + name="Perhaps you meant:", + value="\n".join(f"`{m}`" for m in matches), + ) return await ctx.send(embed=embed) diff --git a/cogs/threadmenu.py b/cogs/threadmenu.py new file mode 100644 index 0000000000..7f9e193844 --- /dev/null +++ b/cogs/threadmenu.py @@ -0,0 +1,830 @@ +import json +import asyncio +from copy import copy as _copy + +import discord +from discord.ext import commands + +from core import checks +from core.models import PermissionLevel + + +class ThreadCreationMenuCore(commands.Cog): + """Core-integrated thread menu configuration and management. + + This Cog exposes the same commands as the legacy plugin to manage menu options, + but stores settings in core config (no plugin DB). + """ + + def __init__(self, bot): + self.bot = bot + + # ----- helpers ----- + def _get_conf(self) -> dict: + return { + "enabled": bool(self.bot.config.get("thread_creation_menu_enabled")), + "options": self.bot.config.get("thread_creation_menu_options") or {}, + "submenus": self.bot.config.get("thread_creation_menu_submenus") or {}, + "timeout": int(self.bot.config.get("thread_creation_menu_timeout") or 20), + "close_on_timeout": bool(self.bot.config.get("thread_creation_menu_close_on_timeout")), + "anonymous_menu": bool(self.bot.config.get("thread_creation_menu_anonymous_menu")), + "embed_text": self.bot.config.get("thread_creation_menu_embed_text") + or "Please select an option.", + "dropdown_placeholder": self.bot.config.get("thread_creation_menu_dropdown_placeholder") + or "Select an option to contact the staff team.", + "embed_title": self.bot.config.get("thread_creation_menu_embed_title"), + "embed_footer": self.bot.config.get("thread_creation_menu_embed_footer"), + "embed_thumbnail_url": self.bot.config.get("thread_creation_menu_embed_thumbnail_url"), + "embed_footer_icon_url": self.bot.config.get("thread_creation_menu_embed_footer_icon_url"), + "embed_color": self.bot.config.get("thread_creation_menu_embed_color"), + } + + async def _save_conf(self, conf: dict): + await self.bot.config.set("thread_creation_menu_enabled", conf.get("enabled", False)) + await self.bot.config.set("thread_creation_menu_options", conf.get("options", {}), convert=False) + await self.bot.config.set("thread_creation_menu_submenus", conf.get("submenus", {}), convert=False) + await self.bot.config.set("thread_creation_menu_timeout", conf.get("timeout", 20)) + await self.bot.config.set( + "thread_creation_menu_close_on_timeout", conf.get("close_on_timeout", False) + ) + await self.bot.config.set("thread_creation_menu_anonymous_menu", conf.get("anonymous_menu", False)) + await self.bot.config.set( + "thread_creation_menu_embed_text", conf.get("embed_text", "Please select an option.") + ) + await self.bot.config.set( + "thread_creation_menu_dropdown_placeholder", + conf.get("dropdown_placeholder", "Select an option to contact the staff team."), + ) + await self.bot.config.set("thread_creation_menu_embed_title", conf.get("embed_title")) + await self.bot.config.set("thread_creation_menu_embed_footer", conf.get("embed_footer")) + await self.bot.config.set("thread_creation_menu_embed_thumbnail_url", conf.get("embed_thumbnail_url")) + await self.bot.config.set( + "thread_creation_menu_embed_footer_icon_url", conf.get("embed_footer_icon_url") + ) + if conf.get("embed_color"): + try: + await self.bot.config.set("thread_creation_menu_embed_color", conf.get("embed_color")) + except Exception: + pass + await self.bot.config.update() + + # ----- commands ----- + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @commands.group(invoke_without_command=True) + async def threadmenu(self, ctx): + """Thread-creation menu settings (core).""" + await ctx.send_help(ctx.command) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu.command(name="toggle") + async def threadmenu_toggle(self, ctx): + """Enable or disable the thread-creation menu. + + Toggles the global on/off state. When disabled, users won't see + or be able to use the interactive thread creation select menu. + """ + conf = self._get_conf() + conf["enabled"] = not conf["enabled"] + await self._save_conf(conf) + await ctx.send(f"Thread-creation menu is now {'enabled' if conf['enabled'] else 'disabled'}.") + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu.command(name="show") + async def threadmenu_show(self, ctx): + """Show all current main-menu options. + + Lists every option (label + description) configured in the root + (non-submenu) select menu so you can review what users will see. + """ + conf = self._get_conf() + if not conf["options"]: + return await ctx.send("There are no options in the main menu.") + embed = discord.Embed(title="Main menu", color=discord.Color.blurple()) + for v in conf["options"].values(): + embed.add_field(name=v["label"], value=v["description"], inline=False) + await ctx.send(embed=embed) + + # ----- options ----- + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu.group(name="option", invoke_without_command=True) + async def threadmenu_option(self, ctx): + """Manage main-menu options (add/remove/edit/show). + + Use subcommands: + - add: interactive wizard to create an option + - remove <label>: delete an option + - edit <label>: interactively modify an option + - show <label>: display full details (type, command/submenu, emoji) + """ + await ctx.send_help(ctx.command) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_option.command(name="show") + async def threadmenu_option_show(self, ctx, *, label: str): + """Show detailed information about a main-menu option.""" + conf = self._get_conf() + key = label.lower().replace(" ", "_") + if key not in conf["options"]: + return await ctx.send("That label does not exist.") + v = conf["options"][key] + embed = discord.Embed(title=v["label"], color=discord.Color.blurple()) + embed.add_field(name="Description", value=v["description"], inline=False) + embed.add_field(name="Emoji", value=v["emoji"], inline=False) + embed.add_field(name="Type", value=v["type"], inline=False) + embed.add_field( + name=("Command" if v["type"] == "command" else "Submenu"), value=v["callback"], inline=False + ) + # Show category if set + cat_id = v.get("category_id") + if cat_id: + guild = self.bot.modmail_guild or ctx.guild + category = guild and guild.get_channel(cat_id) + cat_name = getattr(category, "name", "Unknown/Deleted") + embed.add_field(name="Category", value=f"{cat_name} (ID: {cat_id})", inline=False) + else: + embed.add_field(name="Category", value="Default (main category)", inline=False) + await ctx.send(embed=embed) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_option.command(name="add") + async def threadmenu_option_add(self, ctx): + """Interactive wizard to add a main-menu option.""" + conf = self._get_conf() + + def check(m): + return m.author == ctx.author and m.channel == ctx.channel + + def typecheck(m): + return ( + m.author == ctx.author + and m.channel == ctx.channel + and m.content.lower() + in [ + "command", + "submenu", + ] + ) + + if len(conf["options"]) >= 25: + return await ctx.send("You can only have a maximum of 25 options due to discord limitations.") + + await ctx.send( + "You can type `skip` for non-required steps or `cancel` to cancel the process at any time." + ) + await ctx.send("What is the label of the option?") + label = (await self.bot.wait_for("message", check=check)).content + sanitized_label = label.lower().replace(" ", "_") + + if label.lower() == "cancel": + return await ctx.send("Cancelled.") + + if sanitized_label in conf["options"]: + await ctx.send("That option already exists. Use `threadmenu edit` to edit it.") + return + + await ctx.send("What is the description of the option? (not required)") + description = (await self.bot.wait_for("message", check=check)).content + + if description.lower() == "cancel": + return await ctx.send("Cancelled.") + + if len(description) > 100: + return await ctx.send( + "The description must be less than 100 characters due to discord limitations." + ) + + if description.lower() == "skip": + description = None + + await ctx.send("What is the emoji of the option? (not required)") + emoji = (await self.bot.wait_for("message", check=check)).content + + if emoji.lower() == "cancel": + return await ctx.send("Cancelled.") + + if emoji.lower() == "skip": + emoji = None + + await ctx.send("What is the type of the option? (command/submenu)") + type_ = (await self.bot.wait_for("message", check=typecheck)).content.lower() + + if type_ == "cancel": + return await ctx.send("Cancelled.") + + if type_ == "command": + await ctx.send("What is the command to run for the option?") + else: + await ctx.send("What is the label of the submenu for the option?") + callback = (await self.bot.wait_for("message", check=check)).content + if type_ != "command": + callback = callback.lower().replace(" ", "_") + + if callback.lower() == "cancel": + return await ctx.send("Cancelled.") + + if type_ == "submenu" and callback not in conf["submenus"]: + return await ctx.send("That submenu does not exist. Use `threadmenu submenu create` to add it.") + + # Optional: category where the thread should be created when this option is chosen + await ctx.send( + "Optionally provide a category for threads created via this option (mention, ID, or name).\n" + "Type `default` to use the main category." + ) + category_msg = await self.bot.wait_for("message", check=check) + category_raw = category_msg.content.strip() + category_id: int | None = None + if category_raw.lower() == "cancel": + return await ctx.send("Cancelled.") + if category_raw.lower() not in {"", "default", "none", "skip"}: + guild = self.bot.modmail_guild or ctx.guild + resolved = None + try: + # Try ID + if category_raw.isdigit(): + resolved = guild.get_channel(int(category_raw)) if guild else None + # Try mention <#id> is not valid for categories; fall back to name search + if not resolved and guild: + resolved = discord.utils.find( + lambda c: isinstance(c, discord.CategoryChannel) + and c.name.lower() == category_raw.lower(), + guild.categories, + ) + except Exception: + resolved = None + if isinstance(resolved, discord.CategoryChannel): + category_id = resolved.id + else: + await ctx.send( + "Couldn't resolve that category. I'll default to the main category for this option." + ) + + conf["options"][sanitized_label] = { + "label": label, + "description": description, + "emoji": emoji, + "type": type_, + "callback": callback, + "category_id": category_id, + } + await self._save_conf(conf) + await ctx.send("Option added.") + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_option.command(name="remove") + async def threadmenu_option_remove(self, ctx, *, label: str): + """Remove a main-menu option by label.""" + conf = self._get_conf() + key = label.lower().replace(" ", "_") + if key not in conf["options"]: + return await ctx.send("That option does not exist.") + del conf["options"][key] + await self._save_conf(conf) + await ctx.send("Option removed.") + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_option.command(name="edit") + async def threadmenu_option_edit(self, ctx, *, label: str): + """Interactive wizard to edit a main-menu option.""" + conf = self._get_conf() + key = label.lower().replace(" ", "_") + if key not in conf["options"]: + return await ctx.send("That option does not exist.") + + def check(m): + return m.author == ctx.author and m.channel == ctx.channel + + def typecheck(m): + return ( + m.author == ctx.author + and m.channel == ctx.channel + and m.content.lower() + in [ + "command", + "submenu", + ] + ) + + await ctx.send( + "You can type `skip` for non-required steps (uses previous value) or `cancel` to cancel the process at any time." + "Use `none` to clear the value for non-required steps." + ) + await ctx.send("What is the new description of the option? (not required)") + description = (await self.bot.wait_for("message", check=check)).content + if description.lower() == "cancel": + return await ctx.send("Cancelled.") + + old_description = conf["options"][key]["description"] + + if description.lower() == "skip": + description = old_description + elif description.lower() == "none": + description = None + else: + if len(description) > 100: + return await ctx.send( + "The description must be less than 100 characters due to discord limitations." + ) + + await ctx.send("What is the new emoji of the option?") + emoji = (await self.bot.wait_for("message", check=check)).content + if emoji.lower() == "cancel": + return await ctx.send("Cancelled.") + + old_emoji = conf["options"][key].get("emoji") + + if emoji.lower() == "skip": + emoji = old_emoji + elif emoji.lower() == "none": + emoji = None + + await ctx.send("What is the new type of the option? (command/submenu)") + type_ = (await self.bot.wait_for("message", check=typecheck)).content.lower() + if type_ == "cancel": + return await ctx.send("Cancelled.") + + if type_ == "command": + await ctx.send("What is the new command to run for the option?") + else: + await ctx.send("What is the new label of the new submenu for the option?") + callback = (await self.bot.wait_for("message", check=check)).content + if type_ != "command": + callback = callback.lower().replace(" ", "_") + if callback.lower() == "cancel": + return await ctx.send("Cancelled.") + if type_ == "submenu" and callback not in conf["submenus"]: + return await ctx.send("That submenu does not exist. Use `threadmenu submenu create` to add it.") + + # Category edit (optional) + await ctx.send( + "Optionally provide a new category for this option (mention, ID, or name).\n" + "Send `skip` to keep current setting; send `default` or `none` to clear." + ) + cat_msg = await self.bot.wait_for("message", check=check) + cat_raw = cat_msg.content.strip() + if cat_raw.lower() == "cancel": + return await ctx.send("Cancelled.") + + current = conf["options"][key].get("category_id") + new_category_id = current + if cat_raw.lower() in {"default", "none"}: + new_category_id = None + elif cat_raw.lower() in {"", "skip"}: + new_category_id = current + else: + guild = self.bot.modmail_guild or ctx.guild + resolved = None + try: + if cat_raw.isdigit(): + resolved = guild.get_channel(int(cat_raw)) if guild else None + if not resolved and guild: + resolved = discord.utils.find( + lambda c: isinstance(c, discord.CategoryChannel) + and c.name.lower() == cat_raw.lower(), + guild.categories, + ) + except Exception: + resolved = None + if isinstance(resolved, discord.CategoryChannel): + new_category_id = resolved.id + else: + await ctx.send("Couldn't resolve that category. Keeping previous setting.") + + old_label = conf["options"][key]["label"] + conf["options"][key] = { + "label": old_label, + "description": description, + "emoji": emoji, + "type": type_, + "callback": callback, + "category_id": new_category_id, + } + await self._save_conf(conf) + await ctx.send("Option edited.") + + # ----- submenus ----- + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu.group(name="submenu", invoke_without_command=True) + async def threadmenu_submenu(self, ctx): + """Manage submenus (create/delete/list/show and options within). + + Submenus let you branch the initial select menu into additional + categorized option groups. Use `submenu option` subcommands to + manage the nested options. + """ + await ctx.send_help(ctx.command) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu.command(name="create") + async def threadmenu_submenu_create(self, ctx, *, label: str): + """Create an empty submenu that can hold nested options.""" + conf = self._get_conf() + key = label.lower().replace(" ", "_") + if key in conf["submenus"]: + return await ctx.send( + "That submenu already exists. Please use a unique label or use `threadmenu submenu delete` to delete it." + ) + conf["submenus"][key] = {} + await self._save_conf(conf) + await ctx.send("Submenu created.") + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu.command(name="delete") + async def threadmenu_submenu_delete(self, ctx, *, label: str): + """Delete a submenu and all its options.""" + conf = self._get_conf() + key = label.lower().replace(" ", "_") + if key not in conf["submenus"]: + return await ctx.send("That submenu does not exist.") + del conf["submenus"][key] + await self._save_conf(conf) + await ctx.send("Submenu deleted.") + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu.command(name="list") + async def threadmenu_submenu_list(self, ctx): + """List all submenu keys currently configured.""" + conf = self._get_conf() + if not conf["submenus"]: + return await ctx.send("There are no submenus.") + submenu_list = "Submenus:\n" + ("\n".join(conf["submenus"].keys())) + if len(submenu_list) > 2000: + submenu_list = submenu_list[:1997] + "..." + await ctx.send(submenu_list) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu.command(name="show") + async def threadmenu_submenu_show(self, ctx, *, label: str): + """Show the options configured inside a submenu.""" + conf = self._get_conf() + key = label.lower().replace(" ", "_") + if key not in conf["submenus"]: + return await ctx.send("That submenu does not exist. Use `threadmenu submenu create` to add it.") + if not conf["submenus"][key]: + return await ctx.send(f"There are no options in {key}") + embed = discord.Embed(title=key, color=discord.Color.blurple()) + for v in conf["submenus"][key].values(): + embed.add_field(name=v["label"], value=v["description"], inline=False) + await ctx.send(embed=embed) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu.group(name="option", invoke_without_command=True) + async def threadmenu_submenu_option(self, ctx): + """Manage options within a specific submenu (add/remove/edit).""" + await ctx.send_help(ctx.command) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu_option.command(name="add") + async def threadmenu_submenu_option_add(self, ctx, *, submenu: str): + """Interactive wizard to add an option inside a submenu.""" + conf = self._get_conf() + submenu = submenu.lower().replace(" ", "_") + if submenu not in conf["submenus"]: + return await ctx.send("That submenu does not exist.") + + def check(m): + return m.author == ctx.author and m.channel == ctx.channel + + def typecheck(m): + return ( + m.author == ctx.author + and m.channel == ctx.channel + and m.content.lower() + in [ + "command", + "submenu", + ] + ) + + if len(conf["submenus"][submenu]) >= 24: + return await ctx.send("You can only have a maximum of 24 options due to discord limitations.") + + await ctx.send( + "You can type `skip` for non-required steps or `cancel` to cancel the process at any time." + ) + await ctx.send("What is the label of the option?") + label = (await self.bot.wait_for("message", check=check)).content + sanitized_label = label.lower().replace(" ", "_") + + if label.lower() == "cancel": + return await ctx.send("Cancelled.") + if label.lower() == "main menu": + return await ctx.send("You cannot use that label.") + if sanitized_label in conf["submenus"][submenu]: + await ctx.send("That option already exists. Use `threadmenu submenu edit` to edit it.") + return + + await ctx.send("What is the description of the option? (not required)") + description = (await self.bot.wait_for("message", check=check)).content + if description.lower() == "cancel": + return await ctx.send("Cancelled.") + if len(description) > 100: + return await ctx.send( + "The description must be less than 100 characters due to discord limitations." + ) + + if description.lower() == "skip": + description = None + + await ctx.send("What is the emoji of the option? (not required)") + emoji = (await self.bot.wait_for("message", check=check)).content + if emoji.lower() == "cancel": + return await ctx.send("Cancelled.") + + if emoji.lower() == "skip": + emoji = None + + await ctx.send("What is the type for the option? (command/submenu)") + type_ = (await self.bot.wait_for("message", check=typecheck)).content.lower() + if type_ == "cancel": + return await ctx.send("Cancelled.") + + if type_ == "command": + await ctx.send("What is the command to run for the option?") + else: + await ctx.send("What is the label of the submenu for the option?") + callback = (await self.bot.wait_for("message", check=check)).content + if type_ != "command": + callback = callback.lower().replace(" ", "_") + if type_ == "submenu" and callback not in conf["submenus"]: + return await ctx.send("That submenu does not exist. Use `threadmenu submenu create` to add it.") + + # Optional category for submenu option + await ctx.send( + "Optionally provide a category for threads created via this submenu option (mention, ID, or name).\n" + "Type `default` to use the main category." + ) + category_msg = await self.bot.wait_for("message", check=check) + category_raw = category_msg.content.strip() + category_id: int | None = None + if category_raw.lower() == "cancel": + return await ctx.send("Cancelled.") + if category_raw.lower() not in {"", "default", "none", "skip"}: + guild = self.bot.modmail_guild or ctx.guild + resolved = None + try: + if category_raw.isdigit(): + resolved = guild.get_channel(int(category_raw)) if guild else None + if not resolved and guild: + resolved = discord.utils.find( + lambda c: isinstance(c, discord.CategoryChannel) + and c.name.lower() == category_raw.lower(), + guild.categories, + ) + except Exception: + resolved = None + if isinstance(resolved, discord.CategoryChannel): + category_id = resolved.id + else: + await ctx.send( + "Couldn't resolve that category. I'll default to the main category for this submenu option." + ) + + conf["submenus"][submenu][sanitized_label] = { + "label": label, + "description": description, + "emoji": emoji, + "type": type_, + "callback": callback, + "category_id": category_id, + } + await self._save_conf(conf) + await ctx.send("Option added.") + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu_option.command(name="remove") + async def threadmenu_submenu_option_remove(self, ctx, *, submenu: str): + """Remove an option from a submenu via an interactive prompt.""" + conf = self._get_conf() + submenu = submenu.lower().replace(" ", "_") + if submenu not in conf["submenus"]: + return await ctx.send("That submenu does not exist.") + + def check(m): + return m.author == ctx.author and m.channel == ctx.channel + + await ctx.send("You can send `cancel` at any time to cancel the process.") + await ctx.send("What is the label of the option to remove?") + label = (await self.bot.wait_for("message", check=check)).content + key = label.lower().replace(" ", "_") + if label.lower() == "cancel": + return await ctx.send("Cancelled.") + if key not in conf["submenus"][submenu]: + return await ctx.send("That option does not exist.") + + del conf["submenus"][submenu][key] + await self._save_conf(conf) + await ctx.send("Option removed.") + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu_submenu_option.command(name="edit") + async def threadmenu_submenu_option_edit(self, ctx, *, submenu: str): + """Interactive wizard to edit a submenu option.""" + conf = self._get_conf() + submenu = submenu.lower().replace(" ", "_") + if submenu not in conf["submenus"]: + return await ctx.send("That submenu does not exist. Use `threadmenu submenu create` to add it.") + + def check(m): + return m.author == ctx.author and m.channel == ctx.channel + + def typecheck(m): + return ( + m.author == ctx.author + and m.channel == ctx.channel + and m.content.lower() + in [ + "command", + "submenu", + ] + ) + + await ctx.send( + "You can type `skip` for non-required steps (uses previous value) or `cancel` to cancel the process at any time." + "Use `none` to clear the value for non-required steps." + ) + await ctx.send("What is the label of the option to edit?") + label = (await self.bot.wait_for("message", check=check)).content + key = label.lower().replace(" ", "_") + if label.lower() == "cancel": + return await ctx.send("Cancelled.") + if key not in conf["submenus"][submenu]: + return await ctx.send("That label does not exist.") + + await ctx.send("What is the new description of the option? (not required)") + description = (await self.bot.wait_for("message", check=check)).content + if description.lower() == "cancel": + return await ctx.send("Cancelled.") + + option_data = conf["submenus"][submenu][key] + old_description = option_data.get("description") + + if description.lower() == "skip": + description = old_description + elif description.lower() == "none": + description = None + else: + if len(description) > 100: + return await ctx.send( + "The description must be less than 100 characters due to discord limitations." + ) + + await ctx.send("What is the new emoji of the option? (not required)") + emoji = (await self.bot.wait_for("message", check=check)).content + if emoji.lower() == "cancel": + return await ctx.send("Cancelled.") + + old_emoji = option_data.get("emoji") + + if emoji.lower() == "skip": + emoji = old_emoji + elif emoji.lower() == "none": + emoji = None + + await ctx.send("What is the new type for the option? (command/submenu)") + type_ = (await self.bot.wait_for("message", check=typecheck)).content.lower() + if type_ == "cancel": + return await ctx.send("Cancelled.") + + if type_ == "command": + await ctx.send("What is the command to run for the option?") + else: + await ctx.send("What is the label of the submenu for the option?") + callback = (await self.bot.wait_for("message", check=check)).content + if type_ != "command": + callback = callback.lower().replace(" ", "_") + if callback.lower() == "cancel": + return await ctx.send("Cancelled.") + if type_ == "submenu" and callback not in conf["submenus"]: + return await ctx.send("That submenu does not exist.") + + # Category edit (optional) + await ctx.send( + "Optionally provide a new category for this submenu option (mention, ID, or name).\n" + "Send `skip` to keep current setting; send `default` or `none` to clear." + ) + cat_msg = await self.bot.wait_for("message", check=check) + cat_raw = cat_msg.content.strip() + if cat_raw.lower() == "cancel": + return await ctx.send("Cancelled.") + current = conf["submenus"][submenu][key].get("category_id") + new_category_id = current + if cat_raw.lower() in {"default", "none"}: + new_category_id = None + elif cat_raw.lower() in {"", "skip"}: + new_category_id = current + else: + guild = self.bot.modmail_guild or ctx.guild + resolved = None + try: + if cat_raw.isdigit(): + resolved = guild.get_channel(int(cat_raw)) if guild else None + if not resolved and guild: + resolved = discord.utils.find( + lambda c: isinstance(c, discord.CategoryChannel) + and c.name.lower() == cat_raw.lower(), + guild.categories, + ) + except Exception: + resolved = None + if isinstance(resolved, discord.CategoryChannel): + new_category_id = resolved.id + else: + await ctx.send("Couldn't resolve that category. Keeping previous setting.") + + conf["submenus"][submenu][key]["description"] = description + conf["submenus"][submenu][key]["emoji"] = emoji + conf["submenus"][submenu][key]["type"] = type_ + conf["submenus"][submenu][key]["callback"] = callback + conf["submenus"][submenu][key]["category_id"] = new_category_id + await self._save_conf(conf) + await ctx.send("Option edited.") + + # ----- import/export ----- + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu.command(name="dump_config") + async def threadmenu_dump_config(self, ctx): + """Dump the current core thread menu config to a file.""" + conf = self._get_conf() + with open("thread_creation_menu_config.json", "w", encoding="utf-8") as f: + json.dump(conf, f, indent=4) + await ctx.send(file=discord.File("thread_creation_menu_config.json")) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu.command(name="reset") + async def threadmenu_reset(self, ctx): + """Reset ALL thread-creation menu settings to their defaults. + + This clears options and submenus and restores every key starting with + `thread_creation_menu_` back to the default values. Confirmation required. + This action is irreversible. + """ + warning = ( + "This will clear ALL thread menu options, submenus, and related settings and restore defaults.\n" + "This action is irreversible. Type `confirm` within 30 seconds to proceed, or anything else to cancel." + ) + await ctx.send(warning) + + def check(m: discord.Message) -> bool: + return m.author == ctx.author and m.channel == ctx.channel + + try: + reply = await self.bot.wait_for("message", check=check, timeout=30) + except asyncio.TimeoutError: + return await ctx.send("Timed out — reset cancelled.") + + if reply.content.strip().lower() != "confirm": + return await ctx.send("Reset cancelled.") + + # Reset all `thread_creation_menu_` keys to defaults + defaults = getattr(self.bot.config, "defaults", {}) + keys = [k for k in defaults.keys() if k.startswith("thread_creation_menu_")] + + # Ensure we handle mappings without unwanted conversion + for k in keys: + v = defaults[k] + if k in {"thread_creation_menu_options", "thread_creation_menu_submenus"}: + await self.bot.config.set(k, v, convert=False) + else: + await self.bot.config.set(k, v) + + # Also disable the menu explicitly for clarity + await self.bot.config.set("thread_creation_menu_enabled", False) + await self.bot.config.update() + + await ctx.send( + f"Thread-creation menu configuration has been reset to defaults (reset {len(keys)} keys)." + ) + + @checks.has_permissions(PermissionLevel.ADMINISTRATOR) + @threadmenu.command(name="load_config") + async def threadmenu_load_config(self, ctx): + """Load the thread menu config from an attached file.""" + if not ctx.message.attachments: + return await ctx.send("You must attach a json file to load the config from.") + b = await ctx.message.attachments[0].read() + json_data = b.decode("utf-8") + try: + data = json.loads(json_data) + except json.decoder.JSONDecodeError: + return await ctx.send("Invalid json file.") + + # minimal validation + required = { + "enabled", + "options", + "submenus", + "timeout", + "close_on_timeout", + "anonymous_menu", + "embed_text", + "dropdown_placeholder", + } + if not required.issubset(set(data.keys())): + return await ctx.send("Config file missing required keys.") + + await self._save_conf(data) + await ctx.send("Successfully loaded config into core.") + + +async def setup(bot): + await bot.add_cog(ThreadCreationMenuCore(bot)) diff --git a/cogs/utility.py b/cogs/utility.py index 16eeafc4d6..c420ee7979 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1,4 +1,4 @@ -from core.utils import trigger_typing, truncate, safe_typing +from core.utils import trigger_typing, truncate import asyncio import inspect import os @@ -13,6 +13,7 @@ from subprocess import PIPE from textwrap import indent from typing import Union +import typing import discord from discord.enums import ActivityType, Status @@ -31,7 +32,7 @@ UnseenFormatter, getLogger, ) -from core.utils import trigger_typing, truncate, DummyParam +from core.utils import DummyParam from core.paginator import EmbedPaginatorSession, MessagePaginatorSession @@ -118,7 +119,11 @@ async def send_bot_help(self, mapping): bot = self.context.bot # always come first - default_cogs = [bot.get_cog("Modmail"), bot.get_cog("Utility"), bot.get_cog("Plugins")] + default_cogs = [ + bot.get_cog("Modmail"), + bot.get_cog("Utility"), + bot.get_cog("Plugins"), + ] default_cogs.extend(c for c in cogs if c not in default_cogs) @@ -200,7 +205,9 @@ async def send_error_message(self, error): if snippet_aliases: embed.add_field( - name="Aliases to this snippet:", value=",".join(snippet_aliases), inline=False + name="Aliases to this snippet:", + value=",".join(snippet_aliases), + inline=False, ) return await self.get_destination().send(embed=embed) @@ -221,7 +228,10 @@ async def send_error_message(self, error): await self.context.bot.config.update() else: if len(values) == 1: - embed = discord.Embed(title=f"{command} is an alias.", color=self.context.bot.main_color) + embed = discord.Embed( + title=f"{command} is an alias.", + color=self.context.bot.main_color, + ) embed.add_field(name=f"`{command}` points to:", value=values[0]) else: embed = discord.Embed( @@ -693,7 +703,9 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member, current = self.bot.config["mention"] if not user_or_role: embed = discord.Embed( - title="Current mention:", color=self.bot.main_color, description=str(current) + title="Current mention:", + color=self.bot.main_color, + description=str(current), ) elif ( len(user_or_role) == 1 @@ -810,11 +822,38 @@ async def config_set(self, ctx, key: str.lower, *, value: str): color=self.bot.main_color, description=f"Set `{key}` to `{self.bot.config[key]}`.", ) + # If turning on move-based snoozing, remind to set snoozed_category_id + if key == "snooze_behavior": + behavior = ( + str(self.bot.config.get("snooze_behavior", convert=False)).strip().lower().strip('"') + ) + if behavior == "move": + cat_id = self.bot.config.get("snoozed_category_id", convert=False) + valid = False + if cat_id: + try: + cat_obj = self.bot.modmail_guild.get_channel(int(str(cat_id))) + valid = isinstance(cat_obj, discord.CategoryChannel) + except Exception: + valid = False + if not valid: + example = f"`{self.bot.prefix}config set snoozed_category_id <category_id>`" + embed.add_field( + name="Action required", + value=( + "You set `snooze_behavior` to `move`. Please set `snoozed_category_id` " + "to the category where snoozed threads should be moved.\n" + f"For example: {example}" + ), + inline=False, + ) except InvalidConfigError as exc: embed = exc.embed else: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." + title="Error", + color=self.bot.error_color, + description=f"{key} is an invalid key.", ) valid_keys = [f"`{k}`" for k in sorted(keys)] embed.add_field(name="Valid keys", value=truncate(", ".join(valid_keys), 1024)) @@ -836,7 +875,9 @@ async def config_remove(self, ctx, *, key: str.lower): ) else: embed = discord.Embed( - title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." + title="Error", + color=self.bot.error_color, + description=f"{key} is an invalid key.", ) valid_keys = [f"`{k}`" for k in sorted(keys)] embed.add_field(name="Valid keys", value=", ".join(valid_keys)) @@ -873,21 +914,44 @@ async def config_get(self, ctx, *, key: str.lower = None): ) else: - embed = discord.Embed( - color=self.bot.main_color, - description="Here is a list of currently set configuration variable(s).", - ) - embed.set_author( - name="Current config(s):", - icon_url=self.bot.user.display_avatar.url if self.bot.user.display_avatar else None, - ) - config = self.bot.config.filter_default(self.bot.config) - - for name, value in config.items(): - if name in self.bot.config.public_keys: - embed.add_field(name=name, value=f"`{value}`", inline=False) + # Build one or more embeds, each with up to 25 fields + base_desc = "Here is a list of currently set configuration variable(s)." + author_name = "Current config(s):" + icon = self.bot.user.display_avatar.url if self.bot.user.display_avatar else None - return await ctx.send(embed=embed) + config = self.bot.config.filter_default(self.bot.config) + items = [(name, value) for name, value in config.items() if name in self.bot.config.public_keys] + + embeds: list[discord.Embed] = [] + chunk: list[tuple[str, typing.Any]] = [] + for pair in items: + chunk.append(pair) + if len(chunk) == 15: + e = discord.Embed(color=self.bot.main_color, description=base_desc) + e.set_author(name=author_name, icon_url=icon) + for name, value in chunk: + e.add_field(name=name, value=f"`{value}`", inline=False) + embeds.append(e) + chunk = [] + + if chunk: + e = discord.Embed(color=self.bot.main_color, description=base_desc) + e.set_author(name=author_name, icon_url=icon) + for name, value in chunk: + e.add_field(name=name, value=f"`{value}`", inline=False) + embeds.append(e) + + # Send one or many embeds depending on count. + # In the single-key branch above, variable 'embed' exists; in this multi branch, we only use 'embeds'. + if key: + return await ctx.send(embed=embed) + else: + if not embeds: + return await ctx.send("No public configuration keys are set.") + # Use the existing paginator consistently + paginator = EmbedPaginatorSession(ctx, *embeds) + await paginator.run() + return @config.command(name="help", aliases=["info"]) @checks.has_permissions(PermissionLevel.OWNER) @@ -907,7 +971,10 @@ async def config_help(self, ctx, key: str.lower = None): description=f"`{key}` is an invalid key.", ) if closest: - embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest)) + embed.add_field( + name="Perhaps you meant:", + value="\n".join(f"`{x}`" for x in closest), + ) return await ctx.send(embed=embed) config_help = self.bot.config.config_help @@ -998,7 +1065,9 @@ async def alias(self, ctx, *, name: str.lower = None): if len(values) == 1: embed = discord.Embed( - title=f'Alias - "{name}":', description=values[0], color=self.bot.main_color + title=f'Alias - "{name}":', + description=values[0], + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -1016,10 +1085,14 @@ async def alias(self, ctx, *, name: str.lower = None): if not self.bot.aliases: embed = discord.Embed( - color=self.bot.error_color, description="You dont have any aliases at the moment." + color=self.bot.error_color, + description="You dont have any aliases at the moment.", ) embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') - embed.set_author(name="Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) + embed.set_author( + name="Aliases", + icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128), + ) return await ctx.send(embed=embed) embeds = [] @@ -1028,7 +1101,8 @@ async def alias(self, ctx, *, name: str.lower = None): description = utils.format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) embed.set_author( - name="Command Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128) + name="Command Aliases", + icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128), ) embeds.append(embed) @@ -1048,7 +1122,9 @@ async def alias_raw(self, ctx, *, name: str.lower): val = utils.truncate(utils.escape_code_block(val), 2048 - 7) embed = discord.Embed( - title=f'Raw alias - "{name}":', description=f"```\n{val}```", color=self.bot.main_color + title=f'Raw alias - "{name}":', + description=f"```\n{val}```", + color=self.bot.main_color, ) return await ctx.send(embed=embed) @@ -1066,7 +1142,9 @@ async def make_alias(self, name, value, action): if len(values) > 25: embed = discord.Embed( - title="Error", description="Too many steps, max=25.", color=self.bot.error_color + title="Error", + description="Too many steps, max=25.", + color=self.bot.error_color, ) return embed @@ -1558,7 +1636,11 @@ def _get_perm(self, ctx, name, type_): @permissions.command(name="get", usage="[@user] or [command/level/override] [name]") @checks.has_permissions(PermissionLevel.OWNER) async def permissions_get( - self, ctx, user_or_role: Union[discord.Role, utils.User, str], *, name: str = None + self, + ctx, + user_or_role: Union[discord.Role, utils.User, str], + *, + name: str = None, ): """ View the currently-set permissions. @@ -2080,7 +2162,11 @@ async def update(self, ctx, *, flag: str = ""): res = res.decode("utf-8").rstrip() if err and not res: - embed = discord.Embed(title="Update failed", description=err, color=self.bot.error_color) + embed = discord.Embed( + title="Update failed", + description=err, + color=self.bot.error_color, + ) await ctx.send(embed=embed) elif res != "Already up to date.": @@ -2134,7 +2220,7 @@ async def eval_(self, ctx, *, body: str): body = utils.cleanup_code(body) stdout = StringIO() - to_compile = f'async def func():\n{indent(body, " ")}' + to_compile = f"async def func():\n{indent(body, ' ')}" def paginate(text: str): """Simple generator that paginates text.""" diff --git a/core/clients.py b/core/clients.py index 459ee2ea6b..90f09b3b48 100644 --- a/core/clients.py +++ b/core/clients.py @@ -133,7 +133,9 @@ async def request( return await self._get_response_data(resp) @staticmethod - async def _get_response_data(response: ClientResponse) -> Union[Dict[str, Any], str]: + async def _get_response_data( + response: ClientResponse, + ) -> Union[Dict[str, Any], str]: """ Internal method to convert the response data to `dict` if the data is a json object, or to `str` (raw response) if the data is not a valid json. @@ -476,7 +478,11 @@ async def setup_indexes(self): logger.info('Creating "text" index for logs collection.') logger.info("Name: %s", index_name) await coll.create_index( - [("messages.content", "text"), ("messages.author.name", "text"), ("key", "text")] + [ + ("messages.content", "text"), + ("messages.author.name", "text"), + ("key", "text"), + ] ) logger.debug("Successfully configured and verified database indexes.") @@ -540,7 +546,11 @@ async def find_log_entry(self, key: str) -> list: return await self.logs.find(query, projection).to_list(None) async def get_latest_user_logs(self, user_id: Union[str, int]): - query = {"recipient.id": str(user_id), "guild_id": str(self.bot.guild_id), "open": False} + query = { + "recipient.id": str(user_id), + "guild_id": str(self.bot.guild_id), + "open": False, + } projection = {"messages": {"$slice": 5}} logger.debug("Retrieving user %s latest logs.", user_id) @@ -679,7 +689,9 @@ async def append_log( } return await self.logs.find_one_and_update( - {"channel_id": channel_id}, {"$push": {"messages": data}}, return_document=True + {"channel_id": channel_id}, + {"$push": {"messages": data}}, + return_document=True, ) async def post_log(self, channel_id: Union[int, str], data: dict) -> dict: @@ -689,7 +701,11 @@ async def post_log(self, channel_id: Union[int, str], data: dict) -> dict: async def search_closed_by(self, user_id: Union[int, str]): return await self.logs.find( - {"guild_id": str(self.bot.guild_id), "open": False, "closer.id": str(user_id)}, + { + "guild_id": str(self.bot.guild_id), + "open": False, + "closer.id": str(user_id), + }, {"messages": {"$slice": 5}}, ).to_list(None) diff --git a/core/config.py b/core/config.py index a704443bb1..0e45b00175 100644 --- a/core/config.py +++ b/core/config.py @@ -70,6 +70,7 @@ class ConfigManager: "thread_creation_self_contact_response": "You have opened a Modmail thread.", "thread_creation_contact_response": "{creator.name} has opened a Modmail thread.", "thread_creation_title": "Thread Created", + "thread_creation_send_dm_embed": True, "thread_close_footer": "Replying will create a new thread", "thread_close_title": "Thread Closed", "thread_close_response": "{closer.mention} has closed this Modmail thread.", @@ -135,11 +136,34 @@ class ConfigManager: "thread_min_characters_response": "Your message is too short to create a thread. Please provide more details.", "thread_min_characters_footer": "Minimum {min_characters} characters required.", # --- SNOOZE FEATURE CONFIG --- - "max_snooze_time": 604800, # in seconds, default 7 days + "snooze_default_duration": 604800, # in seconds, default 7 days "snooze_title": "Thread Snoozed", "snooze_text": "This thread has been snoozed. The channel will be restored when the user replies or a moderator unsnoozes it.", "unsnooze_text": "This thread has been unsnoozed and restored.", "unsnooze_notify_channel": "thread", # Can be a channel ID or 'thread' for the thread's own channel + # snooze behavior + "snooze_behavior": "delete", # 'delete' to delete channel, 'move' to move channel to snoozed_category_id + "snoozed_category_id": None, # Category ID to move snoozed channels into when snooze_behavior == 'move' + # attachments persistence for delete-behavior snooze + "snooze_store_attachments": False, # when True, store image attachments as base64 in snooze_data + "snooze_attachment_max_bytes": 4_194_304, # 4 MiB per attachment cap to avoid Mongo 16MB limit + "unsnooze_history_limit": None, # Limit number of messages replayed when unsnoozing (None = all messages) + # --- THREAD CREATION MENU --- + "thread_creation_menu_timeout": 30, # Default interaction timeout for the thread-creation menu (in seconds) + "thread_creation_menu_close_on_timeout": False, + "thread_creation_menu_anonymous_menu": False, + "thread_creation_menu_embed_text": "Please select an option.", + "thread_creation_menu_dropdown_placeholder": "Select an option to contact the staff team.", + "thread_creation_menu_selection_log": True, # log selected option in newly created thread channel + "thread_creation_menu_precreate_channel": False, + # thread-creation menu embed customization + "thread_creation_menu_embed_title": None, + "thread_creation_menu_embed_footer": None, + "thread_creation_menu_embed_thumbnail_url": None, + "thread_creation_menu_embed_image_url": None, + "thread_creation_menu_embed_large_image": False, + "thread_creation_menu_embed_footer_icon_url": None, + "thread_creation_menu_embed_color": str(discord.Color.green()), } private_keys = { @@ -161,6 +185,10 @@ class ConfigManager: "notification_squad": {}, "subscriptions": {}, "closures": {}, + # Thread creation menu + "thread_creation_menu_enabled": False, + "thread_creation_menu_options": {}, # main menu options mapping key -> {label, description, emoji, type, callback} + "thread_creation_menu_submenus": {}, # submenu name -> submenu options (same structure as options) # misc "plugins": [], "aliases": {}, @@ -196,9 +224,23 @@ class ConfigManager: "data_collection": True, } - colors = {"mod_color", "recipient_color", "main_color", "error_color"} + colors = { + "mod_color", + "recipient_color", + "main_color", + "error_color", + "thread_creation_menu_embed_color", + } + + time_deltas = { + "account_age", + "guild_age", + "thread_auto_close", + "thread_cooldown", + "log_expiration", + } - time_deltas = {"account_age", "guild_age", "thread_auto_close", "thread_cooldown", "log_expiration"} + duration_seconds = {"snooze_default_duration"} booleans = { "use_user_id_channel_name", @@ -239,6 +281,16 @@ class ConfigManager: "use_hoisted_top_role", "enable_presence_intent", "registry_plugins_only", + # snooze + "snooze_store_attachments", + # thread creation menu booleans + "thread_creation_send_dm_embed", + "thread_creation_menu_enabled", + "thread_creation_menu_close_on_timeout", + "thread_creation_menu_anonymous_menu", + "thread_creation_menu_selection_log", + "thread_creation_menu_precreate_channel", + "thread_creation_menu_embed_large_image", } enums = { @@ -275,6 +327,7 @@ def populate_cache(self) -> dict: data.update({k.lower(): v for k, v in json.load(f).items() if k.lower() in self.all_keys}) except json.JSONDecodeError: logger.critical("Failed to load config.json env values.", exc_info=True) + self._cache = data config_help_json = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config_help.json") @@ -360,6 +413,14 @@ def get(self, key: str, *, convert: bool = True) -> typing.Any: logger.warning("Invalid %s %s.", key, value) value = self.remove(key) + elif key in self.duration_seconds: + if not isinstance(value, int): + try: + value = int(value) + except (ValueError, TypeError): + logger.warning("Invalid %s %s.", key, value) + value = self.remove(key) + elif key in self.force_str: # Temporary: as we saved in int previously, leading to int32 overflow, # this is transitioning IDs to strings @@ -388,6 +449,10 @@ async def set(self, key: str, item: typing.Any, convert=True) -> None: if not convert: return self.__setitem__(key, item) + if "channel" in key or "category" in key: + if isinstance(item, str) and item not in {"thread", "NONE"}: + item = item.strip("<#>") + if key in self.colors: try: hex_ = str(item) @@ -440,6 +505,25 @@ async def set(self, key: str, item: typing.Any, convert=True) -> None: except ValueError: raise InvalidConfigError("Must be a yes/no value.") + elif key in self.duration_seconds: + if isinstance(item, int): + return self.__setitem__(key, item) + try: + converter = UserFriendlyTime() + time = await converter.convert(None, str(item), now=discord.utils.utcnow()) + if time.arg: + raise ValueError + except BadArgument as exc: + raise InvalidConfigError(*exc.args) + except Exception as e: + logger.debug(e) + raise InvalidConfigError( + "Unrecognized time, please use a duration like '5 days' or '2 hours'." + ) + now = discord.utils.utcnow() + duration_seconds = int((time.dt - now).total_seconds()) + return self.__setitem__(key, duration_seconds) + elif key in self.enums: if isinstance(item, self.enums[key]): # value is an enum type diff --git a/core/config_help.json b/core/config_help.json index 462e4e1c03..b5832935c7 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -492,6 +492,18 @@ "See also: `thread_creation_response`, `thread_creation_footer`, `thread_close_title`." ] }, + "thread_creation_send_dm_embed": { + "default": "Yes", + "description": "When set to `yes`, the bot will send an embed message to the recipient notifying them that a new thread was created. Set to `no` to suppress the initial DM embed. When suppressed and `recipient_thread_close` is enabled, the close emoji will be added to the user's original message instead so they may still close the thread.", + "examples": [ + "`{prefix}config set thread_creation_send_dm_embed no`", + "`{prefix}config set thread_creation_send_dm_embed yes`" + ], + "notes": [ + "Useful if you prefer not to send an extra DM to recipients when creating threads.", + "See also: `recipient_thread_close`, `thread_creation_response`, `thread_creation_title`." + ] + }, "thread_close_footer": { "default": "\"Replying will create a new thread\"", "description": "This is the message embed footer sent to the recipient upon the closure of a thread.", @@ -1266,15 +1278,16 @@ "See also: `thread_min_characters`, `thread_min_characters_title`, `thread_min_characters_response`." ] }, - "max_snooze_time": { + "snooze_default_duration": { "default": "604800 (7 days in seconds)", - "description": "The maximum duration in seconds that a thread can be snoozed. When a thread is snoozed, it is temporarily hidden until the user replies or a moderator unsnoozes it.", + "description": "The default duration that a thread will be snoozed when no duration is specified. When a thread is snoozed, it is temporarily hidden until the user replies or a moderator unsnoozes it.", "examples": [ - "`{prefix}config set max_snooze_time 86400` (1 day)", - "`{prefix}config set max_snooze_time 1209600` (14 days)" + "`{prefix}config set snooze_default_duration 7 days`", + "`{prefix}config set snooze_default_duration 2 hours`", + "`{prefix}config set snooze_default_duration 86400` (raw seconds also accepted)" ], "notes": [ - "The value must be specified in seconds.", + "Accepts user-friendly time like '5 days', '2 hours', or raw seconds.", "See also: `snooze_title`, `snooze_text`, `unsnooze_text`, `unsnooze_notify_channel`." ] }, @@ -1285,7 +1298,7 @@ "`{prefix}config set snooze_title Thread Paused`" ], "notes": [ - "See also: `snooze_text`, `unsnooze_title`, `max_snooze_time`." + "See also: `snooze_text`, `unsnooze_title`, `snooze_default_duration`." ] }, "snooze_text": { @@ -1296,7 +1309,7 @@ ], "notes": [ "Discord flavoured markdown is fully supported in `snooze_text`.", - "See also: `snooze_title`, `unsnooze_text`, `max_snooze_time`." + "See also: `snooze_title`, `unsnooze_text`, `snooze_default_duration`." ] }, "unsnooze_text": { @@ -1307,7 +1320,7 @@ ], "notes": [ "Discord flavoured markdown is fully supported in `unsnooze_text`.", - "See also: `snooze_text`, `unsnooze_notify_channel`, `max_snooze_time`." + "See also: `snooze_text`, `unsnooze_notify_channel`, `snooze_default_duration`." ] }, "unsnooze_notify_channel": { @@ -1320,7 +1333,265 @@ "notes": [ "If set to \"thread\", the notification will be sent in the thread channel itself.", "If set to a channel ID, the notification will be sent to that specific channel.", - "See also: `unsnooze_text`, `max_snooze_time`." + "See also: `unsnooze_text`, `snooze_default_duration`." + ] + }, + "snooze_behavior": { + "default": "\"delete\"", + "description": "Controls how snoozing behaves. 'delete' removes the thread channel and restores it later; 'move' moves the channel into the 'snoozed_category_id' without deleting it.", + "examples": [ + "`{prefix}config set snooze_behavior delete`", + "`{prefix}config set snooze_behavior move`" + ], + "notes": [ + "When set to 'move', set `snoozed_category_id` to a valid Category ID.", + "When unsnoozed, channels moved will return to their original category and position when possible; if original no longer exists they will be moved under `main_category_id`." + ] + }, + "snoozed_category_id": { + "default": "None", + "description": "The category ID where snoozed threads are moved when `snooze_behavior` is set to 'move'.", + "examples": [ + "`{prefix}config set snoozed_category_id 123456789012345678`" + ], + "notes": [ + "Only used when `snooze_behavior` is 'move'.", + "If not set or invalid, the channel will remain in its current category or the bot will fall back to deleting on failure." + ] + }, + "snooze_store_attachments": { + "default": "No", + "description": "When enabled and `snooze_behavior` is 'delete', image attachments are stored as base64 within the snooze data so they can be re-uploaded on unsnooze, preserving media even if the original channel was deleted.", + "examples": [ + "`{prefix}config set snooze_store_attachments yes`", + "`{prefix}config set snooze_store_attachments no`" + ], + "notes": [ + "Only applies to delete-behavior snoozes. In move-behavior, attachments remain in the channel history.", + "To avoid exceeding Mongo's 16MB document size, consider also adjusting `snooze_attachment_max_bytes`." + ] + }, + "snooze_attachment_max_bytes": { + "default": "4194304 (4 MiB)", + "description": "Maximum size per attachment to store as base64 when `snooze_store_attachments` is enabled.", + "examples": [ + "`{prefix}config set snooze_attachment_max_bytes 2097152` (2 MiB)", + "`{prefix}config set snooze_attachment_max_bytes 0` (disable size check; not recommended)" + ], + "notes": [ + "This cap helps prevent hitting MongoDB's 16MB per-document limit when storing large attachments.", + "Non-image files are not stored as base64 and will be preserved as their original URLs if available." + ] + }, + "unsnooze_history_limit": { + "default": "None (all messages replayed)", + "description": "Limits the number of messages replayed when a thread is unsnoozed. When set, only the last N messages will be displayed in the restored channel.", + "examples": [ + "`{prefix}config set unsnooze_history_limit 50`", + "`{prefix}config set unsnooze_history_limit 100`" + ], + "notes": [ + "All messages remain stored in the database regardless of this limit.", + "Set to None or delete this config to replay all messages when unsnoozing.", + "See also: `snooze_behavior`, `unsnooze_text`." + ] + }, + "thread_creation_menu_enabled": { + "default": "Disabled", + "description": "Enables the thread creation menu which asks users to pick an option before the Modmail thread channel is created.", + "examples": [ + "`{prefix}config set thread_creation_menu_enabled yes`" + ], + "notes": [ + "When enabled and at least one option is configured, incoming user DMs are paused until a selection is made.", + "If the menu times out without a selection and `thread_creation_menu_close_on_timeout` is enabled, the thread is aborted silently.", + "See also: `thread_creation_menu_options`, `thread_creation_menu_timeout`." + ] + }, + "thread_creation_menu_options": { + "default": "Empty (no options)", + "description": "Mapping of menu option keys to their data (label, description, emoji, type, callback). A non-empty mapping is required to display the menu.", + "examples": [ + "`{prefix}threadmenu option add` (interactive wizard)", + "`{prefix}threadmenu show`" + ], + "notes": [ + "Type can be 'command' (executes a command after creation) or 'submenu' (opens a submenu).", + "Submenu callbacks must reference keys stored in `thread_creation_menu_submenus`.", + "See also: `thread_creation_menu_submenus`." + ] + }, + "thread_creation_menu_submenus": { + "default": "Empty (no submenus)", + "description": "Mapping of submenu keys to submenu option mappings, identical structure to `thread_creation_menu_options` allowing nested selection.", + "examples": [ + "`{prefix}threadmenu submenu create Appeals`", + "`{prefix}threadmenu submenu option add Appeals`" + ], + "notes": [ + "Submenus allow categorizing options beyond the 25 main menu limit (each submenu limited by Discord select menu rules).", + "See also: `thread_creation_menu_options`." + ] + }, + "thread_creation_menu_timeout": { + "default": "30 (seconds)", + "description": "Number of seconds to wait for a user to pick a menu option before timing out.", + "examples": [ + "`{prefix}config set thread_creation_menu_timeout 30`" + ], + "notes": [ + "If the timeout is reached, `thread_creation_menu_close_on_timeout` controls whether the attempt is aborted or the user is asked to message again.", + "See also: `thread_creation_menu_close_on_timeout`." + ] + }, + "thread_creation_menu_close_on_timeout": { + "default": "No", + "description": "Silently aborts thread creation if the user does not select an option before the timeout expires.", + "examples": [ + "`{prefix}config set thread_creation_menu_close_on_timeout yes`" + ], + "notes": [ + "If disabled, the user receives a message telling them to send a new DM to start again.", + "See also: `thread_creation_menu_timeout`." + ] + }, + "thread_creation_menu_anonymous_menu": { + "default": "No", + "description": "If enabled, the initial menu prompt relayed to staff (after creation) is anonymized; only selection details are logged, not the original prompt message author context.", + "examples": [ + "`{prefix}config set thread_creation_menu_anonymous_menu yes`" + ], + "notes": [ + "Does not affect the DM the user sees, only how it's displayed/logged internally.", + "See also: `thread_creation_menu_selection_log`." + ] + }, + "thread_creation_menu_embed_text": { + "default": "\"Please select an option.\"", + "description": "Text shown in the embed above the selection dropdown in the user's DM.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_text Please choose a department`" + ], + "notes": [ + "Keep this concise; users cannot proceed until choosing.", + "See also: `thread_creation_menu_dropdown_placeholder`." + ] + }, + "thread_creation_menu_dropdown_placeholder": { + "default": "\"Select an option to contact the staff team.\"", + "description": "Placeholder text displayed in the dropdown before selection.", + "examples": [ + "`{prefix}config set thread_creation_menu_dropdown_placeholder Pick a topic...`" + ], + "notes": [ + "Appears grayed out inside the select component.", + "See also: `thread_creation_menu_embed_text`." + ] + }, + "thread_creation_menu_selection_log": { + "default": "Yes", + "description": "Logs the chosen menu option (label, type, callback) as a message in the newly created thread channel for moderator visibility.", + "examples": [ + "`{prefix}config set thread_creation_menu_selection_log no`" + ], + "notes": [ + "When disabled, the staff will not see an automatic message with the selection details though commands may still act.", + "See also: `thread_creation_menu_enabled`, `thread_creation_menu_options`." + ] + }, + "thread_creation_menu_precreate_channel": { + "default": "No", + "description": "When enabled, a thread channel is created immediately upon the user's first DM even if the thread creation menu is enabled. The menu is still shown but selection becomes optional and happens after channel creation.", + "examples": [ + "`{prefix}config set thread_creation_menu_precreate_channel yes`" + ], + "notes": [ + "If a user never selects an option the thread remains open in the default/main category.", + "Category-specific option selections will move the channel afterward if a category_id is configured on the option.", + "Confirmation (`confirm_thread_creation`) is only applied in the deferred mode; enabling precreate bypasses the confirm step for menu flows.", + "See also: `thread_creation_menu_enabled`, `thread_creation_menu_options`, `confirm_thread_creation`." + ] + }, + "thread_creation_menu_embed_title": { + "default": "Empty (no title)", + "description": "Optional title at the top of the thread-creation menu embed in the user's DM.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_title Contact the staff team`", + "`{prefix}config delete thread_creation_menu_embed_title` (clear)" + ], + "notes": [ + "See also: `thread_creation_menu_embed_text`." + ] + }, + "thread_creation_menu_embed_footer": { + "default": "Empty (no footer)", + "description": "Optional footer text at the bottom of the menu embed.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_footer Please choose the most relevant option`", + "`{prefix}config delete thread_creation_menu_embed_footer` (clear)" + ], + "notes": [ + "You can also configure an optional footer icon via `thread_creation_menu_embed_footer_icon_url`." + ] + }, + "thread_creation_menu_embed_footer_icon_url": { + "default": "Empty (no icon)", + "description": "Optional URL for the small footer icon displayed next to the footer text.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_footer_icon_url https://example.com/icon.png`", + "`{prefix}config delete thread_creation_menu_embed_footer_icon_url` (clear)" + ], + "notes": [ + "Use a direct image URL (PNG/JPEG/GIF)." + ] + }, + "thread_creation_menu_embed_thumbnail_url": { + "default": "Empty (no thumbnail)", + "description": "Optional thumbnail image shown in the top-right of the menu embed.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_thumbnail_url https://example.com/logo.png`", + "`{prefix}config delete thread_creation_menu_embed_thumbnail_url` (clear)" + ], + "notes": [ + "Use a direct image URL; recommended square image.", + "Consider file size/CDN reliability so it loads quickly for users." + ] + }, + "thread_creation_menu_embed_image_url": { + "default": "Empty (no image)", + "description": "Optional large hero image displayed in the body of the menu embed. If set, this image is shown prominently and takes precedence over the thumbnail.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_image_url https://example.com/banner.png`", + "`{prefix}config delete thread_creation_menu_embed_image_url` (clear)" + ], + "notes": [ + "Use a direct image URL (PNG/JPEG/GIF).", + "When both a thumbnail and image URL are set, the image URL is used as the large embed image while the thumbnail may still be shown in the top-right.", + "See also: `thread_creation_menu_embed_thumbnail_url`, `thread_creation_menu_embed_large_image`." + ] + }, + "thread_creation_menu_embed_large_image": { + "default": "No", + "description": "Promotes the thumbnail to a large hero image when no `thread_creation_menu_embed_image_url` is set. Useful if you want a big image without specifying a separate URL.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_large_image yes`", + "`{prefix}config set thread_creation_menu_embed_large_image no`" + ], + "notes": [ + "Only applies when `thread_creation_menu_embed_image_url` is not set.", + "If both are provided, the explicit image URL takes precedence.", + "See also: `thread_creation_menu_embed_thumbnail_url`, `thread_creation_menu_embed_image_url`." + ] + }, + "thread_creation_menu_embed_color": { + "default": "Green (hex for Discord Color.green)", + "description": "Color for the menu embed's side strip. Accepts hex (e.g. #5865F2) or one of the supported color names.", + "examples": [ + "`{prefix}config set thread_creation_menu_embed_color #5865F2`", + "`{prefix}config set thread_creation_menu_embed_color blurple`" + ], + "notes": [ + "Color names map to the built-in palette (e.g., 'red', 'green', 'blurple')." ] } } \ No newline at end of file diff --git a/core/models.py b/core/models.py index 611db375f0..5f36f12181 100644 --- a/core/models.py +++ b/core/models.py @@ -30,15 +30,15 @@ class ModmailLogger(logging.Logger): @staticmethod def _debug_(*msgs): - return f'{Fore.CYAN}{" ".join(msgs)}{Style.RESET_ALL}' + return f"{Fore.CYAN}{' '.join(msgs)}{Style.RESET_ALL}" @staticmethod def _info_(*msgs): - return f'{Fore.LIGHTMAGENTA_EX}{" ".join(msgs)}{Style.RESET_ALL}' + return f"{Fore.LIGHTMAGENTA_EX}{' '.join(msgs)}{Style.RESET_ALL}" @staticmethod def _error_(*msgs): - return f'{Fore.RED}{" ".join(msgs)}{Style.RESET_ALL}' + return f"{Fore.RED}{' '.join(msgs)}{Style.RESET_ALL}" def debug(self, msg, *args, **kwargs): if self.isEnabledFor(logging.DEBUG): @@ -149,7 +149,8 @@ def format(self, record): log_stream_formatter = logging.Formatter( - "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%m/%d/%y %H:%M:%S" + "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", + datefmt="%m/%d/%y %H:%M:%S", ) log_file_formatter = FileFormatter( @@ -231,7 +232,12 @@ def create_log_handler( formatter = log_file_formatter else: handler = RotatingFileHandler( - filename, mode=mode, encoding=encoding, maxBytes=maxBytes, backupCount=backupCount, **kwargs + filename, + mode=mode, + encoding=encoding, + maxBytes=maxBytes, + backupCount=backupCount, + **kwargs, ) formatter = log_file_formatter @@ -264,7 +270,10 @@ def getLogger(name=None) -> ModmailLogger: def configure_logging(bot) -> None: global ch_debug, log_level, ch - stream_log_format, file_log_format = bot.config["stream_log_format"], bot.config["file_log_format"] + stream_log_format, file_log_format = ( + bot.config["stream_log_format"], + bot.config["file_log_format"], + ) if stream_log_format == "json": ch.setFormatter(json_formatter) @@ -318,7 +327,10 @@ def configure_logging(bot) -> None: non_verbose_log_level = max(d_level, logging.INFO) stream_handler = create_log_handler(level=non_verbose_log_level) if non_verbose_log_level != d_level: - logger.info("Discord logging level (stdout): %s.", logging.getLevelName(non_verbose_log_level)) + logger.info( + "Discord logging level (stdout): %s.", + logging.getLevelName(non_verbose_log_level), + ) logger.info("Discord logging level (logfile): %s.", logging.getLevelName(d_level)) else: logger.info("Discord logging level: %s.", logging.getLevelName(d_level)) diff --git a/core/paginator.py b/core/paginator.py index 48222d283e..bf76bdc2e2 100644 --- a/core/paginator.py +++ b/core/paginator.py @@ -383,7 +383,7 @@ def add_page(self, item: str) -> None: def _set_footer(self): if self.embed is not None: - footer_text = f"Page {self.current+1} of {len(self.pages)}" + footer_text = f"Page {self.current + 1} of {len(self.pages)}" if self.footer_text: footer_text = footer_text + " • " + self.footer_text diff --git a/core/thread.py b/core/thread.py index d380552694..39edb2b482 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1,6 +1,6 @@ import asyncio -import base64 import copy +import base64 import functools import io import re @@ -14,12 +14,13 @@ import isodate import discord +from discord.ext import commands from discord.ext.commands import MissingRequiredArgument, CommandError from lottie.importers import importers as l_importers from lottie.exporters import exporters as l_exporters -from core.models import DMDisabled, DummyMessage, getLogger -from core.time import human_timedelta +from core.models import DMDisabled, DummyMessage, PermissionLevel, getLogger +from core import checks from core.utils import ( is_image_url, parse_channel_topic, @@ -67,10 +68,15 @@ def __init__( self.close_task = None self.auto_close_task = None self._cancelled = False + self._dm_menu_msg_id = None + self._dm_menu_channel_id = None # --- SNOOZE STATE --- self.snoozed = False # True if thread is snoozed self.snooze_data = None # Dict with channel/category/position/messages for restoration self.log_key = None # Ensure log_key always exists + # --- UNSNOOZE COMMAND QUEUE --- + self._unsnoozing = False # True while restore_from_snooze is running + self._command_queue = [] # Queue of (ctx, command) tuples; close commands always last def __repr__(self): return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipients={len(self._other_recipients)})' @@ -88,9 +94,10 @@ async def wait_until_ready(self) -> None: try: await task except asyncio.TimeoutError: - pass - - self.wait_tasks.remove(task) + logger.warning("Waiting for thread setup timed out.") + finally: + if task in self.wait_tasks: + self.wait_tasks.remove(task) @property def id(self) -> int: @@ -113,10 +120,19 @@ def ready(self) -> bool: return self._ready_event.is_set() @ready.setter - def ready(self, flag: bool): + def ready(self, flag: bool) -> None: + """Set the ready state and dispatch thread_create when transitioning to ready. + + Some legacy code paths set thread.ready = True/False. This setter preserves that API by + updating the internal event and emitting the creation event when entering the ready state. + """ if flag: - self._ready_event.set() - self.bot.dispatch("thread_create", self) + if not self._ready_event.is_set(): + self._ready_event.set() + try: + self.bot.dispatch("thread_create", self) + except Exception as e: + logger.warning("Error dispatching thread_create: %s", e) else: self._ready_event.clear() @@ -133,13 +149,38 @@ def cancelled(self, flag: bool): async def snooze(self, moderator=None, command_used=None, snooze_for=None): """ - Save channel/category/position/messages to DB, mark as snoozed, delete channel. + Save channel/category/position/messages to DB, mark as snoozed. + Behavior is configurable: + - delete (default): delete the channel and store all data for full restore later + - move: move channel to a configured snoozed category and hide it (keeps channel alive) """ if self.snoozed: return False # Already snoozed channel = self.channel if not isinstance(channel, discord.TextChannel): return False + # If using move-based snooze, hard-cap snoozed category to 49 channels + behavior_pre = (self.bot.config.get("snooze_behavior") or "delete").lower() + if behavior_pre == "move": + snoozed_cat_id = self.bot.config.get("snoozed_category_id") + target_category = None + if snoozed_cat_id: + try: + target_category = self.bot.modmail_guild.get_channel(int(snoozed_cat_id)) + except Exception: + target_category = None + if isinstance(target_category, discord.CategoryChannel): + try: + if len(target_category.channels) >= 49: + logger.warning( + "Snoozed category (%s) is full (>=49 channels). Blocking snooze for thread %s.", + target_category.id, + self.id, + ) + return False + except Exception: + # If we cannot determine channel count, proceed; downstream will handle errors + pass # Ensure self.log_key is set before snoozing if not self.log_key: # Try to fetch from DB using channel_id @@ -180,18 +221,18 @@ async def snooze(self, moderator=None, command_used=None, snooze_for=None): ) else None ), - "author_name": getattr(m.author, "name", None), + "author_name": ( + getattr(m.embeds[0].author, "name", "").split(" (")[0] + if m.embeds and m.embeds[0].author and m.author == self.bot.user + else getattr(m.author, "name", None) if m.author != self.bot.user else None + ), + "author_avatar": ( + getattr(m.embeds[0].author, "icon_url", None) + if m.embeds and m.embeds[0].author and m.author == self.bot.user + else m.author.display_avatar.url if m.author != self.bot.user else None + ), } async for m in channel.history(limit=None, oldest_first=True) - if not ( - m.embeds - and getattr(m.embeds[0], "author", None) - and ( - getattr(m.embeds[0].author, "name", "").startswith("📝 Note") - or getattr(m.embeds[0].author, "name", "").startswith("📝 Persistent Note") - ) - ) - and getattr(m, "type", None) not in ("internal", "note") ], "snoozed_by": getattr(moderator, "name", None) if moderator else None, "snooze_command": command_used, @@ -213,76 +254,445 @@ async def snooze(self, moderator=None, command_used=None, snooze_for=None): import logging logging.info(f"[SNOOZE] DB update result: {result.modified_count}") - # Delete channel - await channel.delete(reason="Thread snoozed by moderator") - self._channel = None + + behavior = behavior_pre + if behavior == "move": + # Move the channel to the snoozed category (if configured) and optionally apply a prefix + snoozed_cat_id = self.bot.config.get("snoozed_category_id") + target_category = None + guild = self.bot.modmail_guild + if snoozed_cat_id: + try: + target_category = guild.get_channel(int(snoozed_cat_id)) + except Exception: + target_category = None + # If no valid snooze category is configured, create one automatically + if not isinstance(target_category, discord.CategoryChannel): + try: + # By default, hide the snoozed category from everyone and allow only the bot to see it + overwrites = {guild.default_role: discord.PermissionOverwrite(view_channel=False)} + bot_member = guild.me + if bot_member is not None: + overwrites[bot_member] = discord.PermissionOverwrite( + view_channel=True, + send_messages=True, + read_message_history=True, + manage_channels=True, + manage_messages=True, + attach_files=True, + embed_links=True, + add_reactions=True, + ) + + target_category = await guild.create_category( + name="Snoozed Threads", + overwrites=overwrites, + reason="Auto-created snoozed category for move-based snoozing", + ) + # Persist the newly created category ID into config for future runs + try: + await self.bot.config.set("snoozed_category_id", target_category.id) + await self.bot.config.update() + except Exception: + logger.warning("Failed to persist snoozed_category_id after auto-creation.") + except Exception as e: + logger.warning( + "Failed to auto-create snoozed category (%s). Falling back to current category.", + e, + ) + target_category = channel.category + try: + # Move and sync permissions so the channel inherits the hidden snoozed-category perms + await channel.edit( + category=target_category, + reason="Thread snoozed (moved)", + sync_permissions=True, + ) + # Keep channel reference; just moved + self._channel = channel + # mark in snooze data that this was a move-based snooze + self.snooze_data["moved"] = True + except Exception as e: + logger.warning( + "Failed to move channel to snoozed category: %s. Falling back to delete.", + e, + ) + await channel.delete(reason="Thread snoozed by moderator (fallback delete)") + self._channel = None + else: + # Delete channel + await channel.delete(reason="Thread snoozed by moderator") + self._channel = None return True async def restore_from_snooze(self): """ - Recreate channel in original category/position, replay messages, mark as not snoozed. + Restore a snoozed thread. + - If channel was deleted (delete behavior), recreate and replay messages. + - If channel was moved (move behavior), move back to original category and position. + Mark as not snoozed and clear snooze data. """ + # Prevent concurrent unsnooze operations + if self._unsnoozing: + logger.warning(f"Unsnooze already in progress for thread {self.id}, skipping duplicate call") + return False + + # Mark that unsnooze is in progress + self._unsnoozing = True + if not self.snooze_data or not isinstance(self.snooze_data, dict): import logging logging.warning( f"[UNSNOOZE] Tried to restore thread {self.id} but snooze_data is None or not a dict." ) + self._unsnoozing = False return False - # Now safe to access self.snooze_data + + # Cache some fields we need later (before we potentially clear snooze_data) snoozed_by = self.snooze_data.get("snoozed_by") snooze_command = self.snooze_data.get("snooze_command") + guild = self.bot.modmail_guild - category = guild.get_channel(self.snooze_data["category_id"]) - overwrites = {} - for role_id, perm_values in self.snooze_data["overwrites"]: - role = guild.get_role(role_id) or guild.get_member(role_id) - if role: - overwrites[role] = discord.PermissionOverwrite(**perm_values) - channel = await guild.create_text_channel( - name=self.snooze_data["name"], - category=category, - topic=self.snooze_data["topic"], - slowmode_delay=self.snooze_data["slowmode_delay"], - overwrites=overwrites, - nsfw=self.snooze_data["nsfw"], - position=self.snooze_data["position"], - reason="Thread unsnoozed/restored", + behavior = (self.bot.config.get("snooze_behavior") or "delete").lower() + + # Determine original category; fall back to main_category_id if original missing + orig_category = ( + guild.get_channel(self.snooze_data.get("category_id")) + if self.snooze_data.get("category_id") + else None ) - self._channel = channel + if not isinstance(orig_category, discord.CategoryChannel): + main_cat_id = self.bot.config.get("main_category_id") + orig_category = guild.get_channel(int(main_cat_id)) if main_cat_id else None + + # Default: assume we'll need to recreate + channel: typing.Optional[discord.TextChannel] = None + + # If move-behavior and channel still exists, move it back and restore overwrites + if behavior == "move" and isinstance(self.channel, discord.TextChannel): + try: + await self.channel.edit( + category=orig_category, + position=self.snooze_data.get("position", self.channel.position), + reason="Thread unsnoozed/restored", + ) + # Restore original overwrites captured at snooze time + try: + ow_map: dict = {} + for role_id, perm_values in self.snooze_data.get("overwrites", []): + target = guild.get_role(role_id) or guild.get_member(role_id) + if target is None: + continue + ow_map[target] = discord.PermissionOverwrite(**perm_values) + if ow_map: + await self.channel.edit(overwrites=ow_map, reason="Restore original overwrites") + except Exception as e: + logger.warning("Failed to restore original overwrites on unsnooze: %s", e) + + channel = self.channel + except Exception as e: + logger.warning("Failed to move snoozed channel back, recreating: %s", e) + channel = None + + # If we couldn't move back (or behavior=delete), recreate the channel + if channel is None: + try: + ow_map: dict = {} + for role_id, perm_values in self.snooze_data.get("overwrites", []): + target = guild.get_role(role_id) or guild.get_member(role_id) + if target is None: + continue + ow_map[target] = discord.PermissionOverwrite(**perm_values) + + channel = await guild.create_text_channel( + name=self.snooze_data.get("name") or f"thread-{self.id}", + category=orig_category, + # discord.py expects a dict for overwrites; use empty dict if none + overwrites=ow_map or {}, + position=self.snooze_data.get("position"), + topic=self.snooze_data.get("topic"), + slowmode_delay=self.snooze_data.get("slowmode_delay") or 0, + nsfw=bool(self.snooze_data.get("nsfw")), + reason="Thread unsnoozed/restored (recreated)", + ) + self._channel = channel + except Exception: + logger.error("Failed to recreate thread channel during unsnooze.", exc_info=True) + return False + + # Helper to safely send to thread channel, recreating once if deleted + async def _safe_send_to_channel(*, content=None, embeds=None, allowed_mentions=None): + nonlocal channel + try: + return await channel.send(content=content, embeds=embeds, allowed_mentions=allowed_mentions) + except discord.NotFound: + # Channel was deleted between restore and send; try to recreate once + try: + ow_map: dict = {} + for role_id, perm_values in self.snooze_data.get("overwrites", []) or []: + target = guild.get_role(role_id) or guild.get_member(role_id) + if target is None: + continue + ow_map[target] = discord.PermissionOverwrite(**perm_values) + channel = await guild.create_text_channel( + name=(self.snooze_data.get("name") or f"thread-{self.id}"), + category=orig_category, + # discord.py expects a dict for overwrites; use empty dict if none + overwrites=ow_map or {}, + position=self.snooze_data.get("position"), + topic=self.snooze_data.get("topic"), + slowmode_delay=self.snooze_data.get("slowmode_delay") or 0, + nsfw=bool(self.snooze_data.get("nsfw")), + reason="Thread unsnoozed/restored (recreated after NotFound)", + ) + self._channel = channel + return await channel.send( + content=content, + embeds=embeds, + allowed_mentions=allowed_mentions, + ) + except Exception: + logger.error( + "Failed to recreate channel during unsnooze send.", + exc_info=True, + ) + return None + + # Ensure genesis message exists; always present after unsnooze + genesis_already_sent = False + + async def _ensure_genesis(force: bool = False): + nonlocal genesis_already_sent + try: + existing = await self.get_genesis_message() + except Exception: + existing = None + if existing is None or force: + # Build log_url and log_count best-effort + prefix = (self.bot.config.get("log_url_prefix") or "").strip("/") + if prefix == "NONE": + prefix = "" + key = self.snooze_data.get("log_key") or self.log_key + log_url = ( + f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{key}" + if key + else None + ) + log_count = None + try: + logs = await self.bot.api.get_user_logs(self.id) + log_count = sum(1 for log in logs if not log.get("open")) + except Exception: + log_count = None + # Resolve recipient object + user = self.recipient + if user is None: + try: + user = await self.bot.get_or_fetch_user(self.id) + except Exception: + user = SimpleNamespace( + id=self.id, + mention=f"<@{self.id}>", + created_at=datetime.now(timezone.utc), + ) + try: + info_embed = self._format_info_embed(user, log_url, log_count, self.bot.main_color) + msg = await channel.send(embed=info_embed) + try: + await msg.pin() + except Exception as e: + logger.warning("Failed to pin genesis message during unsnooze: %s", e) + self._genesis_message = msg + genesis_already_sent = True + except Exception: + logger.warning("Failed to send genesis message during unsnooze.", exc_info=True) + + # If we recreated the channel, force-send genesis; if moved back, ensure it's present + try: + if behavior == "move" and isinstance(channel, discord.TextChannel): + await _ensure_genesis(force=False) + else: + await _ensure_genesis(force=True) + except Exception: + logger.debug("Genesis ensure step encountered an error.") + # Strictly restore the log_key from snooze_data (never create a new one) self.log_key = self.snooze_data.get("log_key") - # Replay messages - for msg in self.snooze_data["messages"]: - author = self.bot.get_user(msg["author_id"]) or await self.bot.get_or_fetch_user(msg["author_id"]) - content = msg["content"] - embeds = [discord.Embed.from_dict(e) for e in msg.get("embeds", []) if e] - attachments = msg.get("attachments", []) - msg_type = msg.get("type") - # Only send if there is content, embeds, or attachments - if not content and not embeds and not attachments: - continue # Skip empty messages - author_is_mod = msg["author_id"] not in [r.id for r in self.recipients] - if author_is_mod: - username = msg.get("author_name") or (getattr(author, "name", None)) or "Unknown" - user_id = msg.get("author_id") + + # Replay messages only if we re-created the channel (delete behavior or move fallback) + if behavior != "move" or (behavior == "move" and not self.snooze_data.get("moved", False)): + # Get history limit from config (0 or None = show all) + history_limit = self.bot.config.get("unsnooze_history_limit") + all_messages = self.snooze_data.get("messages", []) + + # Separate genesis, notes, and regular messages + genesis_msg = None + notes = [] + regular_messages = [] + + for msg in all_messages: + msg_type = msg.get("type") + # Check if it's the genesis message (has Roles field) + if msg.get("embeds"): + for embed_dict in msg.get("embeds", []): + if embed_dict.get("fields"): + for field in embed_dict.get("fields", []): + if field.get("name") == "Roles": + genesis_msg = msg + break + if genesis_msg: + break + # Check if it's a note + if msg_type == "mod_only": + notes.append(msg) + elif genesis_msg != msg: + regular_messages.append(msg) + + # Apply limit if set + limited = False + if history_limit: + try: + history_limit = int(history_limit) + if history_limit > 0 and len(regular_messages) > history_limit: + regular_messages = regular_messages[-history_limit:] + limited = True + except (ValueError, TypeError): + pass + + # Replay genesis first (only if we didn't already create it above) + if genesis_msg and not genesis_already_sent: + msg = genesis_msg + try: + author = self.bot.get_user(msg["author_id"]) or await self.bot.get_or_fetch_user( + msg["author_id"] + ) + except discord.NotFound: + author = None + embeds = [discord.Embed.from_dict(e) for e in msg.get("embeds", []) if e] if embeds: - embeds[0].set_author( - name=f"{username} ({user_id})", - icon_url=( - author.display_avatar.url - if author and hasattr(author, "display_avatar") - else None - ), + await _safe_send_to_channel( + embeds=embeds, allowed_mentions=discord.AllowedMentions.none() ) - await channel.send(embeds=embeds) + + # Send history limit notification after genesis + if limited: + prefix = self.bot.config["log_url_prefix"].strip("/") + if prefix == "NONE": + prefix = "" + log_url = ( + f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{self.log_key}" + if self.log_key + else None + ) + + limit_embed = discord.Embed( + color=0xFFA500, + title="⚠️ History Limited", + description=f"Only showing the last **{history_limit}** messages due to the `unsnooze_history_limit` setting.", + ) + if log_url: + limit_embed.description += f"\n\n[View full history in logs]({log_url})" + await _safe_send_to_channel( + embeds=[limit_embed], + allowed_mentions=discord.AllowedMentions.none(), + ) + + # Build list of remaining messages to show + messages_to_show = [] + messages_to_show.extend(notes) + messages_to_show.extend(regular_messages) + + for msg in messages_to_show: + try: + author = self.bot.get_user(msg["author_id"]) or await self.bot.get_or_fetch_user( + msg["author_id"] + ) + except discord.NotFound: + author = None + + content = msg.get("content") + embeds = [discord.Embed.from_dict(e) for e in msg.get("embeds", []) if e] + attachments = msg.get("attachments", []) + + # Only send if there is something to send + if not content and not embeds and not attachments: + continue + + author_is_mod = msg["author_id"] not in [r.id for r in self.recipients] + if author_is_mod: + # Prefer stored author_name/avatar + username = ( + msg.get("author_name") + or (getattr(author, "name", None) if author else None) + or "Unknown" + ) + user_id = msg.get("author_id") + if embeds: + # Ensure embeds show author details + embeds[0].set_author( + name=f"{username} ({user_id})", + icon_url=msg.get("author_avatar") + or ( + author.display_avatar.url + if author and hasattr(author, "display_avatar") + else None + ), + ) + # If there were attachment URLs, include them as a field so mods can access them + if attachments: + try: + embeds[0].add_field( + name="Attachments", + value="\n".join(attachments), + inline=False, + ) + except Exception as e: + logger.info( + "Failed to add attachments field while replaying unsnoozed messages: %s", + e, + ) + await _safe_send_to_channel( + embeds=embeds, + allowed_mentions=discord.AllowedMentions.none(), + ) + else: + # Plain-text path (no embeds): prefix with username and user id + header = f"**{username} ({user_id})**" + body = content or "" + if attachments and not body: + # no content; include attachment URLs on new lines + body = "\n".join(attachments) + formatted = f"{header}: {body}" if body else header + await _safe_send_to_channel( + content=formatted, + allowed_mentions=discord.AllowedMentions.none(), + ) else: - formatted = ( - f"**{username} ({user_id})**: {content}" if content else f"**{username} ({user_id})**" + # Recipient message: include attachment URLs if content is empty + # When no embeds, prefix plain text with username and user id + username = ( + msg.get("author_name") + or (getattr(author, "name", None) if author else None) + or "Unknown" ) - await channel.send(formatted) - else: - await channel.send(content=content or None, embeds=embeds or None) + user_id = msg.get("author_id") + if embeds: + await _safe_send_to_channel( + content=None, + embeds=embeds or None, + allowed_mentions=discord.AllowedMentions.none(), + ) + else: + header = f"**{username} ({user_id})**" + body = content or "" + if attachments and not body: + body = "\n".join(attachments) + formatted = f"{header}: {body}" if body else header + await _safe_send_to_channel( + content=formatted, + allowed_mentions=discord.AllowedMentions.none(), + ) self.snoozed = False # Store snooze_data for notification before clearing snooze_data_for_notify = self.snooze_data @@ -313,18 +723,33 @@ async def restore_from_snooze(self): notify_channel = self.bot.config.get("unsnooze_notify_channel") or "thread" notify_text = self.bot.config.get("unsnooze_text") or "This thread has been unsnoozed and restored." if notify_channel == "thread": - await channel.send(notify_text) + await _safe_send_to_channel(content=notify_text, allowed_mentions=discord.AllowedMentions.none()) else: - ch = self.bot.get_channel(int(notify_channel)) + # Extract channel ID from mention format <#123> or use raw ID + channel_id = str(notify_channel).strip("<#>") + ch = self.bot.get_channel(int(channel_id)) if ch: - await ch.send(f"Thread for user <@{self.id}> has been unsnoozed and restored.") + await ch.send( + f"⏰ Thread for user <@{self.id}> has been unsnoozed and restored in {channel.mention}", + allowed_mentions=discord.AllowedMentions.none(), + ) # Show who ran the snooze command and the command used # Use snooze_data_for_notify to avoid accessing self.snooze_data after it is set to None snoozed_by = snooze_data_for_notify.get("snoozed_by") if snooze_data_for_notify else None snooze_command = snooze_data_for_notify.get("snooze_command") if snooze_data_for_notify else None if snoozed_by or snooze_command: info = f"Snoozed by: {snoozed_by or 'Unknown'} | Command: {snooze_command or '?snooze'}" - await channel.send(info) + await channel.send(info, allowed_mentions=discord.AllowedMentions.none()) + + # Ensure channel is set before processing commands + self._channel = channel + + # Mark unsnooze as complete + self._unsnoozing = False + + # Process queued commands + await self._process_command_queue() + return True @classmethod @@ -371,22 +796,25 @@ async def setup(self, *, creator=None, category=None, initial_message=None): if category is not None: overwrites = {} - try: - channel = await create_thread_channel(self.bot, recipient, category, overwrites) - except discord.HTTPException as e: # Failed to create due to missing perms. - logger.critical("An error occurred while creating a thread.", exc_info=True) - self.manager.cache.pop(self.id) - - embed = discord.Embed(color=self.bot.error_color) - embed.title = "Error while trying to create a thread." - embed.description = str(e) - embed.add_field(name="Recipient", value=recipient.mention) - - if self.bot.log_channel is not None: - await self.bot.log_channel.send(embed=embed) - return - - self._channel = channel + # If thread menu is enabled and this setup call is marked as deferred genesis (initial_message carries flag), + # then we may have already created the channel earlier. Only create if channel missing. + if self._channel is None: + try: + channel = await create_thread_channel(self.bot, recipient, category, overwrites) + except discord.HTTPException as e: # Failed to create due to missing perms. + logger.critical("An error occurred while creating a thread.", exc_info=True) + self.manager.cache.pop(self.id) + + embed = discord.Embed(color=self.bot.error_color) + embed.title = "Error while trying to create a thread." + embed.description = str(e) + embed.add_field(name="Recipient", value=recipient.mention) + + if self.bot.log_channel is not None: + await self.bot.log_channel.send(embed=embed) + return + else: + self._channel = channel try: log_url, log_data = await asyncio.gather( @@ -413,11 +841,40 @@ async def send_genesis_message(): msg = await channel.send(mention, embed=info_embed) self.bot.loop.create_task(msg.pin()) self._genesis_message = msg + # Option selection logging (if a thread-creation menu option was chosen prior to creation) + if getattr(self, "_selected_thread_creation_menu_option", None) and self.bot.config.get( + "thread_creation_menu_selection_log" + ): + opt = self._selected_thread_creation_menu_option + try: + log_txt = f"Selected menu option: {opt.get('label')} ({opt.get('type')})" + if opt.get("type") == "command": + log_txt += f" -> {opt.get('callback')}" + await channel.send(embed=discord.Embed(description=log_txt, color=self.bot.mod_color)) + except Exception: + logger.warning( + "Failed logging thread-creation menu selection", + exc_info=True, + ) except Exception: logger.error("Failed unexpectedly:", exc_info=True) async def send_recipient_genesis_message(): # Once thread is ready, tell the recipient (don't send if using contact on others) + # Allow disabling the DM receipt embed via config + if not self.bot.config.get("thread_creation_send_dm_embed"): + # If self-closable is enabled, add the close reaction to the user's + # original message instead so functionality is preserved without an embed. + try: + recipient_thread_close = self.bot.config.get("recipient_thread_close") + if recipient_thread_close and initial_message is not None: + close_emoji = self.bot.config["close_emoji"] + close_emoji = await self.bot.convert_emoji(close_emoji) + await self.bot.add_reaction(initial_message, close_emoji) + except Exception as e: + logger.info("Failed to add self-close reaction to initial message: %s", e) + return + thread_creation_response = self.bot.config["thread_creation_response"] embed = discord.Embed( @@ -434,7 +891,8 @@ async def send_recipient_genesis_message(): footer = self.bot.config["thread_creation_footer"] embed.set_footer( - text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.modmail_guild, size=128) + text=footer, + icon_url=self.bot.get_guild_icon(guild=self.bot.guild, size=128), ) embed.title = self.bot.config["thread_creation_title"] @@ -616,6 +1074,13 @@ async def close( await self._close(closer, silent, delete_channel, message) async def _close(self, closer, silent=False, delete_channel=True, message=None, scheduled=False): + # Proactively disable any DM thread-creation menu so users can't keep interacting + # with the menu after the thread is closed. + try: + await self._disable_dm_creation_menu() + except Exception: + # Non-fatal; continue closing even if we can't edit the DM menu + pass if self.channel: self.manager.closing.add(self.channel.id) try: @@ -702,11 +1167,11 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, tasks = [self.bot.config.update()] if self.bot.log_channel is not None and self.channel is not None: - if self.bot.config["show_log_url_button"]: + # Only create a URL button if we actually have a valid log_url + view = None + if self.bot.config.get("show_log_url_button") and log_url: view = discord.ui.View() view.add_item(discord.ui.Button(label="Log link", url=log_url, style=discord.ButtonStyle.url)) - else: - view = None tasks.append(self.bot.log_channel.send(embed=embed, view=view)) # Thread closed message @@ -725,12 +1190,18 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, message = self.bot.config["thread_close_response"] message = self.bot.formatter.format( - message, closer=closer, loglink=log_url, logkey=log_data["key"] if log_data else None + message, + closer=closer, + loglink=log_url, + logkey=log_data["key"] if log_data else None, ) embed.description = message footer = self.bot.config["thread_close_footer"] - embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.guild, size=128)) + embed.set_footer( + text=footer, + icon_url=self.bot.get_guild_icon(guild=self.bot.guild, size=128), + ) if not silent: for user in self.recipients: @@ -755,6 +1226,43 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, self.bot.dispatch("thread_close", self, closer, silent, delete_channel, message, scheduled) + async def _disable_dm_creation_menu(self) -> None: + """Best-effort removal of the interactive DM menu view sent during thread creation.""" + if not self._dm_menu_msg_id: + return + # We only ever send the menu to the main recipient + user = self.recipient + if not isinstance(user, (discord.User, discord.Member)): + return + # Ensure we have a DM channel + dm: typing.Optional[discord.DMChannel] = getattr(user, "dm_channel", None) + if dm is None: + try: + dm = await user.create_dm() + except Exception as e: + logger.info("Failed creating DM channel for menu disable: %s", e) + dm = None + if not isinstance(dm, discord.DMChannel): + return + # If we stored the channel id and it differs, but it's still a DM, continue anyway + try: + msg = await dm.fetch_message(self._dm_menu_msg_id) + except (discord.NotFound, discord.Forbidden): + return + except Exception: + return + try: + closed_text = "This thread has been closed. Send a new message to start a new thread." # Grammar-friendly guidance + closed_embed = discord.Embed(description=closed_text) + await msg.edit(content=None, embed=closed_embed, view=None) + except Exception as e: + # Fallback: at least remove interaction so menu cannot be used + logger.warning("Failed editing DM menu message on close: %s", e) + try: + await msg.edit(view=None) + except Exception as inner_e: + logger.debug("Failed removing view from DM menu message: %s", inner_e) + async def cancel_closure(self, auto_close: bool = False, all: bool = False) -> None: if self.close_task is not None and (not auto_close or all): self.close_task.cancel() @@ -801,7 +1309,12 @@ async def _restart_close_timer(self): time_marker_regex, ) - await self.close(closer=self.bot.user, after=int(seconds), message=close_message, auto_close=True) + await self.close( + closer=self.bot.user, + after=int(seconds), + message=close_message, + auto_close=True, + ) async def find_linked_messages( self, @@ -811,31 +1324,73 @@ async def find_linked_messages( note: bool = True, ) -> typing.Tuple[discord.Message, typing.List[typing.Optional[discord.Message]]]: if message1 is not None: - if not message1.embeds or not message1.embeds[0].author.url or message1.author != self.bot.user: - raise ValueError("Malformed thread message.") + if note: + # For notes, don't require author.url; rely on footer/author.name markers + if not message1.embeds or message1.author != self.bot.user: + logger.warning( + f"Malformed note for deletion: embeds={bool(message1.embeds)}, author={message1.author}" + ) + raise ValueError("Malformed note message.") + else: + if ( + not message1.embeds + or not message1.embeds[0].author.url + or message1.author != self.bot.user + ): + logger.debug( + f"Malformed thread message for deletion: embeds={bool(message1.embeds)}, author_url={getattr(message1.embeds[0], 'author', None) and message1.embeds[0].author.url}, author={message1.author}" + ) + # Keep original error string to avoid extra failure embeds in on_message_delete + raise ValueError("Malformed thread message.") elif message_id is not None: try: message1 = await self.channel.fetch_message(message_id) except discord.NotFound: + logger.warning(f"Message ID {message_id} not found in channel history.") raise ValueError("Thread message not found.") + if note: + # Try to treat as note/persistent note first + if message1.embeds and message1.author == self.bot.user: + footer_text = (message1.embeds[0].footer and message1.embeds[0].footer.text) or "" + author_name = getattr(message1.embeds[0].author, "name", "") or "" + is_note = ( + "internal note" in footer_text.lower() + or "persistent internal note" in footer_text.lower() + or author_name.startswith("📝 Note") + or author_name.startswith("📝 Persistent Note") + ) + if is_note: + # Notes have no linked DM counterpart; keep None sentinel + return message1, None + # else: fall through to relay checks below + + # Non-note path (regular relayed messages): require author.url and colors if not ( message1.embeds and message1.embeds[0].author.url and message1.embeds[0].color and message1.author == self.bot.user ): + logger.warning( + f"Message {message_id} is not a valid modmail relay message. embeds={bool(message1.embeds)}, author_url={getattr(message1.embeds[0], 'author', None) and message1.embeds[0].author.url}, color={getattr(message1.embeds[0], 'color', None)}, author={message1.author}" + ) raise ValueError("Thread message not found.") if message1.embeds[0].footer and "Internal Message" in message1.embeds[0].footer.text: if not note: - raise ValueError("Thread message not found.") + logger.warning( + f"Message {message_id} is an internal message, but note deletion not requested." + ) + raise ValueError("Thread message is an internal message, not a note.") + # Internal bot-only message treated similarly; keep None sentinel return message1, None if message1.embeds[0].color.value != self.bot.mod_color and not ( either_direction and message1.embeds[0].color.value == self.bot.recipient_color ): + logger.warning("Message color does not match mod/recipient colors.") raise ValueError("Thread message not found.") else: async for message1 in self.channel.history(): @@ -890,8 +1445,11 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> embed1 = message1.embeds[0] embed1.description = message - tasks = [self.bot.api.edit_message(message1.id, message), message1.edit(embed=embed1)] - if message1.embeds[0].footer and "Persistent Internal Message" in message1.embeds[0].footer.text: + tasks = [ + self.bot.api.edit_message(message1.id, message), + message1.edit(embed=embed1), + ] + if message1.embeds[0].footer and "Persistent Internal Note" in message1.embeds[0].footer.text: tasks += [self.bot.api.edit_note(message1.id, message)] else: for m2 in message2: @@ -910,15 +1468,14 @@ async def delete_message( else: message1, *message2 = await self.find_linked_messages(message, note=note) tasks = [] - - if not isinstance(message, discord.Message): - tasks += [message1.delete()] + # Always delete the primary thread message + tasks += [message1.delete()] for m2 in message2: if m2 is not None: tasks += [m2.delete()] - if message1.embeds[0].footer and "Persistent Internal Message" in message1.embeds[0].footer.text: + if message1.embeds[0].footer and "Persistent Internal Note" in message1.embeds[0].footer.text: tasks += [self.bot.api.delete_note(message1.id)] if tasks: @@ -1024,9 +1581,56 @@ async def note( return msg async def reply( - self, message: discord.Message, anonymous: bool = False, plain: bool = False + self, + message: discord.Message, + content: typing.Optional[str] = None, + anonymous: bool = False, + plain: bool = False, ) -> typing.Tuple[typing.List[discord.Message], discord.Message]: - """Returns List[user_dm_msg] and thread_channel_msg""" + """Send a moderator reply to the thread. + + Parameters + ---------- + message: discord.Message + The invoking command message (contains attachments, stickers, etc.). + content: Optional[str] + Raw reply text to send instead of using ``message.content``. This avoids + mutating ``message.content`` upstream and lets command handlers pass the + processed text directly. + anonymous: bool + Whether to mask the moderator identity in the recipient DM. + plain: bool + Whether to send a plain (non-embed) message to the recipient. + + Returns + ------- + Tuple[List[discord.Message], discord.Message] + A list of messages sent to recipients and the copy sent in the thread channel. + """ + # If this thread was snoozed using move-behavior, unsnooze automatically when a mod replies + try: + behavior = (self.bot.config.get("snooze_behavior") or "delete").lower() + except Exception: + behavior = "delete" + if self.snoozed and behavior == "move": + # Ensure we have snooze_data to restore location + if not self.snooze_data: + try: + log_entry = await self.bot.api.logs.find_one( + {"recipient.id": str(self.id), "snoozed": True} + ) + if log_entry: + self.snooze_data = log_entry.get("snooze_data") + except Exception as e: + logger.info( + "Failed to fetch snooze_data before auto-unsnooze on reply: %s", + e, + ) + try: + await self.restore_from_snooze() + except Exception as e: + logger.warning("Auto-unsnooze on reply failed: %s", e) + if not message.content and not message.attachments and not message.stickers: raise MissingRequiredArgument(DummyParam("msg")) for guild in self.bot.guilds: @@ -1034,7 +1638,10 @@ async def reply( if await self.bot.get_or_fetch_member(guild, self.id): break except discord.NotFound: - pass + logger.info( + "Recipient not found in guild %s when checking mutual servers.", + guild.id if hasattr(guild, "id") else guild, + ) else: return await message.channel.send( embed=discord.Embed( @@ -1055,6 +1662,7 @@ async def reply( from_mod=True, anonymous=anonymous, plain=plain, + content_override=content, ) ) @@ -1084,18 +1692,34 @@ async def reply( ) else: # Send the same thing in the thread channel. - msg = await self.send( - message, destination=self.channel, from_mod=True, anonymous=anonymous, plain=plain - ) - - tasks.append( - self.bot.api.append_log( + try: + msg = await self.send( message, - message_id=msg.id, - channel_id=self.channel.id, - type_="anonymous" if anonymous else "thread_message", + destination=self.channel, + from_mod=True, + anonymous=anonymous, + plain=plain, + content_override=content, + ) + except discord.NotFound: + logger.warning( + "Thread channel not found while replying; skipping thread-channel copy of the message." + ) + msg = None + + if msg is not None: + tasks.append( + self.bot.api.append_log( + message, + message_id=msg.id, + channel_id=self.channel.id, + type_="anonymous" if anonymous else "thread_message", + ) + ) + else: + logger.warning( + "Thread channel message failed to send; skipping append_log. Channel may be missing." ) - ) # Cancel closing if a thread message is sent. if self.close_task is not None: @@ -1125,7 +1749,26 @@ async def send( plain: bool = False, persistent_note: bool = False, thread_creation: bool = False, + *, + content_override: typing.Optional[str] = None, ) -> None: + """Low-level send routine used by reply/note logic. + + Parameters + ---------- + message: discord.Message + The command invocation message (source of attachments/stickers). + destination: Channel/User/Member + Where to send the constructed message/embed. + from_mod: bool + Indicates this is a staff reply (affects author display + logging). + note: bool + Internal note style instead of a regular reply. + anonymous / plain / persistent_note / thread_creation: Various flags controlling style. + content_override: Optional[str] + Explicit text to use instead of ``message.content``. Provided by refactored + reply commands to avoid mutating the original message object. + """ # Handle notes with Discord-like system message format - return early if note: destination = destination or self.channel @@ -1184,11 +1827,9 @@ async def send( if destination is None: logger.error("Attempted to send a message to a thread with no channel (destination is None).") return - try: - await destination.typing() - except discord.NotFound: - logger.warning("Channel not found when trying to send message.") - return + # Initial typing was attempted here previously, but returning on NotFound caused callers to + # receive None and crash when accessing attributes on the message. We rely on the + # snooze-aware typing block below to handle typing and NotFound cases robustly. author = message.author member = self.bot.guild.get_member(author.id) @@ -1234,7 +1875,7 @@ async def send( ): content = "No content" else: - content = message.content or "" + content = (content_override if content_override is not None else message.content) or "" # Only set description if there's actual content to show if content: @@ -1258,7 +1899,7 @@ async def send( tag = str(get_top_role(author, self.bot.config["use_hoisted_top_role"])) name = self.bot.config["anon_username"] if name is None: - name = tag + name = "Anonymous" avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: avatar_url = self.bot.get_guild_icon(guild=self.bot.guild, size=128) @@ -1269,8 +1910,15 @@ async def send( ) else: # Normal message - name = str(author) - avatar_url = avatar_url + # If this message originated from a thread-creation menu command callback + # (user selected an option whose type is command), we force the author + # display to be the bot to avoid showing the user as a replying moderator. + if getattr(message, "_menu_invoked", False): + name = str(self.bot.user) + avatar_url = getattr(self.bot.user.display_avatar, "url", system_avatar_url) + else: + name = str(author) + avatar_url = avatar_url embed.set_author( name=name, icon_url=avatar_url, @@ -1332,7 +1980,11 @@ def lottie_to_png(data): discord.StickerFormatType.gif, ): images.append( - (f"https://media.discordapp.net/stickers/{i.id}.{i.format.file_extension}", i.name, True) + ( + f"https://media.discordapp.net/stickers/{i.id}.{i.format.file_extension}", + i.name, + True, + ) ) elif i.format == discord.StickerFormatType.lottie: # save the json lottie representation @@ -1428,9 +2080,23 @@ def lottie_to_png(data): embed.set_footer(text="Anonymous Reply") # Normal messages elif not anonymous: + # Use configured mod_tag if provided; otherwise fallback to + # the author's top role when available, or their display name. mod_tag = self.bot.config["mod_tag"] if mod_tag is None: - mod_tag = str(get_top_role(message.author, self.bot.config["use_hoisted_top_role"])) + if hasattr(message.author, "roles"): + try: + mod_tag = str( + get_top_role( + message.author, + self.bot.config["use_hoisted_top_role"], + ) # type: ignore[arg-type] + ) + except Exception: + # As a safe fallback, prefer a stable display string + mod_tag = getattr(message.author, "display_name", str(message.author)) + else: + mod_tag = getattr(message.author, "display_name", str(message.author)) embed.set_footer(text=mod_tag) # Normal messages else: embed.set_footer(text=self.bot.config["anon_tag"]) @@ -1444,7 +2110,14 @@ def lottie_to_png(data): if (from_mod or note) and not thread_creation: delete_message = not bool(message.attachments) - if delete_message and destination == self.channel: + # Only delete the source command message when it's in a guild text + # channel; attempting to delete a DM message can raise 50003. + if ( + delete_message + and destination == self.channel + and hasattr(message, "channel") + and isinstance(message.channel, discord.TextChannel) + ): try: await message.delete() except Exception as e: @@ -1457,14 +2130,31 @@ def lottie_to_png(data): ): logger.info("Sending a message to %s when DM disabled is set.", self.recipient) - # Best-effort typing: never block message delivery if typing fails + # Best-effort typing with snooze-aware retry: if channel was deleted during snooze, restore and retry once + restored = False try: await destination.typing() except discord.NotFound: - logger.warning("Channel not found.") - raise + # Unknown Channel: if snoozed or we have snooze data, attempt to restore and retry once + if isinstance(destination, discord.TextChannel) and (self.snoozed or self.snooze_data): + logger.info("Thread channel missing while typing; attempting restore from snooze.") + try: + await self.restore_from_snooze() + destination = self.channel or destination + restored = True + await destination.typing() + except Exception as e: + logger.warning("Restore/typing retry failed: %s", e) + raise + else: + logger.warning("Channel not found.") + raise except (discord.Forbidden, discord.HTTPException, Exception) as e: - logger.warning("Unable to send typing to %s: %s. Continuing without typing.", destination, e) + logger.warning( + "Unable to send typing to %s: %s. Continuing without typing.", + destination, + e, + ) if not from_mod and not note: mentions = await self.get_notifications() @@ -1473,29 +2163,45 @@ def lottie_to_png(data): if plain: if from_mod and not isinstance(destination, discord.TextChannel): - # Plain to user + # Plain to user (DM) with warnings.catch_warnings(): - # Catch coroutines not awaited warning warnings.simplefilter("ignore") additional_images = [] - if embed.footer.text: - plain_message = f"**{embed.footer.text} " - else: - plain_message = "**" - plain_message += f"{embed.author.name}:** {embed.description}" + prefix = f"**{embed.footer.text} " if embed.footer and embed.footer.text else "**" + body = embed.description or "" + plain_message = f"{prefix}{embed.author.name}:** {body}" + files = [] - for i in message.attachments: - files.append(await i.to_file()) + for att in message.attachments: + try: + files.append(await att.to_file()) + except Exception: + logger.warning("Failed to attach file in plain DM.", exc_info=True) - msg = await destination.send(plain_message, files=files) + msg = await destination.send(plain_message, files=files or None) else: # Plain to mods - embed.set_footer(text="[PLAIN] " + embed.footer.text) + footer_text = embed.footer.text if embed.footer else "" + embed.set_footer(text=f"[PLAIN] {footer_text}".strip()) msg = await destination.send(mentions, embed=embed) else: - msg = await destination.send(mentions, embed=embed) + try: + msg = await destination.send(mentions, embed=embed) + except discord.NotFound: + if ( + isinstance(destination, discord.TextChannel) + and (self.snoozed or self.snooze_data) + and not restored + ): + logger.info("Thread channel missing while sending; attempting restore and resend.") + await self.restore_from_snooze() + destination = self.channel or destination + msg = await destination.send(mentions, embed=embed) + else: + logger.warning("Channel not found during send.") + raise if additional_images: self.ready = False @@ -1506,16 +2212,19 @@ def lottie_to_png(data): async def get_notifications(self) -> str: key = str(self.id) - - mentions = [] - mentions.extend(self.bot.config["subscriptions"].get(key, [])) - - if key in self.bot.config["notification_squad"]: - mentions.extend(self.bot.config["notification_squad"][key]) - self.bot.config["notification_squad"].pop(key) + mentions: typing.List[str] = [] + subs = self.bot.config["subscriptions"].get(key, []) + mentions.extend(subs) + one_time = self.bot.config["notification_squad"].get(key, []) + mentions.extend(one_time) + + if one_time: + self.bot.config["notification_squad"].pop(key, None) self.bot.loop.create_task(self.bot.config.update()) - return " ".join(set(mentions)) + if not mentions: + return "" + return " ".join(list(dict.fromkeys(mentions))) async def set_title(self, title: str) -> None: topic = f"Title: {title}\n" @@ -1585,6 +2294,59 @@ async def remove_users(self, users: typing.List[typing.Union[discord.Member, dis await self.channel.edit(topic=topic) await self._update_users_genesis() + async def queue_command(self, ctx, command) -> bool: + """ + Queue a command to be executed after unsnooze completes. + Close commands are automatically moved to the end of the queue. + Returns True if command was queued, False if it should execute immediately. + """ + if self._unsnoozing: + command_name = command.qualified_name if command else "" + + # If it's a close command, always add to end + if command_name == "close": + self._command_queue.append((ctx, command)) + else: + # For non-close commands, insert before any close commands + close_index = None + for i, (_, cmd) in enumerate(self._command_queue): + if cmd and cmd.qualified_name == "close": + close_index = i + break + + if close_index is not None: + self._command_queue.insert(close_index, (ctx, command)) + else: + self._command_queue.append((ctx, command)) + + return True + return False + + async def _process_command_queue(self) -> None: + """ + Process all queued commands after unsnooze completes. + Close commands are always last, so processing stops naturally after close. + """ + if not self._command_queue: + return + + logger.info(f"Processing {len(self._command_queue)} queued commands for thread {self.id}") + + # Process commands in order + while self._command_queue: + ctx, command = self._command_queue.pop(0) + try: + command_name = command.qualified_name if command else "" + await self.bot.invoke(ctx) + + # If close command was executed, stop (it's always last anyway) + if command_name == "close": + logger.info("Close command executed, queue processing complete") + break + + except Exception as e: + logger.error(f"Error processing queued command: {e}", exc_info=True) + class ThreadManager: """Class that handles storing, finding and creating Modmail threads.""" @@ -1621,7 +2383,8 @@ async def find( thread = await self._find_from_channel(channel) if thread is None: user_id, thread = next( - ((k, v) for k, v in self.cache.items() if v.channel == channel), (-1, None) + ((k, v) for k, v in self.cache.items() if v.channel == channel), + (-1, None), ) if thread is not None: logger.debug("Found thread with tempered ID.") @@ -1636,12 +2399,42 @@ async def find( try: await thread.wait_until_ready() except asyncio.CancelledError: - logger.warning("Thread for %s cancelled.", recipient) + # Improve logging: include username and user ID when possible + try: + if recipient is not None: + label = f"{recipient} ({recipient.id})" + elif recipient_id is not None: + user = await self.bot.get_or_fetch_user(recipient_id) + label = f"{user} ({recipient_id})" if user else f"User ({recipient_id})" + else: + label = "Unknown User" + except Exception: + label = f"User ({recipient_id})" if recipient_id is not None else "Unknown User" + logger.warning("Thread for %s cancelled.", label) return thread else: # If the thread is snoozed (channel is None), return it for restoration if thread.cancelled: thread = None + else: + # If the cached thread points to a deleted channel, treat as non-existent + try: + ch = getattr(thread, "channel", None) + if ( + ch + and isinstance(ch, discord.TextChannel) + and self.bot.get_channel(getattr(ch, "id", None)) is None + ): + logger.info( + "Cached thread for %s references a deleted channel. Dropping stale cache entry.", + recipient_id, + ) + self.cache.pop(thread.id, None) + thread = None + except Exception: + # If any attribute access fails, be safe and drop it. + self.cache.pop(getattr(thread, "id", None), None) + thread = None else: def check(topic): @@ -1753,13 +2546,21 @@ async def create( try: await thread.wait_until_ready() except asyncio.CancelledError: - logger.warning("Thread for %s cancelled, abort creating.", recipient) + # Improve logging to include username and ID + try: + label = f"{recipient} ({recipient.id})" + except Exception: + label = f"User ({getattr(recipient, 'id', 'unknown')})" + logger.warning("Thread for %s cancelled, abort creating.", label) return thread else: if thread.channel and self.bot.get_channel(thread.channel.id): logger.warning("Found an existing thread for %s, abort creating.", recipient) return thread - logger.warning("Found an existing thread for %s, closing previous thread.", recipient) + logger.warning( + "Found an existing thread for %s, closing previous thread.", + recipient, + ) self.bot.loop.create_task( thread.close(closer=self.bot.user, silent=True, delete_channel=False) ) @@ -1768,16 +2569,35 @@ async def create( self.cache[recipient.id] = thread - if (message or not manual_trigger) and self.bot.config["confirm_thread_creation"]: + # Determine if the advanced thread-creation menu is enabled; if so and the user + # initiated via DM, we defer confirmation until AFTER the user selects an option. + adv_menu_enabled = self.bot.config.get("thread_creation_menu_enabled") and bool( + self.bot.config.get("thread_creation_menu_options") + ) + user_initiated_dm = (creator is None or creator == recipient) and manual_trigger + + if ( + (message or not manual_trigger) + and self.bot.config["confirm_thread_creation"] + and not (adv_menu_enabled and user_initiated_dm) + ): if not manual_trigger: destination = recipient else: destination = message.channel view = ConfirmThreadCreationView() view.add_item( - AcceptButton("accept-thread-creation", self.bot.config["confirm_thread_creation_accept"]) + AcceptButton( + "accept-thread-creation", + self.bot.config["confirm_thread_creation_accept"], + ) + ) + view.add_item( + DenyButton( + "deny-thread-creation", + self.bot.config["confirm_thread_creation_deny"], + ) ) - view.add_item(DenyButton("deny-thread-creation", self.bot.config["confirm_thread_creation_deny"])) confirm = await destination.send( embed=discord.Embed( title=self.bot.config["confirm_thread_creation_title"], @@ -1804,7 +2624,8 @@ async def create( self.bot.loop.create_task( destination.send( embed=discord.Embed( - title=self.bot.config["thread_cancelled"], color=self.bot.error_color + title=self.bot.config["thread_cancelled"], + color=self.bot.error_color, ) ) ) @@ -1812,7 +2633,738 @@ async def create( del self.cache[recipient.id] return thread - self.bot.loop.create_task(thread.setup(creator=creator, category=category, initial_message=message)) + # --- THREAD-CREATION MENU (deferred or precreate channel creation) --- + adv_enabled = self.bot.config.get("thread_creation_menu_enabled") and bool( + self.bot.config.get("thread_creation_menu_options") + ) + user_initiated = (creator is None or creator == recipient) and manual_trigger + precreate = ( + adv_enabled + and user_initiated + and bool(self.bot.config.get("thread_creation_menu_precreate_channel")) + ) + if adv_enabled and user_initiated and not precreate: + # Send menu prompt FIRST, wait for selection, then create channel. + # Build dummy message for menu DM + try: + embed_text = self.bot.config.get("thread_creation_menu_embed_text") + placeholder = self.bot.config.get("thread_creation_menu_dropdown_placeholder") + timeout = int(self.bot.config.get("thread_creation_menu_timeout") or 20) + except Exception: + embed_text = "Please select an option." + placeholder = "Select an option to contact the staff team." + timeout = 20 + + options = self.bot.config.get("thread_creation_menu_options") or {} + submenus = self.bot.config.get("thread_creation_menu_submenus") or {} + + # Minimal inline view implementation (avoid importing plugin code) + + thread.ready = False # not ready yet + + class _ThreadCreationMenuSelect(discord.ui.Select): + def __init__(self, outer_thread: Thread): + self.outer_thread = outer_thread + opts = [ + discord.SelectOption( + label=o["label"], + description=o["description"], + emoji=o["emoji"], + ) + for o in options.values() + ] + super().__init__( + placeholder=placeholder, + min_values=1, + max_values=1, + options=opts, + ) + + async def callback(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=False) + # If the thread was snoozed before the user selected an option, + # restore it first so channel creation/setup & message relay work. + try: + if self.outer_thread.snoozed: + await self.outer_thread.restore_from_snooze() + except Exception: + logger.warning("Failed unsnoozing thread prior to menu selection; continuing.") + chosen_label = self.values[0] + # Resolve option key + key = chosen_label.lower().replace(" ", "_") + selected = options.get(key) + self.outer_thread._selected_thread_creation_menu_option = selected + # Reflect the selection in the original DM by editing the embed/body + try: + msg = getattr(interaction, "message", None) + if msg is None and self.view and hasattr(self.view, "message"): + msg = self.view.message + if msg is not None: + # Replace entire embed so only the selection line remains + try: + base_color = (msg.embeds[0].color if msg.embeds else None) or getattr( + self.outer_thread.bot, "mod_color", None + ) + except Exception: + base_color = getattr(self.outer_thread.bot, "mod_color", None) + selection_embed = ( + discord.Embed( + description=f"You selected: {chosen_label}", + color=base_color, + ) + if base_color is not None + else discord.Embed(description=f"You selected: {chosen_label}") + ) + await msg.edit(content=None, embed=selection_embed, view=None) + else: + try: + await interaction.edit_original_response( + content=f"You selected: {chosen_label}", view=None + ) + except Exception as e: + # Fallback: best-effort remove the view at least + logger.info( + "Primary edit_original_response failed; trying to remove view only: %s", + e, + ) + await interaction.edit_original_response(view=None) + except Exception as e: + # Ensure the menu is removed even if content edit failed + logger.warning("Failed to update selection message: %s", e) + try: + await interaction.edit_original_response(view=None) + except Exception as inner_e: + logger.debug( + "Failed to remove view after selection failure: %s", + inner_e, + ) + # Stop the view to end the interaction lifecycle + if self.view: + try: + self.view.stop() + except Exception as e: + logger.debug("Failed to stop menu view after selection: %s", e) + # Now create channel + # Determine category: prefer option-specific category if configured and valid + sel_category = None + try: + cat_id = selected.get("category_id") if isinstance(selected, dict) else None + if cat_id: + guild = self.outer_thread.bot.modmail_guild + if guild: + ch = guild.get_channel(cat_id) + if isinstance(ch, discord.CategoryChannel): + sel_category = ch + except Exception: + sel_category = None + # Fallback to provided category (from outer scope) or main category + fallback_category = category or self.outer_thread.bot.main_category + use_category = sel_category or fallback_category + # If confirmation is enabled, prompt now (after option selection) + try: + if self.outer_thread.bot.config.get("confirm_thread_creation"): + dest = message.channel if manual_trigger else recipient + view = ConfirmThreadCreationView() + view.add_item( + AcceptButton( + "accept-thread-creation", + self.outer_thread.bot.config["confirm_thread_creation_accept"], + ) + ) + view.add_item( + DenyButton( + "deny-thread-creation", + self.outer_thread.bot.config["confirm_thread_creation_deny"], + ) + ) + confirm = await dest.send( + embed=discord.Embed( + title=self.outer_thread.bot.config["confirm_thread_creation_title"], + description=self.outer_thread.bot.config["confirm_thread_response"], + color=self.outer_thread.bot.main_color, + ), + view=view, + ) + await view.wait() + if view.value is None: + # Timed out + self.outer_thread.cancelled = True + try: + await dest.send( + embed=discord.Embed( + title=self.outer_thread.bot.config["thread_cancelled"], + description="Timed out", + color=self.outer_thread.bot.error_color, + ) + ) + await confirm.edit(view=None) + except Exception: + logger.warning( + "Failed notifying user of thread creation timeout.", + exc_info=True, + ) + elif view.value is False: + self.outer_thread.cancelled = True + try: + await dest.send( + embed=discord.Embed( + title=self.outer_thread.bot.config["thread_cancelled"], + color=self.outer_thread.bot.error_color, + ) + ) + except Exception: + logger.warning( + "Failed notifying user of thread creation denial.", + exc_info=True, + ) + if self.outer_thread.cancelled: + # Clear pending/menu state and cache + try: + setattr(self.outer_thread, "_pending_menu", False) + self.outer_thread.manager.cache.pop(self.outer_thread.id, None) + except Exception: + logger.debug( + "Failed clearing pending menu/cache after cancellation.", + exc_info=True, + ) + return + except Exception: + # If confirm step fails, proceed to create thread to avoid dead-ends + logger.warning("Confirm step failed after menu selection; continuing.") + + self.outer_thread.bot.loop.create_task( + self.outer_thread.setup( + creator=creator, + category=use_category, + initial_message=message, + ) + ) + # Wait until channel is ready, then forward the original message like usual + try: + await self.outer_thread.wait_until_ready() + # Edge-case: unsnoozed restore might have re-created the channel but genesis send failed; ensure ready channel exists + if not self.outer_thread.channel: + logger.warning("Thread has no channel after unsnooze+selection; abort relay.") + setattr(self.outer_thread, "_pending_menu", False) + return + # Forward the user's initial DM to the thread channel + try: + await self.outer_thread.send(message) + except Exception: + logger.error( + "Failed to relay initial message after menu selection", + exc_info=True, + ) + else: + # React to the user's DM with the 'sent' emoji + try: + ( + sent_emoji, + _, + ) = await self.outer_thread.bot.retrieve_emoji() + await self.outer_thread.bot.add_reaction(message, sent_emoji) + except Exception as e: + logger.debug( + "Failed to add sent reaction to user's DM: %s", + e, + ) + # Dispatch thread_reply event for parity + self.outer_thread.bot.dispatch( + "thread_reply", + self.outer_thread, + False, + message, + False, + False, + ) + # Clear pending flag + setattr(self.outer_thread, "_pending_menu", False) + except Exception: + logger.warning( + "Unhandled failure after menu selection while waiting for channel readiness.", + exc_info=True, + ) + # Invoke command callback AFTER channel ready if type == command + if selected and selected.get("type") == "command": + alias = selected.get("callback") + if alias: + from discord.ext.commands.view import StringView + from core.utils import normalize_alias + + ctxs = [] + for al in normalize_alias(alias): + view_ = StringView(self.outer_thread.bot.prefix + al) + # Create a synthetic message object that makes the bot appear + # as the author for menu-invoked command replies so the user + # selecting the option is not shown as a "mod" sender. + synthetic = DummyMessage(copy.copy(message)) + try: + synthetic.author = ( + self.outer_thread.bot.modmail_guild.me or self.outer_thread.bot.user + ) + except Exception: + synthetic.author = self.outer_thread.bot.user + # Mark this message as menu-invoked for downstream formatting + setattr(synthetic, "_menu_invoked", True) + ctx_ = commands.Context( + prefix=self.outer_thread.bot.prefix, + view=view_, + bot=self.outer_thread.bot, + message=synthetic, + ) + ctx_.thread = self.outer_thread + discord.utils.find( + view_.skip_string, + await self.outer_thread.bot.get_prefix(), + ) + ctx_.invoked_with = view_.get_word().lower() + ctx_.command = self.outer_thread.bot.all_commands.get(ctx_.invoked_with) + # Mark context so downstream send/reply logic can treat as system/bot + setattr(ctx_, "_menu_invoked", True) + ctxs.append(ctx_) + for ctx_ in ctxs: + if ctx_.command: + old_checks = copy.copy(ctx_.command.checks) + ctx_.command.checks = [checks.has_permissions(PermissionLevel.INVALID)] + try: + await self.outer_thread.bot.invoke(ctx_) + finally: + ctx_.command.checks = old_checks + + class _ThreadCreationMenuView(discord.ui.View): + def __init__(self, outer_thread: Thread): + super().__init__(timeout=timeout) + self.outer_thread = outer_thread + self.add_item(_ThreadCreationMenuSelect(outer_thread)) + + async def on_timeout(self): + # Timeout -> abort thread creation + if self.outer_thread.bot.config.get("thread_creation_menu_close_on_timeout"): + try: + # Replace the entire embed with a minimal one containing only the timeout text + try: + color = (menu_msg.embeds[0].color if menu_msg.embeds else None) or getattr( + self.outer_thread.bot, "mod_color", None + ) + except Exception: + color = getattr(self.outer_thread.bot, "mod_color", None) + timeout_embed = ( + discord.Embed( + description="Menu timed out. Please send a new message to start again.", + color=color, + ) + if color + else discord.Embed( + description="Menu timed out. Please send a new message to start again." + ) + ) + await menu_msg.edit(content=None, embed=timeout_embed, view=None) + except Exception: + logger.info( + "Failed editing menu message on timeout (close_on_timeout enabled).", + exc_info=True, + ) + # remove thread from cache + try: + self.outer_thread.manager.cache.pop(self.outer_thread.id, None) + except Exception: + logger.debug( + "Failed popping thread from cache on timeout (close_on_timeout).", + exc_info=True, + ) + # Clear pending menu flag so a new message can recreate a fresh thread + setattr(self.outer_thread, "_pending_menu", False) + self.outer_thread.cancelled = True + else: + try: + # Replace the entire embed with a minimal one containing only the timeout text + try: + color = (menu_msg.embeds[0].color if menu_msg.embeds else None) or getattr( + self.outer_thread.bot, "mod_color", None + ) + except Exception: + color = getattr(self.outer_thread.bot, "mod_color", None) + timeout_embed = ( + discord.Embed( + description="Menu timed out. Please send a new message to start again.", + color=color, + ) + if color + else discord.Embed( + description="Menu timed out. Please send a new message to start again." + ) + ) + await menu_msg.edit(content=None, embed=timeout_embed, view=None) + except Exception: + logger.info( + "Failed editing menu message on timeout (keep alive mode).", + exc_info=True, + ) + # Allow subsequent messages to trigger a new menu/thread by clearing state + setattr(self.outer_thread, "_pending_menu", False) + try: + self.outer_thread.manager.cache.pop(self.outer_thread.id, None) + except Exception: + logger.debug( + "Failed popping thread from cache on timeout (keep alive mode).", + exc_info=True, + ) + self.outer_thread.cancelled = True + # Ensure view is stopped to release any internal tasks + try: + self.stop() + except Exception: + logger.debug( + "Failed stopping ThreadCreationMenuView on timeout.", + exc_info=True, + ) + + # Send DM prompt + try: + # Build embed with new customizable settings + try: + embed_title = self.bot.config.get("thread_creation_menu_embed_title") + embed_footer = self.bot.config.get("thread_creation_menu_embed_footer") + embed_thumb = self.bot.config.get("thread_creation_menu_embed_thumbnail_url") + embed_image = self.bot.config.get("thread_creation_menu_embed_image_url") + embed_footer_icon = self.bot.config.get("thread_creation_menu_embed_footer_icon_url") + embed_color_raw = self.bot.config.get("thread_creation_menu_embed_color") + except Exception: + embed_title = None + embed_footer = None + embed_thumb = None + embed_image = None + embed_footer_icon = None + embed_color_raw = None + embed_color = embed_color_raw or self.bot.mod_color + embed = discord.Embed(title=embed_title, description=embed_text, color=embed_color) + if embed_footer: + try: + if embed_footer_icon: + embed.set_footer(text=embed_footer, icon_url=embed_footer_icon) + else: + embed.set_footer(text=embed_footer) + except Exception as e: + logger.debug("Footer build failed (ignored): %s", e) + # Option A: prefer dedicated large image when provided + if embed_image: + try: + embed.set_image(url=embed_image) + except Exception as e: + logger.debug("Image set failed (ignored): %s", e) + elif embed_thumb: + try: + embed.set_thumbnail(url=embed_thumb) + except Exception as e: + logger.debug("Thumbnail set failed (ignored): %s", e) + menu_view = _ThreadCreationMenuView(thread) + menu_msg = await recipient.send(embed=embed, view=menu_view) + # mark thread as pending menu selection + thread._pending_menu = True + # Explicitly attach the message to the view for safety in callbacks + try: + menu_view.message = menu_msg + except Exception as e: + logger.info( + "Failed attaching menu message reference (initial menu send): %s", + e, + ) + # Store for later disabling on thread close + try: + thread._dm_menu_msg_id = menu_msg.id + thread._dm_menu_channel_id = menu_msg.channel.id + except Exception as e: + logger.info( + "Failed storing DM menu identifiers (initial menu send): %s", + e, + ) + except Exception: + logger.warning( + "Failed to send thread-creation menu DM, falling back to immediate thread creation.", + exc_info=True, + ) + self.bot.loop.create_task( + thread.setup(creator=creator, category=category, initial_message=message) + ) + return thread + + # If menu is enabled but precreate is requested, send the menu DM but do NOT defer creation. + # Selection becomes optional; thread channel will already be created below. + if adv_enabled and user_initiated and precreate: + try: + embed_text = self.bot.config.get("thread_creation_menu_embed_text") + placeholder = self.bot.config.get("thread_creation_menu_dropdown_placeholder") + timeout = int(self.bot.config.get("thread_creation_menu_timeout") or 20) + except Exception: + embed_text = "Please select an option." + placeholder = "Select an option to contact the staff team." + timeout = 20 + + options = self.bot.config.get("thread_creation_menu_options") or {} + + class _PrecreateMenuSelect(discord.ui.Select): + def __init__(self, outer_thread: Thread): + self.outer_thread = outer_thread + opts = [ + discord.SelectOption( + label=o["label"], + description=o["description"], + emoji=o["emoji"], + ) + for o in options.values() + ] + super().__init__( + placeholder=placeholder, + min_values=1, + max_values=1, + options=opts, + ) + + async def callback(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=False) + # If thread somehow got snoozed before selection in precreate flow (rare), restore first. + try: + if self.outer_thread.snoozed: + await self.outer_thread.restore_from_snooze() + except Exception: + logger.warning( + "Failed unsnoozing thread prior to precreate menu selection; continuing.", + exc_info=True, + ) + chosen_label = self.values[0] + key = chosen_label.lower().replace(" ", "_") + selected = options.get(key) + self.outer_thread._selected_thread_creation_menu_option = selected + # Remove the view + try: + msg = getattr(interaction, "message", None) + if msg is None and self.view and hasattr(self.view, "message"): + msg = self.view.message + if msg is not None: + # Replace entire embed so only the selection line remains + try: + base_color = (msg.embeds[0].color if msg.embeds else None) or getattr( + self.outer_thread.bot, "mod_color", None + ) + except Exception: + base_color = getattr(self.outer_thread.bot, "mod_color", None) + selection_embed = ( + discord.Embed( + description=f"You selected: {chosen_label}", + color=base_color, + ) + if base_color is not None + else discord.Embed(description=f"You selected: {chosen_label}") + ) + await msg.edit(content=None, embed=selection_embed, view=None) + else: + try: + await interaction.edit_original_response( + content=f"You selected: {chosen_label}", view=None + ) + except Exception: + await interaction.edit_original_response(view=None) + except Exception: + try: + await interaction.edit_original_response(view=None) + except Exception: + logger.debug( + "Failed secondary edit_original_response path removing view.", + exc_info=True, + ) + if self.view: + try: + self.view.stop() + except Exception: + logger.debug( + "Failed removing view after selection (stop).", + exc_info=True, + ) + # Log selection to thread channel if configured + try: + await self.outer_thread.wait_until_ready() + if self.outer_thread.bot.config.get("thread_creation_menu_selection_log"): + opt = selected or {} + log_txt = f"Selected menu option: {opt.get('label')} ({opt.get('type')})" + if opt.get("type") == "command": + log_txt += f" -> {opt.get('callback')}" + await self.outer_thread.channel.send( + embed=discord.Embed( + description=log_txt, + color=self.outer_thread.bot.mod_color, + ) + ) + # If a category_id is set on the option, move the channel accordingly + try: + cat_id = selected.get("category_id") if isinstance(selected, dict) else None + if cat_id: + guild = self.outer_thread.bot.modmail_guild + target = guild and guild.get_channel(int(cat_id)) + if isinstance(target, discord.CategoryChannel): + await self.outer_thread.channel.edit( + category=target, + reason="Menu selection: move to category", + ) + except Exception: + logger.debug( + "Failed moving thread channel based on selected category_id.", + exc_info=True, + ) + except Exception: + logger.debug( + "Failed logging menu selection or moving category in precreate flow.", + exc_info=True, + ) + # If the option type is command, invoke it now within the created thread + if selected and selected.get("type") == "command": + alias = selected.get("callback") + if alias: + from discord.ext.commands.view import StringView + from core.utils import normalize_alias + + ctxs = [] + for al in normalize_alias(alias): + view_ = StringView(self.outer_thread.bot.prefix + al) + synthetic = DummyMessage(copy.copy(message)) + try: + synthetic.author = ( + self.outer_thread.bot.modmail_guild.me or self.outer_thread.bot.user + ) + except Exception: + synthetic.author = self.outer_thread.bot.user + setattr(synthetic, "_menu_invoked", True) + ctx_ = commands.Context( + prefix=self.outer_thread.bot.prefix, + view=view_, + bot=self.outer_thread.bot, + message=synthetic, + ) + ctx_.thread = self.outer_thread + discord.utils.find( + view_.skip_string, + await self.outer_thread.bot.get_prefix(), + ) + ctx_.invoked_with = view_.get_word().lower() + ctx_.command = self.outer_thread.bot.all_commands.get(ctx_.invoked_with) + setattr(ctx_, "_menu_invoked", True) + ctxs.append(ctx_) + for ctx_ in ctxs: + if ctx_.command: + old_checks = copy.copy(ctx_.command.checks) + ctx_.command.checks = [checks.has_permissions(PermissionLevel.INVALID)] + try: + await self.outer_thread.bot.invoke(ctx_) + finally: + ctx_.command.checks = old_checks + + class _PrecreateMenuView(discord.ui.View): + def __init__(self, outer_thread: Thread): + super().__init__(timeout=timeout) + self.add_item(_PrecreateMenuSelect(outer_thread)) + + async def on_timeout(self): + try: + # Replace the entire embed with a minimal one containing only the timeout text + try: + color = menu_msg.embeds[0].color if menu_msg.embeds else None + except Exception: + color = None + timeout_embed = ( + discord.Embed( + description="Menu timed out. Please send a new message to start again.", + color=color, + ) + if color + else discord.Embed( + description="Menu timed out. Please send a new message to start again." + ) + ) + await menu_msg.edit(content=None, embed=timeout_embed, view=None) + except Exception: + logger.info( + "Failed editing precreate menu message on timeout.", + exc_info=True, + ) + try: + self.stop() + except Exception: + logger.debug( + "Failed stopping PrecreateMenuView on timeout.", + exc_info=True, + ) + + try: + # Build embed with new customizable settings (precreate flow) + try: + embed_title = self.bot.config.get("thread_creation_menu_embed_title") + embed_footer = self.bot.config.get("thread_creation_menu_embed_footer") + embed_thumb = self.bot.config.get("thread_creation_menu_embed_thumbnail_url") + embed_image = self.bot.config.get("thread_creation_menu_embed_image_url") + embed_large = bool(self.bot.config.get("thread_creation_menu_embed_large_image")) + embed_footer_icon = self.bot.config.get("thread_creation_menu_embed_footer_icon_url") + embed_color_raw = self.bot.config.get("thread_creation_menu_embed_color") + except Exception: + embed_title = None + embed_footer = None + embed_thumb = None + embed_image = None + embed_large = False + embed_footer_icon = None + embed_color_raw = None + embed_color = embed_color_raw or self.bot.mod_color + embed = discord.Embed(title=embed_title, description=embed_text, color=embed_color) + if embed_footer: + try: + if embed_footer_icon: + embed.set_footer(text=embed_footer, icon_url=embed_footer_icon) + else: + embed.set_footer(text=embed_footer) + except Exception as e: + logger.debug("Footer build failed (ignored precreate): %s", e) + if embed_image: + try: + embed.set_image(url=embed_image) + except Exception as e: + logger.debug("Image set failed (ignored precreate): %s", e) + elif embed_thumb: + try: + if embed_large: + embed.set_image(url=embed_thumb) + else: + embed.set_thumbnail(url=embed_thumb) + except Exception as e: + logger.debug("Thumbnail/image set failed (ignored precreate): %s", e) + menu_view = _PrecreateMenuView(thread) + # Send menu DM AFTER channel creation initiation (channel will be created below) + menu_msg = await recipient.send(embed=embed, view=menu_view) + try: + menu_view.message = menu_msg + except Exception: + logger.debug( + "Failed attaching menu message reference (precreate menu).", + exc_info=True, + ) + # Store for later disabling on thread close + try: + thread._dm_menu_msg_id = menu_msg.id + thread._dm_menu_channel_id = menu_msg.channel.id + except Exception: + logger.debug( + "Failed storing DM menu identifiers (precreate menu).", + exc_info=True, + ) + except Exception: + logger.debug("Failed to send precreate menu DM; proceeding without menu.") + + # Regular immediate creation (force main_category for user-initiated menu flows) + forced_category = None + if adv_enabled and user_initiated and precreate: + # In precreate mode we still create immediately (main category override optional) + forced_category = self.bot.main_category + chosen_category = forced_category or category + self.bot.loop.create_task( + thread.setup(creator=creator, category=chosen_category, initial_message=message) + ) return thread async def find_or_create(self, recipient) -> Thread: diff --git a/core/time.py b/core/time.py index b6ce91f419..67351792ee 100644 --- a/core/time.py +++ b/core/time.py @@ -89,7 +89,12 @@ def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None): if not status.hasTime: # replace it with the current time - dt = dt.replace(hour=now.hour, minute=now.minute, second=now.second, microsecond=now.microsecond) + dt = dt.replace( + hour=now.hour, + minute=now.minute, + second=now.second, + microsecond=now.microsecond, + ) self.dt: datetime.datetime = dt self._past: bool = dt < now @@ -158,7 +163,11 @@ def __init__(self, dt: datetime.datetime, now: datetime.datetime = None): self.arg = "" async def ensure_constraints( - self, ctx: Context, uft: UserFriendlyTime, now: datetime.datetime, remaining: str + self, + ctx: Context, + uft: UserFriendlyTime, + now: datetime.datetime, + remaining: str, ) -> None: # Strip stray connector words like "in", "to", or "at" that may # remain when the natural language parser isolates the time token @@ -301,7 +310,12 @@ async def convert(self, ctx: Context, argument: str, *, now=None) -> FriendlyTim if not status.hasTime: # replace it with the current time - dt = dt.replace(hour=now.hour, minute=now.minute, second=now.second, microsecond=now.microsecond) + dt = dt.replace( + hour=now.hour, + minute=now.minute, + second=now.second, + microsecond=now.microsecond, + ) # if midnight is provided, just default to next day if status.accuracy == pdt.pdtContext.ACU_HALFDAY: diff --git a/core/utils.py b/core/utils.py index 19ff4cd37b..dc8737ead6 100644 --- a/core/utils.py +++ b/core/utils.py @@ -258,7 +258,9 @@ def cleanup_code(content: str) -> str: UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE) -def parse_channel_topic(text: str) -> typing.Tuple[typing.Optional[str], int, typing.List[int]]: +def parse_channel_topic( + text: str, +) -> typing.Tuple[typing.Optional[str], int, typing.List[int]]: """ A helper to parse channel topics and respectivefully returns all the required values at once. @@ -359,7 +361,8 @@ def match_other_recipients(text: str) -> typing.List[int]: def create_not_found_embed(word, possibilities, name, n=2, cutoff=0.6) -> discord.Embed: # Single reference of Color.red() embed = discord.Embed( - color=discord.Color.red(), description=f"**{name.capitalize()} `{word}` cannot be found.**" + color=discord.Color.red(), + description=f"**{name.capitalize()} `{word}` cannot be found.**", ) val = get_close_matches(word, possibilities, n=n, cutoff=cutoff) if val: @@ -369,7 +372,7 @@ def create_not_found_embed(word, possibilities, name, n=2, cutoff=0.6) -> discor def parse_alias(alias, *, split=True): def encode_alias(m): - return "\x1AU" + base64.b64encode(m.group(1).encode()).decode() + "\x1AU" + return "\x1aU" + base64.b64encode(m.group(1).encode()).decode() + "\x1aU" def decode_alias(m): return base64.b64decode(m.group(1).encode()).decode() @@ -632,7 +635,8 @@ async def callback(self, interaction: discord.Interaction): class ConfirmThreadCreationView(discord.ui.View): def __init__(self): - super().__init__(timeout=20) + # Match thread_creation_menu_timeout default (30s) for consistency in UX + super().__init__(timeout=30) self.value = None @@ -721,8 +725,9 @@ def extract_forwarded_content(message) -> typing.Optional[str]: if len(ref_msg.attachments) > 3: attachment_info += f" (+{len(ref_msg.attachments) - 3} more)" return f"**{ref_author_name}:** [Attachments: {attachment_info}]" - except Exception: - pass + except Exception as e: + # Log and continue; failing to extract a reference preview shouldn't break flow + logger.debug("Failed to extract reference preview: %s", e) except Exception: # Silently handle any unexpected errors pass diff --git a/pyproject.toml b/pyproject.toml index 0a6d6eaa6c..719abc9447 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.2.0' +version = '4.2.1' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ From 17dd88564958a1eb07941233d0c1af36c039eadf Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Fri, 28 Nov 2025 00:34:44 -0800 Subject: [PATCH 694/705] Fix GH Workflow with black Formatting --- cogs/modmail.py | 4 +++- core/thread.py | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 0a97888646..b0e38ed9e0 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1803,7 +1803,9 @@ async def contact( try: await msg.delete(delay=10) except (discord.Forbidden, discord.NotFound) as e: - logger.debug(f"Failed to delete message (likely already deleted or lacking permissions): {e}") + logger.debug( + f"Failed to delete message (likely already deleted or lacking permissions): {e}" + ) # Don't try to create a new thread - we just unsnoozed existing ones return diff --git a/core/thread.py b/core/thread.py index 39edb2b482..bf77180f8c 100644 --- a/core/thread.py +++ b/core/thread.py @@ -224,12 +224,16 @@ async def snooze(self, moderator=None, command_used=None, snooze_for=None): "author_name": ( getattr(m.embeds[0].author, "name", "").split(" (")[0] if m.embeds and m.embeds[0].author and m.author == self.bot.user - else getattr(m.author, "name", None) if m.author != self.bot.user else None + else getattr(m.author, "name", None) + if m.author != self.bot.user + else None ), "author_avatar": ( getattr(m.embeds[0].author, "icon_url", None) if m.embeds and m.embeds[0].author and m.author == self.bot.user - else m.author.display_avatar.url if m.author != self.bot.user else None + else m.author.display_avatar.url + if m.author != self.bot.user + else None ), } async for m in channel.history(limit=None, oldest_first=True) From bcd11935a610949e9f4e889f825367fb372dca43 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Fri, 28 Nov 2025 00:39:38 -0800 Subject: [PATCH 695/705] Add new sponsor to json --- SPONSORS.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/SPONSORS.json b/SPONSORS.json index cdaf3621ac..955b839fd7 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -131,5 +131,21 @@ "description": "*Your Retail Journey*\n*\"Better choice and better value in food, fashion & homewares.\"*\n\n\n**------------------------------------------**\n*__About us__*\nSupermarket, CityStore PLC! Attend a training to become staff!\n\nThis game is currently in V3\n\nWe have a training Centre and applications center!\n\n**------------------------------------------**\n\n> *❤️ Don't hesitate! Dive into the excitement today by joining our vibrant community on Discord. Experience our unique perspective and become an integral part of our group. Your **journey** with us promises to be unforgettable no regrets, only great memories await! ❤️*\n\n*We hope to see you. *\n\n*Signed,*\n**CityStore PLC**\n> Discord: https://discord.gg/yjFQb5mrSk\n> Roblox Group: https://www.roblox.com/groups/32819373/CityStore-PLC#!/about\n\nJoin us now and become apart of Citystore PLC community! 🎉", "color": 15523550 } + }, + { + "embed": { + "description": "✨ *\"Let's bake it!\"* ✨ \n\nKistó is a very successful and well-known **Bakery Group** on the platform. Its goal is to give every guest the **ultimate bakery experience**. \n\nWe have a wide variety of hand-made treats, from our rich **drinks** to our freshly baked **pastries**. Every item is made with care by our **skilled and passionate team**, redefining what it means to be a modern bakery. \n\n💖 Come visit us today and taste the *sweet side of perfection* at **Kistó Bakery.** \n\n**Roblox Group:** [Click here!](https://www.roblox.com/communities/9318596/Kist#!/about) \n**Discord Server:** [Click here!](https://discord.gg/aGt8Wv3gP9)", + "color": 16736255, + "author": { + "name": "Kistó Bakery", + "icon_url": "https://cdn.discordapp.com/attachments/1413609998797242522/1436882475883298887/noFilter_10_1.png" + }, + "footer": { + "text": "Proudly serving since 2021" + }, + "image": { + "url": "https://cdn.discordapp.com/attachments/1413609998797242522/1436882475543429260/0904.png" + } + } } ] From 665e67ea580d3ddcb807c034fabe9bb10629cb11 Mon Sep 17 00:00:00 2001 From: Taku <45324516+Taaku18@users.noreply.github.com> Date: Sun, 30 Nov 2025 02:58:12 -0800 Subject: [PATCH 696/705] Update version to v4.2.1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7470c9900..58243cab61 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ <br> <a href="#"> - <img src="https://img.shields.io/badge/Latest%20Version-v4.2.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> + <img src="https://img.shields.io/badge/Latest%20Version-v4.2.1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs="> </a> <br> From c26af976c550264c4de5f51d1dbe7d63f67686bd Mon Sep 17 00:00:00 2001 From: Martin <55140357+martinbndr@users.noreply.github.com> Date: Mon, 1 Dec 2025 00:10:00 +0100 Subject: [PATCH 697/705] Feat: Renaming of snippets and aliases (#3383) This adds two commands for renaming snippets and aliases for easier name editing. --- cogs/modmail.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ cogs/utility.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/cogs/modmail.py b/cogs/modmail.py index b0e38ed9e0..0e39da920c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -480,6 +480,61 @@ async def snippet_edit(self, ctx, name: str.lower, *, value): embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") await ctx.send(embed=embed) + @snippet.command(name="rename") + @checks.has_permissions(PermissionLevel.SUPPORTER) + async def snippet_rename(self, ctx, name: str.lower, *, value): + """ + Rename a snippet. + + To rename a multi-word snippet name, use quotes: ``` + {prefix}snippet rename "two word" this is a new two word snippet. + ``` + """ + if name in self.bot.snippets: + if self.bot.get_command(value): + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"A command with the same name already exists: `{value}`.", + ) + return await ctx.send(embed=embed) + elif value in self.bot.snippets: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"Snippet `{value}` already exists.", + ) + return await ctx.send(embed=embed) + + if value in self.bot.aliases: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"An alias that shares the same name exists: `{value}`.", + ) + return await ctx.send(embed=embed) + + if len(value) > 120: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description="Snippet names cannot be longer than 120 characters.", + ) + return await ctx.send(embed=embed) + old_snippet_value = self.bot.snippets[name] + self.bot.snippets.pop(name) + self.bot.snippets[value] = old_snippet_value + await self.bot.config.update() + + embed = discord.Embed( + title="Renamed snippet", + color=self.bot.main_color, + description=f'`{name}` has been renamed to "{value}".', + ) + else: + embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet") + await ctx.send(embed=embed) + @commands.command(usage="<category> [options]") @checks.has_permissions(PermissionLevel.MODERATOR) @checks.thread_only() diff --git a/cogs/utility.py b/cogs/utility.py index c420ee7979..5b4de12ee9 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1275,6 +1275,58 @@ async def alias_edit(self, ctx, name: str.lower, *, value): embed = await self.make_alias(name, value, "Edited") return await ctx.send(embed=embed) + @alias.command(name="rename") + @checks.has_permissions(PermissionLevel.MODERATOR) + async def alias_rename(self, ctx, name: str.lower, *, value): + """ + Rename an alias. + """ + if name not in self.bot.aliases: + embed = utils.create_not_found_embed(name, self.bot.aliases.keys(), "Alias") + return await ctx.send(embed=embed) + + embed = None + if self.bot.get_command(value): + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"A command with the same name already exists: `{value}`.", + ) + + elif value in self.bot.aliases: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"Another alias with the same name already exists: `{value}`.", + ) + + elif value in self.bot.snippets: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description=f"A snippet with the same name already exists: `{value}`.", + ) + + elif len(value) > 120: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description="Alias names cannot be longer than 120 characters.", + ) + + if embed is None: + old_alias_value = self.bot.aliases[name] + self.bot.aliases.pop(name) + self.bot.aliases[value] = old_alias_value + await self.bot.config.update() + + embed = discord.Embed( + title="Alias renamed", + color=self.bot.main_color, + description=f'`{name}` has been renamed to "{value}".', + ) + return await ctx.send(embed=embed) + @commands.group(aliases=["perms"], invoke_without_command=True) @checks.has_permissions(PermissionLevel.OWNER) async def permissions(self, ctx): From a7ff289180dfbda7908a80d7af3d2074776f1820 Mon Sep 17 00:00:00 2001 From: Martin <55140357+martinbndr@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:42:27 +0100 Subject: [PATCH 698/705] Fixes config_help notes (#3407) Fixes config_help notes variables inside the `thread_close_response` and `thread_self_close_response`. --- core/config_help.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/config_help.json b/core/config_help.json index b5832935c7..fedf9279ed 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -533,7 +533,7 @@ "notes": [ "When `recipient_thread_close` is enabled and the recipient closed their own thread, `thread_self_close_response` is used instead of this configuration.", "You may use the `{{closer}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that closed the thread.", - "`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{loglink}}` for the unique key (ie. s3kf91a) of the log.", + "`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{logkey}}` for the unique key (ie. s3kf91a) of the log.", "Discord flavoured markdown is fully supported in `thread_close_response`.", "See also: `thread_close_title`, `thread_close_footer`, `thread_self_close_response`, `thread_creation_response`." ] @@ -547,7 +547,7 @@ "notes": [ "When `recipient_thread_close` is disabled or the thread wasn't closed by the recipient, `thread_close_response` is used instead of this configuration.", "You may use the `{{closer}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that closed the thread.", - "`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{loglink}}` for the unique key (ie. s3kf91a) of the log.", + "`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{logkey}}` for the unique key (ie. s3kf91a) of the log.", "Discord flavoured markdown is fully supported in `thread_self_close_response`.", "See also: `thread_close_title`, `thread_close_footer`, `thread_close_response`." ] From 6e75c448f24390bfd27990fbd33729e9295099cf Mon Sep 17 00:00:00 2001 From: Martin <55140357+martinbndr@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:49:10 +0100 Subject: [PATCH 699/705] Git Repository check for bot update (#3406) * Git Repository check for bot update Adds a check mechanism for the `?update` command and the autoupdate task to ensure the bot has been installed via git before trying to update it. * Fix typo in update command --------- Co-authored-by: Sebastian <61157793+sebkuip@users.noreply.github.com> --- bot.py | 33 +++++++++++++++++++++++++++++++++ cogs/utility.py | 29 +++++++++++++---------------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/bot.py b/bot.py index 6176ac5824..9f3de008a1 100644 --- a/bot.py +++ b/bot.py @@ -794,6 +794,33 @@ def check_manual_blocked(self, author: discord.Member) -> bool: logger.debug("User blocked, user %s.", author.name) return False + def check_local_git(self) -> bool: + """ + Checks if the bot is installed via git. + """ + valid_local_git = False + git_folder_path = os.path.join(".git") + + # Check if the .git folder exists and is a directory + if os.path.exists(git_folder_path) and os.path.isdir(git_folder_path): + required_files = ["config", "HEAD"] + required_dirs = ["refs", "objects"] + + # Verify required files exist + for file in required_files: + if not os.path.isfile(os.path.join(git_folder_path, file)): + return valid_local_git + + # Verify required directories exist + for directory in required_dirs: + if not os.path.isdir(os.path.join(git_folder_path, directory)): + return valid_local_git + + # If all checks pass, set valid_local_git to True + valid_local_git = True + + return valid_local_git + async def _process_blocked(self, message): _, blocked_emoji = await self.retrieve_emoji() if await self.is_blocked(message.author, channel=message.channel, send_message=True): @@ -2160,6 +2187,12 @@ async def before_autoupdate(self): self.autoupdate.cancel() return + if not self.check_local_git(): + logger.warning("Bot not installed via git.") + logger.warning("Autoupdates disabled.") + self.autoupdate.cancel() + return + @tasks.loop(hours=1, reconnect=False) async def log_expiry(self): log_expire_after = self.config.get("log_expiration") diff --git a/cogs/utility.py b/cogs/utility.py index 5b4de12ee9..d14aa97baa 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -2134,11 +2134,7 @@ async def update(self, ctx, *, flag: str = ""): data = await self.bot.api.get_user_info() if data: user = data["user"] - embed.set_author( - name=user["username"], - icon_url=user["avatar_url"] if user["avatar_url"] else None, - url=user["url"], - ) + embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) await ctx.send(embed=embed) else: error = None @@ -2177,7 +2173,7 @@ async def update(self, ctx, *, flag: str = ""): embed.set_author( name=user["username"] + " - Updating bot", - icon_url=user["avatar_url"] if user["avatar_url"] else None, + icon_url=user["avatar_url"], url=user["url"], ) @@ -2195,13 +2191,18 @@ async def update(self, ctx, *, flag: str = ""): color=self.bot.main_color, ) embed.set_footer(text="Force update") - embed.set_author( - name=user["username"], - icon_url=user["avatar_url"] if user["avatar_url"] else None, - url=user["url"], - ) + embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) await ctx.send(embed=embed) else: + if self.bot.check_local_git() is False: + embed = discord.Embed( + title="Update Command Unavailable", + description="The bot cannot be updated due to not being installed via git." + "You need to manually update the bot according to your hosting method." + "If you face any issues please don´t hesitate to contact modmail support.", + color=discord.Color.red(), + ) + return await ctx.send(embed=embed) command = "git pull" proc = await asyncio.create_subprocess_shell( command, @@ -2214,11 +2215,7 @@ async def update(self, ctx, *, flag: str = ""): res = res.decode("utf-8").rstrip() if err and not res: - embed = discord.Embed( - title="Update failed", - description=err, - color=self.bot.error_color, - ) + embed = discord.Embed(title="Update failed", description=err, color=self.bot.error_color) await ctx.send(embed=embed) elif res != "Already up to date.": From cfedecb24cfac541270b0fd1b6c59d2176a89c89 Mon Sep 17 00:00:00 2001 From: Martin <55140357+martinbndr@users.noreply.github.com> Date: Sun, 7 Dec 2025 19:31:51 +0100 Subject: [PATCH 700/705] Fix Plugin Help (#3322) * Updates Plugin Wiki Link As the github repo wiki got moved to the own docs page this link needs to be updated. I will update it accordingly if docs may change later. * Fix @local/name doc * Chnaged Plugin Help Link for #3322 Plugin Help link got moved again into a new page of the docs. --------- Co-authored-by: Sebastian <61157793+sebkuip@users.noreply.github.com> --- cogs/plugins.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cogs/plugins.py b/cogs/plugins.py index aa4ad5a65c..a5cece7ab6 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -113,7 +113,7 @@ class Plugins(commands.Cog): These addons could have a range of features from moderation to simply making your life as a moderator easier! Learn how to create a plugin yourself here: - https://github.com/modmail-dev/modmail/wiki/Plugins + https://docs.modmail.dev/usage-guide/plugins """ def __init__(self, bot): @@ -332,7 +332,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): embed = discord.Embed( description="Invalid plugin name, double check the plugin name " "or use one of the following formats: " - "username/repo/plugin-name, username/repo/plugin-name@branch, local/plugin-name.", + "username/repo/plugin-name, username/repo/plugin-name@branch, @local/plugin-name.", color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -357,7 +357,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) - or `local/name` for local plugins. + or `@local/name` for local plugins. """ plugin = await self.parse_user_input(ctx, plugin_name, check_version=True) @@ -444,7 +444,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): Remove an installed plugin of the bot. `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference - to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `local/name` for local plugins. + to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `@local/name` for local plugins. """ plugin = await self.parse_user_input(ctx, plugin_name) if plugin is None: @@ -526,7 +526,7 @@ async def plugins_update(self, ctx, *, plugin_name: str = None): Update a plugin for the bot. `plugin_name` can be the name of the plugin found in `{prefix}plugin registry`, or a direct reference - to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `local/name` for local plugins. + to a GitHub hosted plugin (in the format `user/repo/name[@branch]`) or `@local/name` for local plugins. To update all plugins, do `{prefix}plugins update`. """ From d2b504236181740d8103c5ed9cca4c12d63b52cc Mon Sep 17 00:00:00 2001 From: Sebastian <61157793+sebkuip@users.noreply.github.com> Date: Mon, 8 Dec 2025 12:09:45 +0100 Subject: [PATCH 701/705] Added submenu functionality to threadmenu. Fixes #3403 (#3404) * Threadmenu now supports submenus * Fix a small issue with path not resetting after main menu. * Fix copilot suggestions * Black formatting * Fix undeclared vars * threadmenu: submenu navigation fixes Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * threadmenu: submenu navigation fixes Refactor thread creation menu handling to improve path management and submenu navigation. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Fix formatting according to black --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Co-authored-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> --- cogs/threadmenu.py | 3 ++ core/thread.py | 108 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 94 insertions(+), 17 deletions(-) diff --git a/cogs/threadmenu.py b/cogs/threadmenu.py index 7f9e193844..0e225d527f 100644 --- a/cogs/threadmenu.py +++ b/cogs/threadmenu.py @@ -178,6 +178,9 @@ def typecheck(m): if label.lower() == "cancel": return await ctx.send("Cancelled.") + if label.lower() == "main menu": + return await ctx.send("You cannot use that label.") + if sanitized_label in conf["options"]: await ctx.send("That option already exists. Use `threadmenu edit` to edit it.") return diff --git a/core/thread.py b/core/thread.py index bf77180f8c..b3a9bf35a5 100644 --- a/core/thread.py +++ b/core/thread.py @@ -849,11 +849,9 @@ async def send_genesis_message(): if getattr(self, "_selected_thread_creation_menu_option", None) and self.bot.config.get( "thread_creation_menu_selection_log" ): - opt = self._selected_thread_creation_menu_option + path = self._selected_thread_creation_menu_option try: - log_txt = f"Selected menu option: {opt.get('label')} ({opt.get('type')})" - if opt.get("type") == "command": - log_txt += f" -> {opt.get('callback')}" + log_txt = f"Selected menu path: {' -> '.join(path)}" await channel.send(embed=discord.Embed(description=log_txt, color=self.bot.mod_color)) except Exception: logger.warning( @@ -2659,29 +2657,44 @@ async def create( placeholder = "Select an option to contact the staff team." timeout = 20 - options = self.bot.config.get("thread_creation_menu_options") or {} - submenus = self.bot.config.get("thread_creation_menu_submenus") or {} - # Minimal inline view implementation (avoid importing plugin code) thread.ready = False # not ready yet class _ThreadCreationMenuSelect(discord.ui.Select): - def __init__(self, outer_thread: Thread): + def __init__( + self, + bot, + outer_thread: Thread, + option_data: dict, + menu_msg: discord.Message, + path: list, + is_home: bool = True, + ): + self.bot = bot self.outer_thread = outer_thread - opts = [ + self.option_data = option_data + self.menu_msg = menu_msg + self.path = path + options = [ discord.SelectOption( label=o["label"], description=o["description"], emoji=o["emoji"], ) - for o in options.values() + for o in option_data.values() ] + if not is_home: + options.append( + discord.SelectOption( + label="main menu", description="Return to the main menu", emoji="🏠" + ) + ) super().__init__( placeholder=placeholder, min_values=1, max_values=1, - options=opts, + options=options, ) async def callback(self, interaction: discord.Interaction): @@ -2696,8 +2709,45 @@ async def callback(self, interaction: discord.Interaction): chosen_label = self.values[0] # Resolve option key key = chosen_label.lower().replace(" ", "_") - selected = options.get(key) - self.outer_thread._selected_thread_creation_menu_option = selected + if key == "main_menu": + option_data = self.bot.config.get("thread_creation_menu_options") or {} + new_view = _ThreadCreationMenuView( + self.bot, + self.outer_thread, + option_data, + self.menu_msg, + path=[], + is_home=True, + ) + return await self.menu_msg.edit(view=new_view) + selected: dict = self.option_data.get(key, {}) + next_path = [*self.path, chosen_label] + if selected.get("type", "command") == "submenu": + submenu_data = self.bot.config.get("thread_creation_menu_submenus") or {} + submenu_key = selected.get("callback", key) + option_data = submenu_data.get(submenu_key, {}) + if not option_data: + home_options = self.bot.config.get("thread_creation_menu_options") or {} + new_view = _ThreadCreationMenuView( + self.bot, + self.outer_thread, + home_options, + self.menu_msg, + path=[], + is_home=True, + ) + return await self.menu_msg.edit(view=new_view) + new_view = _ThreadCreationMenuView( + self.bot, + self.outer_thread, + option_data, + self.menu_msg, + path=next_path, + is_home=False, + ) + return await self.menu_msg.edit(view=new_view) + + self.outer_thread._selected_thread_creation_menu_option = next_path # Reflect the selection in the original DM by editing the embed/body try: msg = getattr(interaction, "message", None) @@ -2936,10 +2986,30 @@ async def callback(self, interaction: discord.Interaction): ctx_.command.checks = old_checks class _ThreadCreationMenuView(discord.ui.View): - def __init__(self, outer_thread: Thread): + def __init__( + self, + bot, + outer_thread: Thread, + option_data: dict, + menu_msg: discord.Message, + path: list, + is_home: bool = True, + ): super().__init__(timeout=timeout) self.outer_thread = outer_thread - self.add_item(_ThreadCreationMenuSelect(outer_thread)) + self.path = path + self.menu_msg = menu_msg + self.option_data = option_data + self.add_item( + _ThreadCreationMenuSelect( + bot, + outer_thread, + option_data=option_data, + menu_msg=menu_msg, + path=self.path, + is_home=is_home, + ) + ) async def on_timeout(self): # Timeout -> abort thread creation @@ -3061,8 +3131,12 @@ async def on_timeout(self): embed.set_thumbnail(url=embed_thumb) except Exception as e: logger.debug("Thumbnail set failed (ignored): %s", e) - menu_view = _ThreadCreationMenuView(thread) - menu_msg = await recipient.send(embed=embed, view=menu_view) + menu_msg = await recipient.send(embed=embed) + option_data = self.bot.config.get("thread_creation_menu_options") or {} + menu_view = _ThreadCreationMenuView( + self.bot, thread, option_data, menu_msg, path=[], is_home=True + ) + menu_msg = await menu_msg.edit(view=menu_view) # mark thread as pending menu selection thread._pending_menu = True # Explicitly attach the message to the view for safety in callbacks From 6e094af903f155fab29ca54210888443340454af Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:39:43 +0100 Subject: [PATCH 702/705] Fix: Blackformatting, workflows. Add snooze/unsnooze events. (#3412) * improvements changelog.md * remove advancedmenu plugin * fix: hide privatekey from changelog This is for internal use only. * black formatting * feat: dispatch event for snoozing/unsnoozing. This allows plugin developers to create feature on snoozing/unsnoozing. * bump pipfile * Update Pipfile.lock * black formatting * sync with pipfile. --------- Co-authored-by: Sebastian <61157793+sebkuip@users.noreply.github.com> --- CHANGELOG.md | 66 ++++++++++--- Pipfile | 17 ++-- Pipfile.lock | 218 ++++++++---------------------------------- core/thread.py | 6 ++ plugins/registry.json | 9 -- requirements.txt | 9 +- 6 files changed, 108 insertions(+), 217 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 536680ad2a..2b7a7e28ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,27 +9,65 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v4.2.1 ### Added + +**New Configuration Options:** * `unsnooze_history_limit`: Limits the number of messages replayed when unsnoozing (genesis message and notes are always shown). * `snooze_behavior`: Choose between `delete` (legacy) or `move` behavior for snoozing. * `snoozed_category_id`: Target category for `move` snoozing; required when `snooze_behavior` is `move`. -* Thread-creation menu: Adds an interactive select step before a thread channel is created. - * Commands: - * `threadmenu toggle`: Enable/disable the menu. - * `threadmenu show`: List current top-level options. - * `threadmenu option add`: Interactive wizard to create an option. - * `threadmenu option edit/remove/show`: Manage or inspect an existing option. - * `threadmenu submenu create/delete/list/show`: Manage submenus. - * `threadmenu submenu option add/edit/remove`: Manage options inside a submenu. - * Configuration / Behavior: - * Per-option `category` targeting when creating a thread; falls back to `main_category_id` if invalid/missing. - * Optional selection logging (`thread_creation_menu_selection_log`) posts the chosen option in the new thread. - * Anonymous prompt support (`thread_creation_menu_anonymous_menu`). +* `snooze_store_attachments`: When enabled, image attachments are stored as base64 when snoozing with delete behavior, allowing them to be re-uploaded on unsnooze. +* `snooze_attachment_max_bytes`: Maximum size per attachment to store as base64 (default: 4 MiB). +* `thread_creation_menu_timeout`: Timeout duration for user interaction with the menu (default: 30 seconds). +* `thread_creation_menu_close_on_timeout`: Silently abort thread creation if user doesn't select an option. +* `thread_creation_menu_anonymous_menu`: Anonymize the initial menu prompt relayed to staff. +* `thread_creation_menu_embed_text`: Text shown in the embed above the selection dropdown. +* `thread_creation_menu_dropdown_placeholder`: Placeholder text in the dropdown before selection. +* `thread_creation_menu_selection_log`: Log the chosen menu option in the newly created thread channel. +* `thread_creation_menu_precreate_channel`: Create thread channel immediately upon first DM even if menu is enabled. +* `thread_creation_menu_embed_title`: Optional title for the thread-creation menu embed. +* `thread_creation_menu_embed_footer`: Optional footer text for the menu embed. +* `thread_creation_menu_embed_footer_icon_url`: Optional URL for the footer icon. +* `thread_creation_menu_embed_thumbnail_url`: Optional thumbnail image URL. +* `thread_creation_menu_embed_image_url`: Optional large hero image URL for the menu embed. +* `thread_creation_menu_embed_large_image`: Promote thumbnail to large hero image if no separate image URL is set. +* `thread_creation_menu_embed_color`: Color for the menu embed's side strip. + +**Thread-Creation Menu Feature:** +* Full thread-creation menu system with interactive select menus: + * `?threadmenu toggle`: Enable/disable the menu globally. + * `?threadmenu show`: List current top-level options. + * `?threadmenu option add`: Interactive wizard to create an option. + * `?threadmenu option edit/remove/show`: Manage or inspect existing options. + * `?threadmenu submenu create/delete/list/show`: Manage submenus (nested menu levels). + * `?threadmenu submenu option add/edit/remove`: Manage options inside submenus. + * `?threadmenu dump_config`: Export current configuration to a file. + * `?threadmenu load_config`: Import configuration from a file. + * `?threadmenu reset`: Reset all thread-creation menu settings to defaults. +* Per-option category targeting: Each menu option can specify a target category where threads are created. +* Submenu support: Create up to 25 main-level options, each with up to 24 nested options. +* Optional selection logging: Log which menu option was chosen in the newly created thread channel. +* Anonymous menu support: Hide original prompt author context from staff when menu is anonymized. +* Category fallback: If an option's category is invalid/missing, creation falls back to `main_category_id`. + +**Snooze Enhancements:** +* Attachment persistence for delete-behavior snoozing: Image attachments can now be stored as base64 data. +* Enhanced unsnooze functionality with configurable message replay limits. +* Auto-unsnooze task continuously monitors and automatically unsnoozes threads when duration expires. ### Changed -- Renamed `max_snooze_time` to `snooze_default_duration`. The old config will be invalidated. +- Renamed `max_snooze_time` to `snooze_default_duration` (accepts seconds or human-readable time like "7 days"). - When `snooze_behavior` is set to `move`, the snoozed category now has a hard limit of 49 channels. New snoozes are blocked once it’s full until space is freed. - When switching `snooze_behavior` to `move` via `?config set`, the bot reminds admins to set `snoozed_category_id` if it’s missing. -- Thread-creation menu options & submenu options now support an optional per-option `category` target. The interactive wizards (`threadmenu option add` / `threadmenu submenu option add`) and edit commands allow specifying or updating a category. If the stored category is missing or invalid at selection time, channel creation automatically falls back to `main_category_id`. +- Thread-creation menu options and submenu options now support per-option `category` targeting. +- Category selection in menu option wizards allows specifying ID, name, or mention format. +- Snoozed thread restoration now respects `unsnooze_history_limit` (if set) to replay only the last N messages. +- Enhanced auto-unsnooze task monitors and automatically unsnoozes threads when their snooze duration expires. +- Snoozed threads can now be moved to a dedicated category instead of being deleted (via `snooze_behavior: move`). + +### Fixed + +- Corrected behavior when snooze channel count reaches the 49-channel limit in move-based snoozing. +- Improved category resolution in threadmenu wizards (handles ID, name, and mention formats reliably). +- Enhanced thread state restoration after unsnoozing to properly re-add all recipients. # v4.2.0 diff --git a/Pipfile b/Pipfile index daa0e60698..6feb42454e 100644 --- a/Pipfile +++ b/Pipfile @@ -7,28 +7,29 @@ verify_ssl = true bandit = ">=1.7.5" black = "==23.11.0" pylint = "==3.0.2" -tomli = "==2.2.1" # Needed for black on Python < 3.11 +tomli = "==2.2.1" [packages] aiohttp = "==3.13.2" -async-timeout = {version = "==5.0.1", markers = "python_version < '3.11'"} # Required by aiohttp -typing-extensions = ">=4.12.2" # Required by aiohttp +async-timeout = {version = "==5.0.1", markers = "python_version < '3.11'"} +typing-extensions = "==4.15.0" colorama = "==0.4.6" "discord.py" = {version = "==2.6.3", extras = ["speed"]} emoji = "==2.8.0" isodate = "==0.6.1" motor = "==3.7.1" -natural = "==0.2.0" # Why is this needed? +natural = "==0.2.0" packaging = "==23.2" parsedatetime = "==2.6" -dnspython = ">=2.8,<3" # Required by pymongo -pymongo = ">=4.9,<5" # Required by motor +dnspython = "==2.8.0" +pymongo = "==4.15.3" python-dateutil = "==2.8.2" python-dotenv = "==1.0.0" -uvloop = {version = ">=0.19.0", markers = "sys_platform != 'win32'"} +uvloop = {version = "==0.22.1", markers = "sys_platform != 'win32'"} lottie = {version = "==0.7.2", extras = ["pdf"]} -setuptools = "*" # Needed for lottie +setuptools = "==80.9.0" requests = "==2.31.0" +orjson = "==3.11.4" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 39cd6c33e2..011514b29b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b9e47a4bb95c39f0d11eeffe03c9229ef1751eec0e412c1a9b4c1f6dc47ed754" + "sha256": "6dc9fd3ca0aa2c413384ee16afb30290a840f6755cbf0bf828d0661171604db4" }, "pipfile-spec": 6, "requires": {}, @@ -14,14 +14,6 @@ ] }, "default": { - "aiodns": { - "hashes": [ - "sha256:11264edbab51896ecf546c18eb0dd56dff0428c6aa6d2cd87e643e07300eb310", - "sha256:6d0404f7d5215849233f6ee44854f2bb2481adf71b336b2279016ea5990ca5c5" - ], - "markers": "python_version >= '3.9'", - "version": "==3.5.0" - }, "aiohappyeyeballs": { "hashes": [ "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", @@ -181,61 +173,6 @@ "markers": "python_version >= '3.9'", "version": "==25.4.0" }, - "audioop-lts": { - "hashes": [ - "sha256:0337d658f9b81f4cd0fdb1f47635070cc084871a3d4646d9de74fdf4e7c3d24a", - "sha256:03f061a1915538fd96272bac9551841859dbb2e3bf73ebe4a23ef043766f5449", - "sha256:068aa17a38b4e0e7de771c62c60bbca2455924b67a8814f3b0dee92b5820c0b3", - "sha256:088327f00488cdeed296edd9215ca159f3a5a5034741465789cad403fcf4bec0", - "sha256:0d9385e96f9f6da847f4d571ce3cb15b5091140edf3db97276872647ce37efd7", - "sha256:106753a83a25ee4d6f473f2be6b0966fc1c9af7e0017192f5531a3e7463dce58", - "sha256:143fad0311e8209ece30a8dbddab3b65ab419cbe8c0dde6e8828da25999be911", - "sha256:15ab25dd3e620790f40e9ead897f91e79c0d3ce65fe193c8ed6c26cffdd24be7", - "sha256:167d3b62586faef8b6b2275c3218796b12621a60e43f7e9d5845d627b9c9b80e", - "sha256:2b267b70747d82125f1a021506565bdc5609a2b24bcb4773c16d79d2bb260bbd", - "sha256:3bcddaaf6cc5935a300a8387c99f7a7fbbe212a11568ec6cf6e4bc458c048636", - "sha256:3fc38008969796f0f689f1453722a0f463da1b8a6fbee11987830bfbb664f623", - "sha256:47eba38322370347b1c47024defbd36374a211e8dd5b0dcbce7b34fdb6f8847b", - "sha256:48159d96962674eccdca9a3df280e864e8ac75e40a577cc97c5c42667ffabfc5", - "sha256:49ee1a41738a23e98d98b937a0638357a2477bc99e61b0f768a8f654f45d9b7a", - "sha256:4a53aa7c16a60a6857e6b0b165261436396ef7293f8b5c9c828a3a203147ed4a", - "sha256:4b4cd51a57b698b2d06cb9993b7ac8dfe89a3b2878e96bc7948e9f19ff51dba6", - "sha256:51c916108c56aa6e426ce611946f901badac950ee2ddaf302b7ed35d9958970d", - "sha256:550c114a8df0aafe9a05442a1162dfc8fec37e9af1d625ae6060fed6e756f303", - "sha256:58cf54380c3884fb49fdd37dfb7a772632b6701d28edd3e2904743c5e1773602", - "sha256:5b00be98ccd0fc123dcfad31d50030d25fcf31488cde9e61692029cd7394733b", - "sha256:5f93a5db13927a37d2d09637ccca4b2b6b48c19cd9eda7b17a2e9f77edee6a6f", - "sha256:64d0c62d88e67b98a1a5e71987b7aa7b5bcffc7dcee65b635823dbdd0a8dbbd0", - "sha256:73f80bf4cd5d2ca7814da30a120de1f9408ee0619cc75da87d0641273d202a09", - "sha256:752d76472d9804ac60f0078c79cdae8b956f293177acd2316cd1e15149aee132", - "sha256:83c381767e2cc10e93e40281a04852facc4cd9334550e0f392f72d1c0a9c5753", - "sha256:8fefe5868cd082db1186f2837d64cfbfa78b548ea0d0543e9b28935ccce81ce9", - "sha256:9191d68659eda01e448188f60364c7763a7ca6653ed3f87ebb165822153a8547", - "sha256:96f19de485a2925314f5020e85911fb447ff5fbef56e8c7c6927851b95533a1c", - "sha256:9a13dc409f2564de15dd68be65b462ba0dde01b19663720c68c1140c782d1d75", - "sha256:a2c2a947fae7d1062ef08c4e369e0ba2086049a5e598fda41122535557012e9e", - "sha256:a2d4f1513d63c795e82948e1305f31a6d530626e5f9f2605408b300ae6095093", - "sha256:a5bf613e96f49712073de86f20dbdd4014ca18efd4d34ed18c75bd808337851b", - "sha256:a6d2e0f9f7a69403e388894d4ca5ada5c47230716a03f2847cfc7bd1ecb589d6", - "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", - "sha256:ba7c3a7e5f23e215cb271516197030c32aef2e754252c4c70a50aaff7031a2c8", - "sha256:c0022283e9556e0f3643b7c3c03f05063ca72b3063291834cca43234f20c60bb", - "sha256:c174e322bb5783c099aaf87faeb240c8d210686b04bd61dfd05a8e5a83d88969", - "sha256:c9c8e68d8b4a56fda8c025e538e639f8c5953f5073886b596c93ec9b620055e7", - "sha256:cfcac6aa6f42397471e4943e0feb2244549db5c5d01efcd02725b96af417f3fe", - "sha256:d5e73fa573e273e4f2e5ff96f9043858a5e9311e94ffefd88a3186a910c70917", - "sha256:def246fe9e180626731b26e89816e79aae2276f825420a07b4a647abaa84becc", - "sha256:dfbbc74ec68a0fd08cfec1f4b5e8cca3d3cd7de5501b01c4b5d209995033cde9", - "sha256:e160bf9df356d841bb6c180eeeea1834085464626dc1b68fa4e1d59070affdc3", - "sha256:e541c3ef484852ef36545f66209444c48b28661e864ccadb29daddb6a4b8e5f5", - "sha256:f9b0b8a03ef474f56d1a842af1a2e01398b8f7654009823c6d9e0ecff4d5cfbf", - "sha256:f9ee9b52f5f857fbaf9d605a360884f034c92c1c23021fb90b2e39b8e64bede6", - "sha256:fbdd522624141e40948ab3e8cdae6e04c748d78710e9f0f8d4dae2750831de19", - "sha256:fd3d4602dc64914d462924a08c1a9816435a2155d74f325853c1f1ac3b2d9800" - ], - "markers": "python_version >= '3.13'", - "version": "==0.2.2" - }, "brotli": { "hashes": [ "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24", @@ -359,11 +296,11 @@ }, "certifi": { "hashes": [ - "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", - "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43" + "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", + "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316" ], "markers": "python_version >= '3.7'", - "version": "==2025.10.5" + "version": "==2025.11.12" }, "cffi": { "hashes": [ @@ -1048,6 +985,7 @@ "sha256:fb1c37c71cad991ef4d89c7a634b5ffb4447dbd7ae3ae13e8f5ee7f1775e7ab1", "sha256:fb6a03a678085f64b97f9d4a9ae69376ce91a3a9e9b56a82b1580d8e1d501aff" ], + "index": "pypi", "markers": "python_version >= '3.9'", "version": "==3.11.4" }, @@ -1293,104 +1231,6 @@ "markers": "python_version >= '3.9'", "version": "==0.4.1" }, - "pycares": { - "hashes": [ - "sha256:00538826d2eaf4a0e4becb0753b0ac8d652334603c445c9566c9eb273657eb4c", - "sha256:066f3caa07c85e1a094aebd9e7a7bb3f3b2d97cff2276665693dd5c0cc81cf84", - "sha256:0aed0974eab3131d832e7e84a73ddb0dddbc57393cd8c0788d68a759a78c4a7b", - "sha256:1571a7055c03a95d5270c914034eac7f8bfa1b432fc1de53d871b821752191a4", - "sha256:1732db81e348bfce19c9bf9448ba660aea03042eeeea282824da1604a5bd4dcf", - "sha256:1dbbf0cfb39be63598b4cdc2522960627bf2f523e49c4349fb64b0499902ec7c", - "sha256:218619b912cef7c64a339ab0e231daea10c994a05699740714dff8c428b9694a", - "sha256:23d50a0842e8dbdddf870a7218a7ab5053b68892706b3a391ecb3d657424d266", - "sha256:29daa36548c04cdcd1a78ae187a4b7b003f0b357a2f4f1f98f9863373eedc759", - "sha256:2c296ab94d1974f8d2f76c499755a9ce31ffd4986e8898ef19b90e32525f7d84", - "sha256:2d5cac829da91ade70ce1af97dad448c6cd4778b48facbce1b015e16ced93642", - "sha256:30ceed06f3bf5eff865a34d21562c25a7f3dad0ed336b9dd415330e03a6c50c4", - "sha256:30d197180af626bb56f17e1fa54640838d7d12ed0f74665a3014f7155435b199", - "sha256:30feeab492ac609f38a0d30fab3dc1789bd19c48f725b2955bcaaef516e32a21", - "sha256:3139ec1f4450a4b253386035c5ecd2722582ae3320a456df5021ffe3f174260a", - "sha256:31b85ad00422b38f426e5733a71dfb7ee7eb65a99ea328c508d4f552b1760dc8", - "sha256:35ff1ec260372c97ed688efd5b3c6e5481f2274dea08f6c4ea864c195a9673c6", - "sha256:3784b80d797bcc2ff2bf3d4b27f46d8516fe1707ff3b82c2580dc977537387f9", - "sha256:386da2581db4ea2832629e275c061103b0be32f9391c5dfaea7f6040951950ad", - "sha256:3b44e54cad31d3c3be5e8149ac36bc1c163ec86e0664293402f6f846fb22ad00", - "sha256:3bd81ad69f607803f531ff5cfa1262391fa06e78488c13495cee0f70d02e0287", - "sha256:3d5300a598ad48bbf169fba1f2b2e4cf7ab229e7c1a48d8c1166f9ccf1755cb3", - "sha256:3db6b6439e378115572fa317053f3ee6eecb39097baafe9292320ff1a9df73e3", - "sha256:3ef1ab7abbd238bb2dbbe871c3ea39f5a7fc63547c015820c1e24d0d494a1689", - "sha256:45d3254a694459fdb0640ef08724ca9d4b4f6ff6d7161c9b526d7d2e2111379e", - "sha256:4b6f7581793d8bb3014028b8397f6f80b99db8842da58f4409839c29b16397ad", - "sha256:4da2e805ed8c789b9444ef4053f6ef8040cd13b0c1ca6d3c4fe6f9369c458cb4", - "sha256:5344d52efa37df74728505a81dd52c15df639adffd166f7ddca7a6318ecdb605", - "sha256:5d69e2034160e1219665decb8140e439afc7a7afcfd4adff08eb0f6142405c3e", - "sha256:5d70324ca1d82c6c4b00aa678347f7560d1ef2ce1d181978903459a97751543a", - "sha256:5e1ab899bb0763dea5d6569300aab3a205572e6e2d0ef1a33b8cf2b86d1312a4", - "sha256:6195208b16cce1a7b121727710a6f78e8403878c1017ab5a3f92158b048cec34", - "sha256:66c310773abe42479302abf064832f4a37c8d7f788f4d5ee0d43cbad35cf5ff4", - "sha256:6f74b1d944a50fa12c5006fd10b45e1a45da0c5d15570919ce48be88e428264c", - "sha256:6f751f5a0e4913b2787f237c2c69c11a53f599269012feaa9fb86d7cef3aec26", - "sha256:702d21823996f139874aba5aa9bb786d69e93bde6e3915b99832eb4e335d31ae", - "sha256:719f7ddff024fdacde97b926b4b26d0cc25901d5ef68bb994a581c420069936d", - "sha256:742fbaa44b418237dbd6bf8cdab205c98b3edb334436a972ad341b0ea296fb47", - "sha256:7570e0b50db619b2ee370461c462617225dc3a3f63f975c6f117e2f0c94f82ca", - "sha256:775d99966e28c8abd9910ddef2de0f1e173afc5a11cea9f184613c747373ab80", - "sha256:77bf82dc0beb81262bf1c7f546e1c1fde4992e5c8a2343b867ca201b85f9e1aa", - "sha256:7830709c23bbc43fbaefbb3dde57bdd295dc86732504b9d2e65044df8fd5e9fb", - "sha256:7aba9a312a620052133437f2363aae90ae4695ee61cb2ee07cbb9951d4c69ddd", - "sha256:80752133442dc7e6dd9410cec227c49f69283c038c316a8585cca05ec32c2766", - "sha256:836725754c32363d2c5d15b931b3ebd46b20185c02e850672cb6c5f0452c1e80", - "sha256:83a7401d7520fa14b00d85d68bcca47a0676c69996e8515d53733972286f9739", - "sha256:84b0b402dd333403fdce0e204aef1ef834d839c439c0c1aa143dc7d1237bb197", - "sha256:84fde689557361764f052850a2d68916050adbfd9321f6105aca1d8f1a9bd49b", - "sha256:87dab618fe116f1936f8461df5970fcf0befeba7531a36b0a86321332ff9c20b", - "sha256:8a75a406432ce39ce0ca41edff7486df6c970eb0fe5cfbe292f195a6b8654461", - "sha256:910ce19a549f493fb55cfd1d7d70960706a03de6bfc896c1429fc5d6216df77e", - "sha256:9518514e3e85646bac798d94d34bf5b8741ee0cb580512e8450ce884f526b7cf", - "sha256:95bc81f83fadb67f7f87914f216a0e141555ee17fd7f56e25aa0cc165e99e53b", - "sha256:96e07d5a8b733d753e37d1f7138e7321d2316bb3f0f663ab4e3d500fabc82807", - "sha256:97d971b3a88a803bb95ff8a40ea4d68da59319eb8b59e924e318e2560af8c16d", - "sha256:9a00408105901ede92e318eecb46d0e661d7d093d0a9b1224c71b5dd94f79e83", - "sha256:9d0c543bdeefa4794582ef48f3c59e5e7a43d672a4bfad9cbbd531e897911690", - "sha256:a4060d8556c908660512d42df1f4a874e4e91b81f79e3a9090afedc7690ea5ba", - "sha256:a98fac4a3d4f780817016b6f00a8a2c2f41df5d25dfa8e5b1aa0d783645a6566", - "sha256:aa160dc9e785212c49c12bb891e242c949758b99542946cc8e2098ef391f93b0", - "sha256:aca981fc00c8af8d5b9254ea5c2f276df8ece089b081af1ef4856fbcfc7c698a", - "sha256:afc6503adf8b35c21183b9387be64ca6810644ef54c9ef6c99d1d5635c01601b", - "sha256:b50ca218a3e2e23cbda395fd002d030385202fbb8182aa87e11bea0a568bd0b8", - "sha256:b93d624560ba52287873bacff70b42c99943821ecbc810b959b0953560f53c36", - "sha256:bac55842047567ddae177fb8189b89a60633ac956d5d37260f7f71b517fd8b87", - "sha256:c0eec184df42fc82e43197e073f9cc8f93b25ad2f11f230c64c2dc1c80dbc078", - "sha256:c2971af3a4094280f7c24293ff4d361689c175c1ebcbea6b3c1560eaff7cb240", - "sha256:c2af7a9d3afb63da31df1456d38b91555a6c147710a116d5cc70ab1e9f457a4f", - "sha256:c863d9003ca0ce7df26429007859afd2a621d3276ed9fef154a9123db9252557", - "sha256:c9d839b5700542b27c1a0d359cbfad6496341e7c819c7fea63db9588857065ed", - "sha256:cb711a66246561f1cae51244deef700eef75481a70d99611fd3c8ab5bd69ab49", - "sha256:cdac992206756b024b371760c55719eb5cd9d6b2cb25a8d5a04ae1b0ff426232", - "sha256:cf306f3951740d7bed36149a6d8d656a7d5432dd4bbc6af3bb6554361fc87401", - "sha256:d2a3526dbf6cb01b355e8867079c9356a8df48706b4b099ac0bf59d4656e610d", - "sha256:d552fb2cb513ce910d1dc22dbba6420758a991a356f3cd1b7ec73a9e31f94d01", - "sha256:d5fe089be67bc5927f0c0bd60c082c79f22cf299635ee3ddd370ae2a6e8b4ae0", - "sha256:dc54a21586c096df73f06f9bdf594e8d86d7be84e5d4266358ce81c04c3cc88c", - "sha256:dcd4a7761fdfb5aaac88adad0a734dd065c038f5982a8c4b0dd28efa0bd9cc7c", - "sha256:dde02314eefb85dce3cfdd747e8b44c69a94d442c0d7221b7de151ee4c93f0f5", - "sha256:df0a17f4e677d57bca3624752bbb515316522ad1ce0de07ed9d920e6c4ee5d35", - "sha256:e0fcd3a8bac57a0987d9b09953ba0f8703eb9dca7c77f7051d8c2ed001185be8", - "sha256:e2f8d9cfe0eb3a2997fde5df99b1aaea5a46dabfcfcac97b2d05f027c2cd5e28", - "sha256:ea785d1f232b42b325578f0c8a2fa348192e182cc84a1e862896076a4a2ba2a7", - "sha256:eddf5e520bb88b23b04ac1f28f5e9a7c77c718b8b4af3a4a7a2cc4a600f34502", - "sha256:ee1ea367835eb441d246164c09d1f9703197af4425fc6865cefcde9e2ca81f85", - "sha256:ee751409322ff10709ee867d5aea1dc8431eec7f34835f0f67afd016178da134", - "sha256:f199702740f3b766ed8c70efb885538be76cb48cd0cb596b948626f0b825e07a", - "sha256:f4695153333607e63068580f2979b377b641a03bc36e02813659ffbea2b76fe2", - "sha256:f6c602c5e3615abbf43dbdf3c6c64c65e76e5aa23cb74e18466b55d4a2095468", - "sha256:faa8321bc2a366189dcf87b3823e030edf5ac97a6b9a7fc99f1926c4bf8ef28e", - "sha256:ff3d25883b7865ea34c00084dd22a7be7c58fd3131db6b25c35eafae84398f9d", - "sha256:ffb22cee640bc12ee0e654eba74ecfb59e2e0aebc5bccc3cc7ef92f487008af7" - ], - "markers": "python_version >= '3.9'", - "version": "==4.11.0" - }, "pycparser": { "hashes": [ "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", @@ -1523,11 +1363,11 @@ }, "tinycss2": { "hashes": [ - "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", - "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289" + "sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661", + "sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957" ], - "markers": "python_version >= '3.8'", - "version": "==1.4.0" + "markers": "python_version >= '3.10'", + "version": "==1.5.1" }, "typing-extensions": { "hashes": [ @@ -1861,12 +1701,12 @@ }, "bandit": { "hashes": [ - "sha256:3348e934d736fcdb68b6aa4030487097e23a501adf3e7827b63658df464dddd0", - "sha256:dbfe9c25fc6961c2078593de55fd19f2559f9e45b99f1272341f5b95dea4e56b" + "sha256:32410415cd93bf9c8b91972159d5cf1e7f063a9146d70345641cd3877de348ce", + "sha256:bda8d68610fc33a6e10b7a8f1d61d92c8f6c004051d5e946406be1fb1b16a868" ], "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==1.8.6" + "markers": "python_version >= '3.10'", + "version": "==1.9.2" }, "black": { "hashes": [ @@ -1895,11 +1735,20 @@ }, "click": { "hashes": [ - "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", - "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4" + "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", + "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6" ], "markers": "python_version >= '3.10'", - "version": "==8.3.0" + "version": "==8.3.1" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.4.6" }, "dill": { "hashes": [ @@ -2080,11 +1929,11 @@ }, "stevedore": { "hashes": [ - "sha256:18363d4d268181e8e8452e71a38cd77630f345b2ef6b4a8d5614dac5ee0d18cf", - "sha256:d31496a4f4df9825e1a1e4f1f74d19abb0154aff311c3b376fcc89dae8fccd73" + "sha256:4a36dccefd7aeea0c70135526cecb7766c4c84c473b1af68db23d541b6dc1820", + "sha256:f22d15c6ead40c5bbfa9ca54aa7e7b4a07d59b36ae03ed12ced1a54cf0b51945" ], - "markers": "python_version >= '3.9'", - "version": "==5.5.0" + "markers": "python_version >= '3.10'", + "version": "==5.6.0" }, "tomli": { "hashes": [ @@ -2132,6 +1981,15 @@ ], "markers": "python_version >= '3.8'", "version": "==0.13.3" + }, + "typing-extensions": { + "hashes": [ + "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", + "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==4.15.0" } } } diff --git a/core/thread.py b/core/thread.py index b3a9bf35a5..09263b197d 100644 --- a/core/thread.py +++ b/core/thread.py @@ -259,6 +259,9 @@ async def snooze(self, moderator=None, command_used=None, snooze_for=None): logging.info(f"[SNOOZE] DB update result: {result.modified_count}") + # Dispatch thread_snoozed event for plugins + self.bot.dispatch("thread_snoozed", self, moderator, snooze_for) + behavior = behavior_pre if behavior == "move": # Move the channel to the snoozed category (if configured) and optionally apply a prefix @@ -751,6 +754,9 @@ async def _ensure_genesis(force: bool = False): # Mark unsnooze as complete self._unsnoozing = False + # Dispatch thread_unsnoozed event for plugins + self.bot.dispatch("thread_unsnoozed", self) + # Process queued commands await self._process_command_queue() diff --git a/plugins/registry.json b/plugins/registry.json index 4079001a50..506df880bd 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -1,13 +1,4 @@ { - "advanced-menu": { - "repository": "sebkuip/mm-plugins", - "branch": "master", - "description": "Advanced menu plugin using dropdown selectors. Supports submenus (and sub-submenus infinitely).", - "bot_version": "v4.0.0", - "title": "Advanced menu", - "icon_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png", - "thumbnail_url": "https://raw.githubusercontent.com/sebkuip/mm-plugins/master/advanced-menu/logo.png" - }, "announcement": { "repository": "Jerrie-Aries/modmail-plugins", "branch": "master", diff --git a/requirements.txt b/requirements.txt index 9c07172039..1120657d07 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1,13 @@ --i https://pypi.org/simple -aiodns==3.5.0; python_version >= '3.9' +-i https://pypi.org/simple aiohappyeyeballs==2.6.1; python_version >= '3.9' aiohttp==3.13.2; python_version >= '3.9' aiosignal==1.4.0; python_version >= '3.9' async-timeout==5.0.1; python_version < '3.11' attrs==25.4.0; python_version >= '3.9' -audioop-lts==0.2.2; python_version >= '3.13' brotli==1.2.0 cairocffi==1.7.1; python_version >= '3.8' cairosvg==2.8.2; python_version >= '3.9' -certifi==2025.10.5; python_version >= '3.7' +certifi==2025.11.12; python_version >= '3.7' cffi==2.0.0; python_version >= '3.9' charset-normalizer==3.4.4; python_version >= '3.7' colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' @@ -30,7 +28,6 @@ packaging==23.2; python_version >= '3.7' parsedatetime==2.6 pillow==12.0.0; python_version >= '3.10' propcache==0.4.1; python_version >= '3.9' -pycares==4.11.0; python_version >= '3.9' pycparser==2.23; python_version >= '3.8' pymongo==4.15.3; python_version >= '3.9' python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' @@ -38,7 +35,7 @@ python-dotenv==1.0.0; python_version >= '3.8' requests==2.31.0; python_version >= '3.7' setuptools==80.9.0; python_version >= '3.9' six==1.17.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' -tinycss2==1.4.0; python_version >= '3.8' +tinycss2==1.5.1; python_version >= '3.10' typing-extensions==4.15.0; python_version >= '3.9' urllib3==2.5.0; python_version >= '3.9' uvloop==0.22.1; sys_platform != 'win32' From 3c3608fb2cc875c21b59e4875fbba3cda8c0897a Mon Sep 17 00:00:00 2001 From: Martin <55140357+martinbndr@users.noreply.github.com> Date: Sat, 13 Dec 2025 23:55:19 +0100 Subject: [PATCH 703/705] Add threadmenu toggle notice (#3411) * Add threadmenu toggle notice Adds a notice to the `threadmenu toggle` command. It gets displayed if the advancedmenu plugin is part of the bot and checks if its enabled at the same time. useful for users because both would interrupt eachother. * Threadmenu toggle notice link Adds a link to the migration guide for the legacy plugin. --- cogs/threadmenu.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cogs/threadmenu.py b/cogs/threadmenu.py index 0e225d527f..4f4f1985ae 100644 --- a/cogs/threadmenu.py +++ b/cogs/threadmenu.py @@ -87,6 +87,19 @@ async def threadmenu_toggle(self, ctx): conf["enabled"] = not conf["enabled"] await self._save_conf(conf) await ctx.send(f"Thread-creation menu is now {'enabled' if conf['enabled'] else 'disabled'}.") + advancedmenu_plugin = self.bot.get_cog("AdvancedMenu") + if ( + advancedmenu_plugin + and hasattr(advancedmenu_plugin, "config") + and advancedmenu_plugin.config.get("enabled") + and advancedmenu_plugin.config["enabled"] is True + and conf["enabled"] + ): + await ctx.send( + "**Warning:** You are using both the core threadmenu feature and the advancedmenu plugin.\n" + "It is recommended to disable/uninstall the advancedmenu plugin to avoid interruption.\n" + "Migration guide can be found at: <https://docs.modmail.dev/usage-guide/threadmenu#advanced-legacy-usage>" + ) @checks.has_permissions(PermissionLevel.ADMINISTRATOR) @threadmenu.command(name="show") From ab458f5b09499fe009359a550c1f170d46215cc2 Mon Sep 17 00:00:00 2001 From: Martin <55140357+martinbndr@users.noreply.github.com> Date: Sat, 20 Dec 2025 20:38:28 +0100 Subject: [PATCH 704/705] Improvements for alias creation/editing (#3422) Improves the make_alias function. --- cogs/utility.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index d14aa97baa..6047ae1205 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1129,7 +1129,7 @@ async def alias_raw(self, ctx, *, name: str.lower): return await ctx.send(embed=embed) - async def make_alias(self, name, value, action): + async def make_alias(self, name, value, action, ctx): values = utils.parse_alias(value) if not values: embed = discord.Embed( @@ -1176,16 +1176,23 @@ async def make_alias(self, name, value, action): if multiple_alias: embed.description = ( "The command you are attempting to point " - f"to does not exist: `{linked_command}`." + f"to on step {i} does not exist: `{linked_command}`." ) else: embed.description = ( "The command you are attempting to point " - f"to on step {i} does not exist: `{linked_command}`." + f"to does not exist: `{linked_command}`." ) return embed else: + if linked_command == "eval" and not await checks.check_permissions(ctx, "eval"): + embed = discord.Embed( + title="Error", + description="You can only add the `eval` command to an alias if you have permissions for that command.", + color=self.bot.error_color, + ) + return embed save_aliases.append(val) if multiple_alias: embed.add_field(name=f"Step {i}:", value=utils.truncate(val, 1024)) @@ -1240,7 +1247,7 @@ async def alias_add(self, ctx, name: str.lower, *, value): ) if embed is None: - embed = await self.make_alias(name, value, "Added") + embed = await self.make_alias(name, value, "Added", ctx) return await ctx.send(embed=embed) @alias.command(name="remove", aliases=["del", "delete"]) @@ -1272,7 +1279,7 @@ async def alias_edit(self, ctx, name: str.lower, *, value): embed = utils.create_not_found_embed(name, self.bot.aliases.keys(), "Alias") return await ctx.send(embed=embed) - embed = await self.make_alias(name, value, "Edited") + embed = await self.make_alias(name, value, "Edited", ctx) return await ctx.send(embed=embed) @alias.command(name="rename") From ad801b117ca4ab9b2474190dc8669879aa8bcd47 Mon Sep 17 00:00:00 2001 From: Martin <55140357+martinbndr@users.noreply.github.com> Date: Sat, 20 Dec 2025 22:43:25 +0100 Subject: [PATCH 705/705] Fixes thread_auto_close execution when disabled. (#3423) * Fixes thread_auto_close execution when disabled. This fixes the issue #3290 which caused threads to be auto-closed even if `thread_auto_close` has been disabled. There was also an issue that closed the thread when the user has responded to mods. The thread should stay open and only auto close when the staff has replied back. * fix: prevent autoclosing when close has been cancelled. This solves the thread from autoclosing if the closure has been cancelled earlier in a thread. * fix: AttributeError / lower mongo calls. I had added a small bugfix aswell for pagination when an invalid config var was given. This happened to occur upon removing the `thread_auto_close` config. --------- Co-authored-by: lorenzo132 <lhoorn4@gmail.com> Co-authored-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> --- cogs/utility.py | 33 ++++++++++++++++++++++++++------- core/thread.py | 9 ++++++++- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 6047ae1205..deae14f19e 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -873,14 +873,33 @@ async def config_remove(self, ctx, *, key: str.lower): color=self.bot.main_color, description=f"`{key}` had been reset to default.", ) + + # Cancel exsisting active closures from thread_auto_close due to being disabled. + if key == "thread_auto_close": + closures = self.bot.config["closures"] + for recipient_id, items in tuple(closures.items()): + if items.get("auto_close", False) is True: + self.bot.config["closures"].pop(recipient_id) + thread = await self.bot.threads.find(recipient_id=int(recipient_id)) + if thread: + await thread.cancel_closure(all=True) + else: + self.bot.config["closures"].pop(recipient_id) + # Only update config once after processing all closures + await self.bot.config.update() else: - embed = discord.Embed( - title="Error", - color=self.bot.error_color, - description=f"{key} is an invalid key.", - ) - valid_keys = [f"`{k}`" for k in sorted(keys)] - embed.add_field(name="Valid keys", value=", ".join(valid_keys)) + embeds = [] + for names in zip_longest(*(iter(sorted(keys)),) * 15): + description = "\n".join(f"`{name}`" for name in takewhile(lambda x: x is not None, names)) + embed = discord.Embed( + title="Error - Invalid Key", + color=self.bot.error_color, + description=f"`{key}` is an invalid key.\n\n**Valid configuration keys:**\n{description}", + ) + embeds.append(embed) + + session = EmbedPaginatorSession(ctx, *embeds) + return await session.run() return await ctx.send(embed=embed) diff --git a/core/thread.py b/core/thread.py index 09263b197d..45a6cb9c71 100644 --- a/core/thread.py +++ b/core/thread.py @@ -67,6 +67,7 @@ def __init__( self.wait_tasks = [] self.close_task = None self.auto_close_task = None + self.auto_close_cancelled = False # Track if auto-close was explicitly cancelled self._cancelled = False self._dm_menu_msg_id = None self._dm_menu_channel_id = None @@ -1078,6 +1079,7 @@ async def close( self.auto_close_task = task else: self.close_task = task + self.auto_close_cancelled = False # Reset flag when manually closing else: await self._close(closer, silent, delete_channel, message) @@ -1278,6 +1280,7 @@ async def cancel_closure(self, auto_close: bool = False, all: bool = False) -> N if self.auto_close_task is not None and (auto_close or all): self.auto_close_task.cancel() self.auto_close_task = None + self.auto_close_cancelled = True # Mark auto-close as explicitly cancelled to_update = self.bot.config["closures"].pop(str(self.id), None) if to_update is not None: @@ -1810,7 +1813,11 @@ async def send( return await destination.send(embed=embed) if not note and from_mod: - self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close + # Only restart auto-close if it wasn't explicitly cancelled + if not self.auto_close_cancelled: + self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close + elif not note and not from_mod: + await self.cancel_closure(all=True) if self.close_task is not None: # cancel closing if a thread message is sent.

      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 Date: Tue, 10 Nov 2020 23:31:31 +0800 Subject: [PATCH 155/705] Bump version to dev12 --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index b85a61856b..7a04011382 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev11" +__version__ = "3.7.0-dev12" import asyncio From ff9888bc34d3dcaaa640dd08002458b5db7b43f7 Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Tue, 10 Nov 2020 07:56:42 -0800 Subject: [PATCH 156/705] Create and delete persistent notes --- cogs/modmail.py | 2 +- core/clients.py | 34 +++++++++++++++++++++++++----- core/thread.py | 56 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 07fb0c5b7b..41040b5ead 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -901,7 +901,7 @@ async def note_persistent(self, ctx, *, msg: str = ""): async with ctx.typing(): msg = await ctx.thread.note(ctx.message, persistent=True) await msg.pin() - await self.bot.api.create_note(recipient=ctx.thread.recipient, message=ctx.message) + await self.bot.api.create_note(recipient=ctx.thread.recipient, message=ctx.message, message_id=msg.id) @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) diff --git a/core/clients.py b/core/clients.py index 6d74290105..b03b85044a 100644 --- a/core/clients.py +++ b/core/clients.py @@ -142,6 +142,21 @@ async def search_closed_by(self, user_id: Union[int, str]): async def search_by_text(self, text: str, limit: Optional[int]): return NotImplemented + async def create_note(self, recipient: Member, message: Message, message_id: Union[int, str]): + return NotImplemented + + async def find_notes(self, recipient: Member): + return NotImplemented + + async def update_note_ids(self, ids: dict): + return NotImplemented + + async def delete_note(self, message_id: Union[int, str]): + return NotImplemented + + async def edit_note(self, message_id: Union[int, str]): + return NotImplemented + def get_plugin_partition(self, cog): return NotImplemented @@ -401,7 +416,7 @@ async def search_by_text(self, text: str, limit: Optional[int]): {"messages": {"$slice": 5}}, ).to_list(limit) - async def create_note(self, recipient: Member, message: Message): + async def create_note(self, recipient: Member, message: Message, message_id: Union[int, str]): await self.db.notes.insert_one( { "recipient": str(recipient.id), @@ -409,17 +424,26 @@ async def create_note(self, recipient: Member, message: Message): "id": str(message.author.id), "name": message.author.name, "discriminator": message.author.discriminator, - "avatar_url": str(message.author.avatar_url), + "avatar_url": str(message.author.avatar_url) }, + "message": message.content, + "message_id": str(message_id), } ) - async def delete_note(self): - pass - async def find_notes(self, recipient: Member): return await self.db.notes.find({"recipient": str(recipient.id)}).to_list(None) + async def update_note_ids(self, ids: dict): + for object_id, message_id in ids.items(): + await self.db.notes.update_one({"_id": object_id}, {"$set": {"message_id": message_id}}) + + async def delete_note(self, message_id: Union[int, str]): + await self.db.notes.delete_one({"message_id": str(message_id)}) + + async def edit_note(self, message_id: Union[int, str]): + return NotImplemented + def get_plugin_partition(self, cog): cls_name = cog.__class__.__name__ return self.db.plugins[cls_name] diff --git a/core/thread.py b/core/thread.py index 7786e89ace..e4cac3e666 100644 --- a/core/thread.py +++ b/core/thread.py @@ -3,6 +3,7 @@ import re import typing from datetime import datetime, timedelta +import time from types import SimpleNamespace import isodate @@ -191,13 +192,42 @@ async def send_recipient_genesis_message(): await self.bot.add_reaction(msg, close_emoji) async def send_persistent_notes(): - notes = await self.bot.api.find_notes() + notes = await self.bot.api.find_notes(self.recipient) + ids = {} + + class State: + def store_user(self, user): + return user + for note in notes: - message = discord.Message() - await self.note(note.message) - pass + author = note["author"] + + class Author: + name = author["name"] + id = author["id"] + discriminator = author["discriminator"] + avatar_url = author["avatar_url"] + + data = { + "id": round(time.time() * 1000 - discord.utils.DISCORD_EPOCH) << 22, + "attachments": {}, + "embeds": {}, + "edited_timestamp": None, + "type": None, + "pinned": None, + "mention_everyone": None, + "tts": None, + "content": note["message"], + "author": Author(), + } + message = discord.Message(state=State(), channel=None, data=data) + ids[note["_id"]] = str((await self.note(message, persistent=True, thread_creation=True)).id) + + await self.bot.api.update_note_ids(ids) - await asyncio.gather(send_genesis_message(), send_recipient_genesis_message()) + await asyncio.gather( + send_genesis_message(), send_recipient_genesis_message(), send_persistent_notes() + ) self.bot.dispatch("thread_ready", self) def _format_info_embed(self, user, log_url, log_count, color): @@ -517,11 +547,14 @@ async def find_linked_messages( ): raise ValueError("Thread message not found.") - if message1.embeds[0].color.value == self.bot.main_color and message1.embeds[ - 0 - ].author.name.startswith("Note"): + if message1.embeds[0].color.value == self.bot.main_color and ( + message1.embeds[0].author.name.startswith("Note") + or message1.embeds[0].author.name.startswith("Persistent Note") + ): if not note: raise ValueError("Thread message not found.") + elif message1.embeds[0].author.name.startswith("Persistent Note"): + await self.bot.api.delete_note(message_id) return message1, None if message1.embeds[0].color.value != self.bot.mod_color and not ( @@ -636,11 +669,11 @@ async def edit_dm_message(self, message: discord.Message, content: str) -> None: self.bot.api.edit_message(message.id, content), linked_message.edit(embed=embed) ) - async def note(self, message: discord.Message, persistent=False) -> None: + async def note(self, message: discord.Message, persistent=False, thread_creation=False) -> None: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) - msg = await self.send(message, self.channel, note=True, persistent_note=persistent) + msg = await self.send(message, self.channel, note=True, persistent_note=persistent, thread_creation=thread_creation) self.bot.loop.create_task( self.bot.api.append_log( @@ -727,6 +760,7 @@ async def send( anonymous: bool = False, plain: bool = False, persistent_note: bool = False, + thread_creation: bool = False, ) -> None: self.bot.loop.create_task( @@ -876,7 +910,7 @@ async def send( embed.set_footer(text=f"Message ID: {message.id}") embed.colour = self.bot.recipient_color - if from_mod or note: + if (from_mod or note) and not thread_creation: delete_message = not bool(message.attachments) if delete_message and destination == self.channel: try: From c097db9c305182daad883cd276d8ae2b56904f61 Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Tue, 10 Nov 2020 18:40:15 -0800 Subject: [PATCH 157/705] move api.delete_note to the right place --- core/thread.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/thread.py b/core/thread.py index 0f11aba6c7..0094b9bf2f 100644 --- a/core/thread.py +++ b/core/thread.py @@ -569,8 +569,6 @@ async def find_linked_messages( ): if not note: raise ValueError("Thread message not found.") - elif message1.embeds[0].author.name.startswith("Persistent Note"): - await self.bot.api.delete_note(message_id) return message1, None if message1.embeds[0].color.value != self.bot.mod_color and not ( @@ -646,6 +644,8 @@ async def delete_message( tasks += [message1.delete()] if message2 is not None: tasks += [message2.delete()] + elif message1.embeds[0].author.name.startswith("Persistent Note"): + await self.bot.api.delete_note(message1.id) if tasks: await asyncio.gather(*tasks) From 55281cc27f682d610779b0f9c8350e748149919c Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Tue, 10 Nov 2020 18:42:54 -0800 Subject: [PATCH 158/705] add to tasks --- core/thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread.py b/core/thread.py index 0094b9bf2f..2dd20ce4d2 100644 --- a/core/thread.py +++ b/core/thread.py @@ -645,7 +645,7 @@ async def delete_message( if message2 is not None: tasks += [message2.delete()] elif message1.embeds[0].author.name.startswith("Persistent Note"): - await self.bot.api.delete_note(message1.id) + tasks += [self.bot.api.delete_note(message1.id)] if tasks: await asyncio.gather(*tasks) From 18bcb9eb7505d1cc3421e429f6d89478b2ffce71 Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Tue, 10 Nov 2020 18:47:15 -0800 Subject: [PATCH 159/705] edit persistent notes --- core/clients.py | 6 +++--- core/thread.py | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/clients.py b/core/clients.py index b03b85044a..300425be53 100644 --- a/core/clients.py +++ b/core/clients.py @@ -154,7 +154,7 @@ async def update_note_ids(self, ids: dict): async def delete_note(self, message_id: Union[int, str]): return NotImplemented - async def edit_note(self, message_id: Union[int, str]): + async def edit_note(self, message_id: Union[int, str], message: str): return NotImplemented def get_plugin_partition(self, cog): @@ -441,8 +441,8 @@ async def update_note_ids(self, ids: dict): async def delete_note(self, message_id: Union[int, str]): await self.db.notes.delete_one({"message_id": str(message_id)}) - async def edit_note(self, message_id: Union[int, str]): - return NotImplemented + async def edit_note(self, message_id: Union[int, str], message: str): + await self.db.notes.update_one({"message_id": str(message_id)}, {"$set": {"message": message}}) def get_plugin_partition(self, cog): cls_name = cog.__class__.__name__ diff --git a/core/thread.py b/core/thread.py index 2dd20ce4d2..3562d98ee3 100644 --- a/core/thread.py +++ b/core/thread.py @@ -629,6 +629,8 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) -> embed2 = message2.embeds[0] embed2.description = message tasks += [message2.edit(embed=embed2)] + elif message1.embeds[0].author.name.startswith("Persistent Note"): + tasks += [self.bot.api.edit_note(message1.id, message)] await asyncio.gather(*tasks) From 18d3b4b7e1a7c6f8b8d6fd5f992ac09281d0cf88 Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Tue, 10 Nov 2020 18:49:58 -0800 Subject: [PATCH 160/705] format --- cogs/modmail.py | 4 +++- core/clients.py | 10 +++++++--- core/thread.py | 21 +++++++++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/cogs/modmail.py b/cogs/modmail.py index 3207bcdd5b..b977d8fdf4 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -899,7 +899,9 @@ async def note_persistent(self, ctx, *, msg: str = ""): async with ctx.typing(): msg = await ctx.thread.note(ctx.message, persistent=True) await msg.pin() - await self.bot.api.create_note(recipient=ctx.thread.recipient, message=ctx.message, message_id=msg.id) + await self.bot.api.create_note( + recipient=ctx.thread.recipient, message=ctx.message, message_id=msg.id + ) @commands.command() @checks.has_permissions(PermissionLevel.SUPPORTER) diff --git a/core/clients.py b/core/clients.py index 300425be53..62f565f91c 100644 --- a/core/clients.py +++ b/core/clients.py @@ -424,7 +424,7 @@ async def create_note(self, recipient: Member, message: Message, message_id: Uni "id": str(message.author.id), "name": message.author.name, "discriminator": message.author.discriminator, - "avatar_url": str(message.author.avatar_url) + "avatar_url": str(message.author.avatar_url), }, "message": message.content, "message_id": str(message_id), @@ -436,13 +436,17 @@ async def find_notes(self, recipient: Member): async def update_note_ids(self, ids: dict): for object_id, message_id in ids.items(): - await self.db.notes.update_one({"_id": object_id}, {"$set": {"message_id": message_id}}) + await self.db.notes.update_one( + {"_id": object_id}, {"$set": {"message_id": message_id}} + ) async def delete_note(self, message_id: Union[int, str]): await self.db.notes.delete_one({"message_id": str(message_id)}) async def edit_note(self, message_id: Union[int, str], message: str): - await self.db.notes.update_one({"message_id": str(message_id)}, {"$set": {"message": message}}) + await self.db.notes.update_one( + {"message_id": str(message_id)}, {"$set": {"message": message}} + ) def get_plugin_partition(self, cog): cls_name = cog.__class__.__name__ diff --git a/core/thread.py b/core/thread.py index 3562d98ee3..b9bf261b12 100644 --- a/core/thread.py +++ b/core/thread.py @@ -229,7 +229,9 @@ class Author: "author": Author(), } message = discord.Message(state=State(), channel=None, data=data) - ids[note["_id"]] = str((await self.note(message, persistent=True, thread_creation=True)).id) + ids[note["_id"]] = str( + (await self.note(message, persistent=True, thread_creation=True)).id + ) await self.bot.api.update_note_ids(ids) @@ -242,7 +244,10 @@ async def activate_auto_triggers(): pass await asyncio.gather( - send_genesis_message(), send_recipient_genesis_message(), activate_auto_triggers(), send_persistent_notes(), + send_genesis_message(), + send_recipient_genesis_message(), + activate_auto_triggers(), + send_persistent_notes(), ) self.bot.dispatch("thread_ready", self) @@ -687,11 +692,19 @@ async def edit_dm_message(self, message: discord.Message, content: str) -> None: self.bot.api.edit_message(message.id, content), linked_message.edit(embed=embed) ) - async def note(self, message: discord.Message, persistent=False, thread_creation=False) -> None: + async def note( + self, message: discord.Message, persistent=False, thread_creation=False + ) -> None: if not message.content and not message.attachments: raise MissingRequiredArgument(SimpleNamespace(name="msg")) - msg = await self.send(message, self.channel, note=True, persistent_note=persistent, thread_creation=thread_creation) + msg = await self.send( + message, + self.channel, + note=True, + persistent_note=persistent, + thread_creation=thread_creation, + ) self.bot.loop.create_task( self.bot.api.append_log( From 8e4f8d6a8f95a7623f8fde1e55129eb9aec4ef3d Mon Sep 17 00:00:00 2001 From: Cyrus Yip Date: Tue, 10 Nov 2020 18:53:20 -0800 Subject: [PATCH 161/705] changelog and version bump --- CHANGELOG.md | 3 ++- bot.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9123ab168f..dff6738aa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev12 +# v3.7.0-dev13 ### Added @@ -27,6 +27,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added support for thread titles, `?title`. ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) - Added `data_collection` to specify if bot metadata should be collected by Modmail developers. - Added `?autotrigger`, `use_regex_autotrigger` config to specify keywords to trigger commands. ([GH #130](https://github.com/kyb3r/modmail/issues/130), [GH #649](https://github.com/kyb3r/modmail/issues/649)) +- Added `?note persistent` that creates notes that are persistent for a user. ### Fixed diff --git a/bot.py b/bot.py index 7a04011382..5aa4c1cb57 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev12" +__version__ = "3.7.0-dev13" import asyncio From 2ea4b368d27f59a852e48176dad3d2e407fed0b0 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 14:21:21 +0800 Subject: [PATCH 162/705] Fix bugs with autotriggers --- bot.py | 35 ++++++++++++++++------------------- cogs/utility.py | 12 +++++++----- core/config.py | 3 ++- core/utils.py | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/bot.py b/bot.py index 5aa4c1cb57..f7a59a0944 100644 --- a/bot.py +++ b/bot.py @@ -849,7 +849,6 @@ async def get_contexts(self, message, *, cls=commands.Context): discord.utils.find(view.skip_string, prefixes) ctx_.invoked_with = view.get_word().lower() ctx_.command = self.all_commands.get(ctx_.invoked_with) - print(ctx_.invoked_with, ctx_.args, ctx_.kwargs) ctxs += [ctx_] return ctxs @@ -867,30 +866,28 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) thread = await self.threads.find(channel=ctx.channel) invoked_prefix = self.prefix - invoker = view.get_word().lower() + invoker = None # Check if there is any aliases being called. if self.config.get("use_regex_autotrigger"): - alias = self.auto_triggers[ - next(filter(lambda x: re.match(x, message.content), self.auto_triggers.keys())) - ] + trigger = next( + filter(lambda x: re.match(x, message.content), self.auto_triggers.keys()) + ) + if trigger: + invoker = re.match(trigger, message.content).group(0) else: - alias = self.auto_triggers[ - next( - filter( - lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys() - ) - ) - ] + trigger = next( + filter(lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys()) + ) + if trigger: + invoker = trigger.lower() - if alias is None: - ctx.thread = thread - ctx.invoked_with = invoker - ctx.command = self.all_commands.get(invoker) - ctxs = [ctx] - else: + alias = self.auto_triggers[trigger] + + ctxs = [] + if alias is not None: ctxs = [] - aliases = normalize_alias(alias, message.content[len(f"{invoked_prefix}{invoker}") :]) + aliases = normalize_alias(alias) if not aliases: logger.warning("Alias %s is invalid as called in automove.", invoker) diff --git a/cogs/utility.py b/cogs/utility.py index 950baaaf14..ea4db89fca 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1780,16 +1780,18 @@ async def autotrigger_remove(self, ctx, keyword): @checks.has_permissions(PermissionLevel.OWNER) async def autotrigger_test(self, ctx, *, text): """Tests a string against the current autotrigger setup""" - for keyword in list(self.bot.auto_triggers): + for keyword in self.bot.auto_triggers: if self.bot.config.get("use_regex_autotrigger"): check = re.match(keyword, text) + regex = True else: - check = keyword in text + check = keyword.lower() in text.lower() + regex = False if check: alias = self.bot.auto_triggers[keyword] embed = discord.Embed( - title="Keyword Found", + title=f"{'Regex ' if regex else ''}Keyword Found", color=self.bot.main_color, description=f"autotrigger keyword `{keyword}` found. Command executed: `{alias}`", ) @@ -1798,7 +1800,7 @@ async def autotrigger_test(self, ctx, *, text): embed = discord.Embed( title="Keyword Not Found", color=self.bot.error_color, - description=f"No autotrigger keyword found. Thread will stay in {self.bot.main_category}.", + description=f"No autotrigger keyword found.", ) return await ctx.send(embed=embed) @@ -1807,7 +1809,7 @@ async def autotrigger_test(self, ctx, *, text): async def autotrigger_list(self, ctx): """Lists all autotriggers set up""" embeds = [] - for keyword in list(self.bot.auto_triggers): + for keyword in self.bot.auto_triggers: command = self.bot.auto_triggers[keyword] embed = discord.Embed(title=keyword, color=self.bot.main_color, description=command,) embeds.append(embed) diff --git a/core/config.py b/core/config.py index 85d0797488..d92889f41e 100644 --- a/core/config.py +++ b/core/config.py @@ -160,7 +160,8 @@ class ConfigManager: "close_on_leave", "alert_on_mention", "confirm_thread_creation", - "use_regex_autotrigger" "enable_plugins", + "use_regex_autotrigger", + "enable_plugins", "data_collection", "enable_eval", } diff --git a/core/utils.py b/core/utils.py index a236adbc0f..b6640eaed8 100644 --- a/core/utils.py +++ b/core/utils.py @@ -302,7 +302,7 @@ def decode_alias(m): return aliases -def normalize_alias(alias, message): +def normalize_alias(alias, message=""): aliases = parse_alias(alias) contents = parse_alias(message, split=False) From 9920b0dee7aacc60542fb961073f679c1dc14559 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 14:23:10 +0800 Subject: [PATCH 163/705] Add git links to changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dff6738aa1..04cae2085c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added support for thread titles, `?title`. ([GH #2838](https://github.com/kyb3r/modmail/issues/2838)) - Added `data_collection` to specify if bot metadata should be collected by Modmail developers. - Added `?autotrigger`, `use_regex_autotrigger` config to specify keywords to trigger commands. ([GH #130](https://github.com/kyb3r/modmail/issues/130), [GH #649](https://github.com/kyb3r/modmail/issues/649)) -- Added `?note persistent` that creates notes that are persistent for a user. +- Added `?note persistent` that creates notes that are persistent for a user. ([GH #2842](https://github.com/kyb3r/modmail/issues/2842), [PR #2878](https://github.com/kyb3r/modmail/pull/2878)) ### Fixed From da09dabe60bcbb382bd2d1822c65e6e92400b664 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 16:07:36 +0800 Subject: [PATCH 164/705] Update reaadme links --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 700b3bc10b..baf7c84c3b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - Bot instances + Bot instances @@ -54,7 +54,7 @@ This bot is free for everyone and always will be. If you like this project and w When a member sends a direct message to the bot, Modmail will create a channel or "thread" into a designated category. All further DM messages will automatically relay to that channel; any available staff can respond within the channel. -Our Logviewer will save the threads so you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.logviewer.tech/example). +Our Logviewer will save the threads so you can view previous threads through their corresponding log link. Here is an [**example**](https://logs.modmail.dev/example). ## Features @@ -67,7 +67,7 @@ Our Logviewer will save the threads so you can view previous threads through the * Minimum length for members to be in the guild before allowed to contact Modmail (`guild_age`). * **Advanced Logging Functionality:** - * When you close a thread, Modmail will generate a [log link](https://logs.logviewer.tech/example) and post it to your log channel. + * When you close a thread, Modmail will generate a [log link](https://logs.modmail.dev/example) and post it to your log channel. * Native Discord dark-mode feel. * Markdown/formatting support. * Login via Discord to protect your logs ([premium Patreon feature](https://patreon.com/kyber)). From 5a05869c15968e5c02e57635bde2585271eccaab Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:34:08 +0800 Subject: [PATCH 165/705] Add a bunch of new events, fix plugin ready --- CHANGELOG.md | 3 +++ bot.py | 21 +++++++++++++++++++++ cogs/modmail.py | 21 ++------------------- cogs/plugins.py | 4 ++++ core/thread.py | 3 +++ 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04cae2085c..c787e11655 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?contact` now sends members a DM. - `level_permissions` and `command_permissions` would sometimes be reset. ([GH #2856](https://github.com/kyb3r/modmail/issues/2856)) - Command truncated after && in alias. ([GH #2870](https://github.com/kyb3r/modmail/issues/2870)) +- `on_plugins_ready` event for plugins works now. ### Improved @@ -42,6 +43,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Internal - Use enums in config. ([GH #2821](https://github.com/kyb3r/modmail/issues/2821)) +- `on_thread_close` event for plugins. +- `on_thread_reply` event for plugins. # v3.6.2 diff --git a/bot.py b/bot.py index f7a59a0944..ce2c7bdd6e 100644 --- a/bot.py +++ b/bot.py @@ -811,6 +811,8 @@ async def process_dm_modmail(self, message: discord.Message) -> None: await self.add_reaction(message, blocked_emoji) else: await self.add_reaction(message, sent_emoji) + self.bot.dispatch("thread_reply", thread, False, message, False, False) + async def get_contexts(self, message, *, cls=commands.Context): """ @@ -1131,6 +1133,25 @@ async def on_raw_reaction_add(self, payload): if self.config["transfer_reactions"]: await self.handle_reaction_events(payload) + react_message_id = tryint(self.bot.config.get("react_to_contact_message")) + react_message_emoji = self.bot.config.get("react_to_contact_emoji") + if all((react_message_id, react_message_emoji)): + if payload.message_id == react_message_id: + if payload.emoji.is_unicode_emoji(): + emoji_fmt = payload.emoji.name + else: + emoji_fmt = f"<:{payload.emoji.name}:{payload.emoji.id}>" + + if emoji_fmt == react_message_emoji: + channel = self.bot.get_channel(payload.channel_id) + member = channel.guild.get_member(payload.user_id) + message = await channel.fetch_message(payload.message_id) + await message.remove_reaction(payload.emoji, member) + + ctx = await self.bot.get_context(message) + ctx.author = member + await ctx.invoke(self.contact, user=member, manual_trigger=False) + async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: await self.handle_reaction_events(payload) diff --git a/cogs/modmail.py b/cogs/modmail.py index b977d8fdf4..ee62f58137 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1012,25 +1012,8 @@ async def contact( await ctx.message.delete() @commands.Cog.listener() - async def on_raw_reaction_add(self, payload): - react_message_id = tryint(self.bot.config.get("react_to_contact_message")) - react_message_emoji = self.bot.config.get("react_to_contact_emoji") - if all((react_message_id, react_message_emoji)): - if payload.message_id == react_message_id: - if payload.emoji.is_unicode_emoji(): - emoji_fmt = payload.emoji.name - else: - emoji_fmt = f"<:{payload.emoji.name}:{payload.emoji.id}>" - - if emoji_fmt == react_message_emoji: - channel = self.bot.get_channel(payload.channel_id) - member = channel.guild.get_member(payload.user_id) - message = await channel.fetch_message(payload.message_id) - await message.remove_reaction(payload.emoji, member) - - ctx = await self.bot.get_context(message) - ctx.author = member - await ctx.invoke(self.contact, user=member, manual_trigger=False) + async def on_plugin_ready(self): + print('hi') @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.MODERATOR) diff --git a/cogs/plugins.py b/cogs/plugins.py index e85907838f..1cce8449c7 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -15,6 +15,7 @@ import discord from discord.ext import commands +from discord.utils import async_all from pkg_resources import parse_version @@ -145,6 +146,9 @@ async def initial_load_plugins(self): continue logger.debug("Finished loading all plugins.") + + self.bot.dispatch('plugins_ready') + self._ready_event.set() await self.bot.config.update() diff --git a/core/thread.py b/core/thread.py index b9bf261b12..d5517fb375 100644 --- a/core/thread.py +++ b/core/thread.py @@ -486,6 +486,8 @@ async def _close( tasks.append(self.channel.delete()) await asyncio.gather(*tasks) + self.bot.dispatch("thread_close", self, closer, silent, delete_channel, message, scheduled) + async def cancel_closure(self, auto_close: bool = False, all: bool = False) -> None: if self.close_task is not None and (not auto_close or all): @@ -779,6 +781,7 @@ async def reply( ) await asyncio.gather(*tasks) + self.bot.dispatch("thread_reply", self, True, message, anonymous, plain) async def send( self, From 5d62d270dd753d72386c700c3917b742a52b75f1 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:34:38 +0800 Subject: [PATCH 166/705] Push version --- CHANGELOG.md | 2 +- bot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c787e11655..c22fe36bdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev13 +# v3.7.0-dev14 ### Added diff --git a/bot.py b/bot.py index ce2c7bdd6e..05b67ff3fe 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev13" +__version__ = "3.7.0-dev14" import asyncio From 2d56745e678a3468970e21fcea38721060589773 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:46:30 +0800 Subject: [PATCH 167/705] Fix CI --- .github/workflows/lints.yml | 2 +- bot.py | 1 - cogs/modmail.py | 4 ---- cogs/plugins.py | 2 +- core/thread.py | 1 - 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 52a538bef7..68b0de7c8a 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -31,4 +31,4 @@ jobs: continue-on-error: true - name: Black and flake8 run: | - black . --diff + black . --diff --check diff --git a/bot.py b/bot.py index 05b67ff3fe..28b19514ba 100644 --- a/bot.py +++ b/bot.py @@ -813,7 +813,6 @@ async def process_dm_modmail(self, message: discord.Message) -> None: await self.add_reaction(message, sent_emoji) self.bot.dispatch("thread_reply", thread, False, message, False, False) - async def get_contexts(self, message, *, cls=commands.Context): """ Returns all invocation contexts from the message. diff --git a/cogs/modmail.py b/cogs/modmail.py index ee62f58137..268d00d547 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1011,10 +1011,6 @@ async def contact( await asyncio.sleep(5) await ctx.message.delete() - @commands.Cog.listener() - async def on_plugin_ready(self): - print('hi') - @commands.group(invoke_without_command=True) @checks.has_permissions(PermissionLevel.MODERATOR) @trigger_typing diff --git a/cogs/plugins.py b/cogs/plugins.py index 1cce8449c7..fe70b5225b 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -147,7 +147,7 @@ async def initial_load_plugins(self): logger.debug("Finished loading all plugins.") - self.bot.dispatch('plugins_ready') + self.bot.dispatch("plugins_ready") self._ready_event.set() await self.bot.config.update() diff --git a/core/thread.py b/core/thread.py index d5517fb375..2713afd273 100644 --- a/core/thread.py +++ b/core/thread.py @@ -488,7 +488,6 @@ async def _close( await asyncio.gather(*tasks) self.bot.dispatch("thread_close", self, closer, silent, delete_channel, message, scheduled) - async def cancel_closure(self, auto_close: bool = False, all: bool = False) -> None: if self.close_task is not None and (not auto_close or all): self.close_task.cancel() From 97155865d6be1830e554a57e298445afd51efb9d Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:50:12 +0800 Subject: [PATCH 168/705] Fix CI --- cogs/utility.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index ea4db89fca..75d141496d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1811,7 +1811,11 @@ async def autotrigger_list(self, ctx): embeds = [] for keyword in self.bot.auto_triggers: command = self.bot.auto_triggers[keyword] - embed = discord.Embed(title=keyword, color=self.bot.main_color, description=command,) + embed = discord.Embed( + title=keyword, + color=self.bot.main_color, + description=command, + ) embeds.append(embed) if not embeds: From 615bad0984f3a9e48fe4a2ef211d1377ec979fb5 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:39:56 +0800 Subject: [PATCH 169/705] bugfix --- CHANGELOG.md | 2 +- bot.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c22fe36bdc..effb9f6269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev14 +# v3.7.0-dev15 ### Added diff --git a/bot.py b/bot.py index 28b19514ba..9d9bfaa24d 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev14" +__version__ = "3.7.0-dev15" import asyncio @@ -12,16 +12,16 @@ from types import SimpleNamespace import discord -from discord.ext import commands, tasks -from discord.ext.commands.view import StringView - import isodate - from aiohttp import ClientSession +from discord.ext import commands, tasks +from discord.ext.commands.view import StringView from emoji import UNICODE_EMOJI - from pkg_resources import parse_version +from core.utils import tryint + + try: # noinspection PyUnresolvedReferences from colorama import init @@ -31,13 +31,13 @@ pass from core import checks -from core.clients import ApiClient, PluginDatabaseClient, MongoDBClient +from core.clients import ApiClient, MongoDBClient, PluginDatabaseClient from core.config import ConfigManager -from core.utils import human_join, match_title, normalize_alias -from core.models import DMDisabled, PermissionLevel, SafeFormatter, getLogger, configure_logging +from core.models import (DMDisabled, PermissionLevel, SafeFormatter, + configure_logging, getLogger) from core.thread import ThreadManager from core.time import human_timedelta - +from core.utils import human_join, match_title, normalize_alias logger = getLogger(__name__) From fedbca8d8fc1b6e10f9d3f6b2370b2a61b671996 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:46:24 +0800 Subject: [PATCH 170/705] Lint --- .github/workflows/lints.yml | 2 +- bot.py | 3 +-- cogs/utility.py | 6 +----- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 68b0de7c8a..07339a6198 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -29,6 +29,6 @@ jobs: - name: Pylint run: pylint ./bot.py cogs/*.py core/*.py --disable=import-error --exit-zero -r y continue-on-error: true - - name: Black and flake8 + - name: Black run: | black . --diff --check diff --git a/bot.py b/bot.py index 9d9bfaa24d..e4a4a57a5b 100644 --- a/bot.py +++ b/bot.py @@ -33,8 +33,7 @@ from core import checks from core.clients import ApiClient, MongoDBClient, PluginDatabaseClient from core.config import ConfigManager -from core.models import (DMDisabled, PermissionLevel, SafeFormatter, - configure_logging, getLogger) +from core.models import DMDisabled, PermissionLevel, SafeFormatter, configure_logging, getLogger from core.thread import ThreadManager from core.time import human_timedelta from core.utils import human_join, match_title, normalize_alias diff --git a/cogs/utility.py b/cogs/utility.py index 75d141496d..ea4db89fca 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1811,11 +1811,7 @@ async def autotrigger_list(self, ctx): embeds = [] for keyword in self.bot.auto_triggers: command = self.bot.auto_triggers[keyword] - embed = discord.Embed( - title=keyword, - color=self.bot.main_color, - description=command, - ) + embed = discord.Embed(title=keyword, color=self.bot.main_color, description=command,) embeds.append(embed) if not embeds: From b80c00800812454a8ab3891dc0717bf1961f0f44 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:50:11 +0800 Subject: [PATCH 171/705] lint --- .github/workflows/lints.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 07339a6198..efda5bdcfa 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install bandit pylint black + python -m pip install bandit==1.6.2 pylint black====19.10b0 continue-on-error: true - name: Bandit syntax check run: bandit ./bot.py cogs/*.py core/*.py -b .bandit_baseline.json From 09e5929e6389b2f27296a43f85c9dc2e17b9fa98 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:52:52 +0800 Subject: [PATCH 172/705] lint --- .github/workflows/lints.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index efda5bdcfa..689e611157 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install bandit==1.6.2 pylint black====19.10b0 + python -m pip install bandit==1.6.2 pylint black==19.10b0 continue-on-error: true - name: Bandit syntax check run: bandit ./bot.py cogs/*.py core/*.py -b .bandit_baseline.json From bfb1a17786f477a8c101580600c47668e2b9fad4 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:59:49 +0800 Subject: [PATCH 173/705] bugfixing --- bot.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index e4a4a57a5b..6d9f2d45ed 100644 --- a/bot.py +++ b/bot.py @@ -810,7 +810,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: await self.add_reaction(message, blocked_emoji) else: await self.add_reaction(message, sent_emoji) - self.bot.dispatch("thread_reply", thread, False, message, False, False) + self.dispatch("thread_reply", thread, False, message, False, False) async def get_contexts(self, message, *, cls=commands.Context): """ @@ -1131,8 +1131,8 @@ async def on_raw_reaction_add(self, payload): if self.config["transfer_reactions"]: await self.handle_reaction_events(payload) - react_message_id = tryint(self.bot.config.get("react_to_contact_message")) - react_message_emoji = self.bot.config.get("react_to_contact_emoji") + react_message_id = tryint(self.config.get("react_to_contact_message")) + react_message_emoji = self.config.get("react_to_contact_emoji") if all((react_message_id, react_message_emoji)): if payload.message_id == react_message_id: if payload.emoji.is_unicode_emoji(): @@ -1141,12 +1141,12 @@ async def on_raw_reaction_add(self, payload): emoji_fmt = f"<:{payload.emoji.name}:{payload.emoji.id}>" if emoji_fmt == react_message_emoji: - channel = self.bot.get_channel(payload.channel_id) + channel = self.get_channel(payload.channel_id) member = channel.guild.get_member(payload.user_id) message = await channel.fetch_message(payload.message_id) await message.remove_reaction(payload.emoji, member) - ctx = await self.bot.get_context(message) + ctx = await self.get_context(message) ctx.author = member await ctx.invoke(self.contact, user=member, manual_trigger=False) From c04f0e011d28198afffa8b712d3d979ea42c1d97 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 15:18:27 +0800 Subject: [PATCH 174/705] Add 10min cooldown to title --- CHANGELOG.md | 2 +- bot.py | 12 ++++++++++-- cogs/modmail.py | 8 +++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index effb9f6269..9917d564ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev15 +# v3.7.0-dev16 ### Added diff --git a/bot.py b/bot.py index 6d9f2d45ed..7ff45bfbfe 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev15" +__version__ = "3.7.0-dev16" import asyncio @@ -462,7 +462,7 @@ async def on_ready(self): log["channel_id"], { "open": False, - "title": match_title(thread.channel.topic), + "title": None, "closed_at": str(datetime.utcnow()), "close_message": "Channel has been deleted, no closer found.", "closer": { @@ -1323,6 +1323,14 @@ async def on_command_error(self, context, exception): logger.warning("CommandNotFound: %s", exception) elif isinstance(exception, commands.MissingRequiredArgument): await context.send_help(context.command) + elif isinstance(exception, commands.CommandOnCooldown): + await context.send( + embed=discord.Embed( + title="Command on cooldown", + description=f"Try again in {exception.retry_after:.2f} seconds", + color=self.error_color, + ) + ) elif isinstance(exception, commands.CheckFailure): for check in context.command.checks: if not await check(context): diff --git a/cogs/modmail.py b/cogs/modmail.py index 268d00d547..ed9a3dfec7 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -7,6 +7,7 @@ import discord from discord.ext import commands +from discord.ext.commands.cooldowns import BucketType from discord.role import Role from discord.utils import escape_markdown @@ -296,6 +297,7 @@ async def move(self, ctx, *, arguments): `options` is a string which takes in arguments on how to perform the move. Ex: "silently" """ split_args = arguments.strip('"').split(" ") + category = None # manually parse arguments, consumes as much of args as possible for category for i in range(len(split_args)): @@ -314,6 +316,9 @@ async def move(self, ctx, *, arguments): else: break + if not category: + raise commands.ChannelNotFound(arguments) + options = " ".join(arguments.split(" ")[-i:]) thread = ctx.thread @@ -646,9 +651,10 @@ def format_log_embeds(self, logs, avatar_url): embeds.append(embed) return embeds - @commands.command() + @commands.command(cooldown_after_parsing=True) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() + @commands.cooldown(1, 600, BucketType.channel) async def title(self, ctx, *, name: str): """Sets title for a thread""" await ctx.thread.set_title(name) From cdad32046de4d325db3dd72e76ccbff5a8d5a68d Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 15:26:59 +0800 Subject: [PATCH 175/705] bugfix --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 7ff45bfbfe..11c45dd050 100644 --- a/bot.py +++ b/bot.py @@ -1148,7 +1148,7 @@ async def on_raw_reaction_add(self, payload): ctx = await self.get_context(message) ctx.author = member - await ctx.invoke(self.contact, user=member, manual_trigger=False) + await ctx.invoke(self.get_cog("Modmail").contact, user=member, manual_trigger=False) async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: From 60ac027152d33aed55f2aafcf48f2ed6d6df933f Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 15:27:18 +0800 Subject: [PATCH 176/705] bugfix --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 11c45dd050..1a54f2ce37 100644 --- a/bot.py +++ b/bot.py @@ -1148,7 +1148,7 @@ async def on_raw_reaction_add(self, payload): ctx = await self.get_context(message) ctx.author = member - await ctx.invoke(self.get_cog("Modmail").contact, user=member, manual_trigger=False) + await ctx.invoke(self.get_command("contact"), user=member, manual_trigger=False) async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: From 29747b714ef034dc9bb69847dbc684e7a8f721a5 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 15:28:49 +0800 Subject: [PATCH 177/705] lint --- bot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 1a54f2ce37..799a230a84 100644 --- a/bot.py +++ b/bot.py @@ -1148,7 +1148,9 @@ async def on_raw_reaction_add(self, payload): ctx = await self.get_context(message) ctx.author = member - await ctx.invoke(self.get_command("contact"), user=member, manual_trigger=False) + await ctx.invoke( + self.get_command("contact"), user=member, manual_trigger=False + ) async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: From a84cb9c7b80679134f450a5fe359e76d01ee47d9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 22:54:08 +0800 Subject: [PATCH 178/705] Autoupdate functions --- CHANGELOG.md | 3 +- bot.py | 110 +++++++++++++++++++++- cogs/modmail.py | 9 ++ cogs/utility.py | 120 +++++++++++++++++++++++- core/checks.py | 22 ++++- core/clients.py | 207 ++++++++++++++++++++++++++++++++++++++++++ core/config.py | 2 + core/config_help.json | 18 ++++ core/models.py | 6 ++ core/utils.py | 1 + 10 files changed, 493 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9917d564ca..d096c8f4e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev16 +# v3.7.0-dev17 ### Added @@ -28,6 +28,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added `data_collection` to specify if bot metadata should be collected by Modmail developers. - Added `?autotrigger`, `use_regex_autotrigger` config to specify keywords to trigger commands. ([GH #130](https://github.com/kyb3r/modmail/issues/130), [GH #649](https://github.com/kyb3r/modmail/issues/649)) - Added `?note persistent` that creates notes that are persistent for a user. ([GH #2842](https://github.com/kyb3r/modmail/issues/2842), [PR #2878](https://github.com/kyb3r/modmail/pull/2878)) +- Autoupdates and `?update` which was removed in v3.0.0 ### Fixed diff --git a/bot.py b/bot.py index 799a230a84..0dc95df4c7 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev16" +__version__ = "3.7.0-dev17" import asyncio @@ -6,6 +6,7 @@ import logging import os import re +import subprocess import sys import typing from datetime import datetime @@ -31,9 +32,17 @@ pass from core import checks +from core.changelog import Changelog from core.clients import ApiClient, MongoDBClient, PluginDatabaseClient from core.config import ConfigManager -from core.models import DMDisabled, PermissionLevel, SafeFormatter, configure_logging, getLogger +from core.models import ( + DMDisabled, + HostingMethod, + PermissionLevel, + SafeFormatter, + configure_logging, + getLogger, +) from core.thread import ThreadManager from core.time import human_timedelta from core.utils import human_join, match_title, normalize_alias @@ -58,6 +67,7 @@ def __init__(self): self._session = None self._api = None self.metadata_loop = None + self.autoupdate_loop = None self.formatter = SafeFormatter() self.loaded_cogs = ["cogs.modmail", "cogs.plugins", "cogs.utility"] self._connected = asyncio.Event() @@ -88,6 +98,21 @@ def uptime(self) -> str: return self.formatter.format(fmt, d=days, h=hours, m=minutes, s=seconds) + @property + def hosting_method(self) -> HostingMethod: + # use enums + if ".heroku" in os.environ.get("PYTHONHOME", ""): + return HostingMethod.HEROKU + + if os.environ.get("pm_id"): + return HostingMethod.PM2 + + return HostingMethod.OTHER + + @property + def is_pm2(self) -> bool: + return ".heroku" in os.environ.get("PYTHONHOME", "") + def startup(self): logger.line() if os.name != "nt": @@ -494,6 +519,12 @@ async def on_ready(self): self.metadata_loop.before_loop(self.before_post_metadata) self.metadata_loop.start() + self.autoupdate_loop = tasks.Loop( + self.autoupdate, seconds=0, minutes=0, hours=1, count=None, reconnect=True, loop=None + ) + self.autoupdate_loop.before_loop(self.before_autoupdate) + self.autoupdate_loop.start() + other_guilds = [ guild for guild in self.guilds if guild not in {self.guild, self.modmail_guild} ] @@ -1398,6 +1429,81 @@ async def before_post_metadata(self): if not self.guild: self.metadata_loop.cancel() + async def autoupdate(self): + changelog = await Changelog.from_url(self) + latest = changelog.latest_version + + if self.version < parse_version(latest.version): + if self.hosting_method == HostingMethod.HEROKU: + data = await self.api.update_repository() + + embed = discord.Embed(color=self.main_color) + + commit_data = data["data"] + user = data["user"] + embed.set_author( + name=user["username"] + " - Updating Bot", + icon_url=user["avatar_url"], + url=user["url"], + ) + + embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + + embed.description = latest.description + for name, value in latest.fields.items(): + embed.add_field(name=name, value=value) + + if commit_data: + message = commit_data["commit"]["message"] + html_url = commit_data["html_url"] + short_sha = commit_data["sha"][:6] + embed.add_field( + name="Merge Commit", + value=f"[`{short_sha}`]({html_url}) " f"{message} - {user['username']}", + ) + logger.info("Bot has been updated.") + channel = self.log_channel + await channel.send(embed=embed) + else: + command = "git pull" + + cmd = subprocess.run( + command, + cwd=os.getcwd(), + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + ) + res = cmd.stdout.decode("utf-8").strip() + + if res != "Already up to date.": + logger.info("Bot has been updated.") + channel = self.log_channel + if self.hosting_method == HostingMethod.PM2: + embed = discord.Embed(title="Bot has been updated", color=self.main_color) + await channel.send(embed=embed) + else: + embed = discord.Embed( + title="Bot has been updated and is logging out.", + description="If you do not have an auto-restart setup, please manually start the bot.", + color=self.main_color, + ) + await channel.send(embed=embed) + await self.logout() + + async def before_autoupdate(self): + await self.wait_for_connected() + logger.debug("Starting autoupdate loop") + + if self.config.get("disable_autoupdates"): + logger.warning("Autoupdates disabled.") + self.autoupdate_loop.cancel() + + if not self.config.get("github_token"): + logger.warning("GitHub access token not found.") + logger.warning("Autoupdates disabled.") + self.autoupdate_loop.cancel() + def main(): try: diff --git a/cogs/modmail.py b/cogs/modmail.py index ed9a3dfec7..d036a6ee01 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1535,6 +1535,15 @@ async def isenable(self, ctx): return await ctx.send(embed=embed) + @commands.command(usage="[after] [close message]") + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def adduser(self, ctx, *, member: discord.Member = None): + await ctx.thread.add_user(member) + + sent_emoji, _ = await self.bot.retrieve_emoji() + await self.bot.add_reaction(ctx.message, sent_emoji) + def setup(bot): bot.add_cog(Modmail(bot)) diff --git a/cogs/utility.py b/cogs/utility.py index ea4db89fca..63bd70aac8 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -10,6 +10,7 @@ from io import BytesIO, StringIO from itertools import takewhile, zip_longest from json import JSONDecodeError, loads +import subprocess from textwrap import indent from types import SimpleNamespace from typing import Union @@ -24,12 +25,13 @@ from core import checks, utils from core.changelog import Changelog from core.models import ( + HostingMethod, InvalidConfigError, PermissionLevel, - SimilarCategoryConverter, UnseenFormatter, getLogger, ) +from core.utils import trigger_typing from core.paginator import EmbedPaginatorSession, MessagePaginatorSession @@ -1825,6 +1827,122 @@ async def autotrigger_list(self, ctx): await EmbedPaginatorSession(ctx, *embeds).run() + @commands.command() + @checks.has_permissions(PermissionLevel.OWNER) + @checks.github_token_required() + @trigger_typing + async def github(self, ctx): + """Shows the GitHub user your Github_Token is linked to.""" + data = await self.bot.api.get_user_info() + + embed = discord.Embed( + title="GitHub", description="Current User", color=self.bot.main_color + ) + user = data["user"] + embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) + embed.set_thumbnail(url=user["avatar_url"]) + await ctx.send(embed=embed) + + @commands.command() + @checks.has_permissions(PermissionLevel.OWNER) + @checks.github_token_required(ignore_if_not_heroku=True) + @trigger_typing + async def update(self, ctx, *, flag: str = ""): + """ + Update Modmail. + This only works for PM2 or Heroku users who have configured their bot for updates. + To stay up-to-date with the latest commit + from GitHub, specify "force" as the flag. + """ + + changelog = await Changelog.from_url(self.bot) + latest = changelog.latest_version + + desc = ( + f"The latest version is [`{self.bot.version}`]" + "(https://github.com/kyb3r/modmail/blob/master/bot.py#L25)" + ) + + if self.bot.version >= parse_version(latest.version) and flag.lower() != "force": + embed = discord.Embed( + title="Already up to date", description=desc, color=self.bot.main_color + ) + + data = await self.bot.api.get_user_info() + if not data.get("error"): + user = data["user"] + embed.set_author( + name=user["username"], icon_url=user["avatar_url"], url=user["url"] + ) + await ctx.send(embed=embed) + else: + if self.bot.hosting_method == HostingMethod.HEROKU: + data = await self.bot.api.update_repository() + + commit_data = data["data"] + user = data["user"] + + if commit_data: + embed = discord.Embed(color=self.bot.main_color) + + embed.set_footer( + text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" + ) + + embed.set_author( + name=user["username"] + " - Updating bot", + icon_url=user["avatar_url"], + url=user["url"], + ) + + embed.description = latest.description + for name, value in latest.fields.items(): + embed.add_field(name=name, value=value) + # message = commit_data['commit']['message'] + html_url = commit_data["html_url"] + short_sha = commit_data["sha"][:6] + embed.add_field(name="Merge Commit", value=f"[`{short_sha}`]({html_url})") + else: + embed = discord.Embed( + title="Already up to date with master repository.", + description="No further updates required", + color=self.bot.main_color, + ) + embed.set_author( + name=user["username"], icon_url=user["avatar_url"], url=user["url"] + ) + await ctx.send(embed=embed) + else: + command = "git pull" + + cmd = subprocess.run( + command, + cwd=os.getcwd(), + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + ) + res = cmd.stdout.decode("utf-8").strip() + + if res != "Already up to date.": + logger.info("Bot has been updated.") + if self.bot.hosting_method == HostingMethod.PM2: + embed = discord.Embed( + title="Bot has been updated", color=self.bot.main_color + ) + await ctx.send(embed=embed) + else: + embed = discord.Embed( + title="Bot has been updated and is logging out.", + description="If you do not have an auto-restart setup, please manually start the bot.", + color=self.bot.main_color, + ) + await ctx.send(embed=embed) + await self.bot.logout() + else: + embed = discord.Embed(title="Already up to date.", color=self.bot.main_color,) + await ctx.send(embed=embed) + @commands.command(hidden=True, name="eval") @checks.has_permissions(PermissionLevel.OWNER) async def eval_(self, ctx, *, body: str): diff --git a/core/checks.py b/core/checks.py index 46f8424b96..0b7b2acfa3 100644 --- a/core/checks.py +++ b/core/checks.py @@ -1,6 +1,6 @@ from discord.ext import commands -from core.models import PermissionLevel, getLogger +from core.models import HostingMethod, PermissionLevel, getLogger logger = getLogger(__name__) @@ -100,3 +100,23 @@ async def predicate(ctx): predicate.fail_msg = "This is not a Modmail thread." return commands.check(predicate) + + +def github_token_required(ignore_if_not_heroku=False): + """ + A decorator that ensures github token + is set + """ + + async def predicate(ctx): + if ignore_if_not_heroku and ctx.bot.hosting_method != HostingMethod.HEROKU: + return True + else: + return ctx.bot.config.get("github_token") + + predicate.fail_msg = ( + "You can only use this command if you have a " + "configured `GITHUB_TOKEN`. Get a " + "personal access token from developer settings." + ) + return commands.check(predicate) diff --git a/core/clients.py b/core/clients.py index 62f565f91c..4f751ca723 100644 --- a/core/clients.py +++ b/core/clients.py @@ -5,6 +5,7 @@ from typing import Union, Optional from discord import Member, DMChannel, TextChannel, Message +from discord.ext import commands from aiohttp import ClientResponseError, ClientResponse from motor.motor_asyncio import AsyncIOMotorClient @@ -15,6 +16,198 @@ logger = getLogger(__name__) +class GitHub: + """ + The client for interacting with GitHub API. + Parameters + ---------- + bot : Bot + The Modmail bot. + access_token : str, optional + GitHub's access token. + username : str, optional + GitHub username. + avatar_url : str, optional + URL to the avatar in GitHub. + url : str, optional + URL to the GitHub profile. + Attributes + ---------- + bot : Bot + The Modmail bot. + access_token : str + GitHub's access token. + username : str + GitHub username. + avatar_url : str + URL to the avatar in GitHub. + url : str + URL to the GitHub profile. + Class Attributes + ---------------- + BASE : str + GitHub API base URL. + REPO : str + Modmail repo URL for GitHub API. + HEAD : str + Modmail HEAD URL for GitHub API. + MERGE_URL : str + URL for merging upstream to master. + FORK_URL : str + URL to fork Modmail. + STAR_URL : str + URL to star Modmail. + """ + + BASE = "https://api.github.com" + REPO = BASE + "/repos/kyb3r/modmail" + HEAD = REPO + "/git/refs/heads/master" + MERGE_URL = BASE + "/repos/{username}/modmail/merges" + FORK_URL = REPO + "/forks" + STAR_URL = BASE + "/user/starred/kyb3r/modmail" + + def __init__(self, bot, access_token: str = "", username: str = "", **kwargs): + self.bot = bot + self.session = bot.session + self.headers: dict = None + self.access_token = access_token + self.username = username + self.avatar_url: str = kwargs.pop("avatar_url", "") + self.url: str = kwargs.pop("url", "") + if self.access_token: + self.headers = {"Authorization": "token " + str(access_token)} + + async def request( + self, + url: str, + method: str = "GET", + payload: dict = None, + return_response: bool = False, + headers: dict = None, + ) -> Union[ClientResponse, dict, str]: + """ + Makes a HTTP request. + Parameters + ---------- + url : str + The destination URL of the request. + method : str + The HTTP method (POST, GET, PUT, DELETE, FETCH, etc.). + payload : Dict[str, Any] + The json payload to be sent along the request. + return_response : bool + Whether the `ClientResponse` object should be returned. + headers : Dict[str, str] + Additional headers to `headers`. + Returns + ------- + ClientResponse or Dict[str, Any] or List[Any] or str + `ClientResponse` if `return_response` is `True`. + `dict` if the returned data is a json object. + `list` if the returned data is a json list. + `str` if the returned data is not a valid json data, + the raw response. + """ + if headers is not None: + headers.update(self.headers) + else: + headers = self.headers + async with self.session.request(method, url, headers=headers, json=payload) as resp: + if return_response: + return resp + try: + return await resp.json() + except (JSONDecodeError, ClientResponseError): + return await resp.text() + + def filter_valid(self, data): + """ + Filters configuration keys that are accepted. + Parameters + ---------- + data : Dict[str, Any] + The data that needs to be cleaned. + Returns + ------- + Dict[str, Any] + Filtered `data` to keep only the accepted pairs. + """ + valid_keys = self.bot.config.valid_keys.difference(self.bot.config.protected_keys) + return {k: v for k, v in data.items() if k in valid_keys} + + async def update_repository(self, sha: str = None) -> Optional[dict]: + """ + Update the repository from Modmail main repo. + Parameters + ---------- + sha : Optional[str], optional + The commit SHA to update the repository. + Returns + ------- + Optional[dict] + If the response is a dict. + """ + if not self.username: + raise commands.CommandInvokeError("Username not found.") + + if sha is None: + resp: dict = await self.request(self.HEAD) + sha = resp["object"]["sha"] + + payload = {"base": "master", "head": sha, "commit_message": "Updating bot"} + + merge_url = self.MERGE_URL.format(username=self.username) + + resp = await self.request(merge_url, method="POST", payload=payload) + if isinstance(resp, dict): + return resp + + async def fork_repository(self) -> None: + """ + Forks Modmail's repository. + """ + await self.request(self.FORK_URL, method="POST") + + async def has_starred(self) -> bool: + """ + Checks if shared Modmail. + Returns + ------- + bool + `True`, if Modmail was starred. + Otherwise `False`. + """ + resp = await self.request(self.STAR_URL, return_response=True) + return resp.status == 204 + + async def star_repository(self) -> None: + """ + Stars Modmail's repository. + """ + await self.request(self.STAR_URL, method="PUT", headers={"Content-Length": "0"}) + + @classmethod + async def login(cls, bot) -> "GitHub": + """ + Logs in to GitHub with configuration variable information. + Parameters + ---------- + bot : Bot + The Modmail bot. + Returns + ------- + GitHub + The newly created `GitHub` object. + """ + self = cls(bot, bot.config.get("github_token")) + resp: dict = await self.request("https://api.github.com/user") + self.username = resp["login"] + self.avatar_url = resp["avatar_url"] + self.url = resp["html_url"] + logger.info(f"GitHub logged in to: {self.username}") + return self + + class ApiClient: """ This class represents the general request class for all type of clients. @@ -452,6 +645,20 @@ def get_plugin_partition(self, cog): cls_name = cog.__class__.__name__ return self.db.plugins[cls_name] + async def update_repository(self) -> dict: + user = await GitHub.login(self.bot) + data = await user.update_repository() + return { + "data": data, + "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,}, + } + + async def get_user_info(self) -> dict: + user = await GitHub.login(self.bot) + return { + "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,} + } + class PluginDatabaseClient: def __init__(self, bot): diff --git a/core/config.py b/core/config.py index d92889f41e..9aab61acf2 100644 --- a/core/config.py +++ b/core/config.py @@ -136,6 +136,7 @@ class ConfigManager: "enable_eval": True, # github access token for private repositories "github_token": None, + "disable_autoupdates": False, # Logging "log_level": "INFO", # data collection @@ -164,6 +165,7 @@ class ConfigManager: "enable_plugins", "data_collection", "enable_eval", + "disable_autoupdates", } enums = { diff --git a/core/config_help.json b/core/config_help.json index 970ebc6229..32cc694f32 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -779,5 +779,23 @@ "notes": [ "This configuration can only to be set through `.env` file or environment (config) variables." ] + }, + "github_token": { + "default": "None, required for update functionality", + "description": "A github personal access token with the repo scope: https://github.com/settings/tokens.", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] + }, + "disable_autoupdates": { + "default": "No", + "description": "Controls if autoupdates should be disabled or not.", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] } } diff --git a/core/models.py b/core/models.py index 0ad40bad1f..6882fe6b5f 100644 --- a/core/models.py +++ b/core/models.py @@ -264,3 +264,9 @@ class DMDisabled(IntEnum): NONE = 0 NEW_THREADS = 1 ALL_THREADS = 2 + + +class HostingMethod(IntEnum): + HEROKU = 0 + PM2 = 1 + OTHER = 2 diff --git a/core/utils.py b/core/utils.py index b6640eaed8..5eb8ea1680 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,4 +1,5 @@ import base64 +from core.models import HostingMethod import functools import re import string From 90d78cffd5a7ff96f9d7ffbe97a98684d1b37210 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:03:05 +0800 Subject: [PATCH 179/705] Fix a bug in update related commands --- CHANGELOG.md | 2 +- bot.py | 2 +- cogs/utility.py | 21 +++++++++++++-------- core/clients.py | 28 ++++++++++++++++++---------- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d096c8f4e3..87faf160e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev17 +# v3.7.0-dev18 ### Added diff --git a/bot.py b/bot.py index 0dc95df4c7..39d4895d83 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev17" +__version__ = "3.7.0-dev18" import asyncio diff --git a/cogs/utility.py b/cogs/utility.py index 63bd70aac8..3bdbe58fd0 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1835,13 +1835,18 @@ async def github(self, ctx): """Shows the GitHub user your Github_Token is linked to.""" data = await self.bot.api.get_user_info() - embed = discord.Embed( - title="GitHub", description="Current User", color=self.bot.main_color - ) - user = data["user"] - embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) - embed.set_thumbnail(url=user["avatar_url"]) - await ctx.send(embed=embed) + if data: + embed = discord.Embed( + title="GitHub", description="Current User", color=self.bot.main_color + ) + user = data["user"] + embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"]) + embed.set_thumbnail(url=user["avatar_url"]) + await ctx.send(embed=embed) + else: + await ctx.send(embed=discord.Embed( + title="Invalid Github Token", color=self.bot.error_color + )) @commands.command() @checks.has_permissions(PermissionLevel.OWNER) @@ -1869,7 +1874,7 @@ async def update(self, ctx, *, flag: str = ""): ) data = await self.bot.api.get_user_info() - if not data.get("error"): + if data: user = data["user"] embed.set_author( name=user["username"], icon_url=user["avatar_url"], url=user["url"] diff --git a/core/clients.py b/core/clients.py index 4f751ca723..3ad3e5a93c 100644 --- a/core/clients.py +++ b/core/clients.py @@ -11,7 +11,7 @@ from motor.motor_asyncio import AsyncIOMotorClient from pymongo.errors import ConfigurationError -from core.models import getLogger +from core.models import InvalidConfigError, getLogger logger = getLogger(__name__) @@ -201,11 +201,15 @@ async def login(cls, bot) -> "GitHub": """ self = cls(bot, bot.config.get("github_token")) resp: dict = await self.request("https://api.github.com/user") - self.username = resp["login"] - self.avatar_url = resp["avatar_url"] - self.url = resp["html_url"] - logger.info(f"GitHub logged in to: {self.username}") - return self + if resp.get("login"): + self.username = resp["login"] + self.avatar_url = resp["avatar_url"] + self.url = resp["html_url"] + logger.info(f"GitHub logged in to: {self.username}") + return self + else: + raise InvalidConfigError("Invalid github token") + class ApiClient: @@ -654,10 +658,14 @@ async def update_repository(self) -> dict: } async def get_user_info(self) -> dict: - user = await GitHub.login(self.bot) - return { - "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,} - } + try: + user = await GitHub.login(self.bot) + except InvalidConfigError: + return None + else: + return { + "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,} + } class PluginDatabaseClient: From 07e51b4f498c9a633f0fcb5686130b97c4169e65 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:14:08 +0800 Subject: [PATCH 180/705] Use asyncio subprocess --- .github/workflows/lints.yml | 2 +- bot.py | 16 +++++----------- cogs/utility.py | 19 +++++++------------ core/clients.py | 7 +++++-- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index 689e611157..94b322d968 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -25,7 +25,7 @@ jobs: python -m pip install bandit==1.6.2 pylint black==19.10b0 continue-on-error: true - name: Bandit syntax check - run: bandit ./bot.py cogs/*.py core/*.py -b .bandit_baseline.json + run: bandit -r . -b .bandit_baseline.json - name: Pylint run: pylint ./bot.py cogs/*.py core/*.py --disable=import-error --exit-zero -r y continue-on-error: true diff --git a/bot.py b/bot.py index 39d4895d83..1827bb7e50 100644 --- a/bot.py +++ b/bot.py @@ -6,10 +6,10 @@ import logging import os import re -import subprocess import sys import typing from datetime import datetime +from subprocess import PIPE from types import SimpleNamespace import discord @@ -1466,15 +1466,9 @@ async def autoupdate(self): await channel.send(embed=embed) else: command = "git pull" - - cmd = subprocess.run( - command, - cwd=os.getcwd(), - stderr=subprocess.PIPE, - stdout=subprocess.PIPE, - shell=True, - ) - res = cmd.stdout.decode("utf-8").strip() + proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + res = await proc.stdout.read() + res = res.decode("utf-8").rstrip() if res != "Already up to date.": logger.info("Bot has been updated.") @@ -1499,7 +1493,7 @@ async def before_autoupdate(self): logger.warning("Autoupdates disabled.") self.autoupdate_loop.cancel() - if not self.config.get("github_token"): + if not self.config.get("github_token") and self.hosting_method == HostingMethod.HEROKU: logger.warning("GitHub access token not found.") logger.warning("Autoupdates disabled.") self.autoupdate_loop.cancel() diff --git a/cogs/utility.py b/cogs/utility.py index 3bdbe58fd0..0b228bbdd2 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -10,7 +10,7 @@ from io import BytesIO, StringIO from itertools import takewhile, zip_longest from json import JSONDecodeError, loads -import subprocess +from subprocess import PIPE from textwrap import indent from types import SimpleNamespace from typing import Union @@ -1844,9 +1844,9 @@ async def github(self, ctx): embed.set_thumbnail(url=user["avatar_url"]) await ctx.send(embed=embed) else: - await ctx.send(embed=discord.Embed( - title="Invalid Github Token", color=self.bot.error_color - )) + await ctx.send( + embed=discord.Embed(title="Invalid Github Token", color=self.bot.error_color) + ) @commands.command() @checks.has_permissions(PermissionLevel.OWNER) @@ -1920,14 +1920,9 @@ async def update(self, ctx, *, flag: str = ""): else: command = "git pull" - cmd = subprocess.run( - command, - cwd=os.getcwd(), - stderr=subprocess.PIPE, - stdout=subprocess.PIPE, - shell=True, - ) - res = cmd.stdout.decode("utf-8").strip() + proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + res = await proc.stdout.read() + res = res.decode("utf-8").rstrip() if res != "Already up to date.": logger.info("Bot has been updated.") diff --git a/core/clients.py b/core/clients.py index 3ad3e5a93c..90a9d23294 100644 --- a/core/clients.py +++ b/core/clients.py @@ -211,7 +211,6 @@ async def login(cls, bot) -> "GitHub": raise InvalidConfigError("Invalid github token") - class ApiClient: """ This class represents the general request class for all type of clients. @@ -664,7 +663,11 @@ async def get_user_info(self) -> dict: return None else: return { - "user": {"username": user.username, "avatar_url": user.avatar_url, "url": user.url,} + "user": { + "username": user.username, + "avatar_url": user.avatar_url, + "url": user.url, + } } From e7c479c4146eb29ab55ab5620f7b702d3249bbd4 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:18:20 +0800 Subject: [PATCH 181/705] bump version & update baseline --- .bandit_baseline.json | 172 ++++++++++++++++++++++++++---------------- CHANGELOG.md | 2 +- bot.py | 2 +- 3 files changed, 107 insertions(+), 69 deletions(-) diff --git a/.bandit_baseline.json b/.bandit_baseline.json index 539fe85a88..df81a6fecc 100644 --- a/.bandit_baseline.json +++ b/.bandit_baseline.json @@ -1,32 +1,20 @@ { "errors": [], - "generated_at": "2019-10-07T08:19:22Z", + "generated_at": "2020-11-12T15:17:38Z", "metrics": { - "./bot.py": { - "CONFIDENCE.HIGH": 0.0, + ".\\bot.py": { + "CONFIDENCE.HIGH": 1.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, "CONFIDENCE.UNDEFINED": 0.0, "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 0.0, + "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 933, - "nosec": 0 - }, - "_totals": { - "CONFIDENCE.HIGH": 2.0, - "CONFIDENCE.LOW": 0.0, - "CONFIDENCE.MEDIUM": 1.0, - "CONFIDENCE.UNDEFINED": 0.0, - "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 2.0, - "SEVERITY.MEDIUM": 1.0, - "SEVERITY.UNDEFINED": 0.0, - "loc": 7299, + "loc": 1264, "nosec": 0 }, - "cogs/modmail.py": { + ".\\cogs\\modmail.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -35,10 +23,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 973, + "loc": 1280, "nosec": 0 }, - "cogs/plugins.py": { + ".\\cogs\\plugins.py": { "CONFIDENCE.HIGH": 1.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -47,22 +35,22 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 537, + "loc": 572, "nosec": 0 }, - "cogs/utility.py": { - "CONFIDENCE.HIGH": 1.0, + ".\\cogs\\utility.py": { + "CONFIDENCE.HIGH": 2.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, "CONFIDENCE.UNDEFINED": 0.0, "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 0.0, + "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1587, + "loc": 1710, "nosec": 0 }, - "core/_color_data.py": { + ".\\core\\_color_data.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -71,10 +59,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1168, + "loc": 1166, "nosec": 0 }, - "core/changelog.py": { + ".\\core\\changelog.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -83,10 +71,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 154, + "loc": 145, "nosec": 0 }, - "core/checks.py": { + ".\\core\\checks.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -95,10 +83,22 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 75, + "loc": 89, + "nosec": 0 + }, + ".\\core\\clients.py": { + "CONFIDENCE.HIGH": 0.0, + "CONFIDENCE.LOW": 0.0, + "CONFIDENCE.MEDIUM": 1.0, + "CONFIDENCE.UNDEFINED": 0.0, + "SEVERITY.HIGH": 0.0, + "SEVERITY.LOW": 1.0, + "SEVERITY.MEDIUM": 0.0, + "SEVERITY.UNDEFINED": 0.0, + "loc": 585, "nosec": 0 }, - "core/clients.py": { + ".\\core\\config.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -107,10 +107,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 200, + "loc": 327, "nosec": 0 }, - "core/config.py": { + ".\\core\\decorators.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -119,10 +119,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 276, + "loc": 9, "nosec": 0 }, - "core/decorators.py": { + ".\\core\\models.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -131,10 +131,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 7, + "loc": 199, "nosec": 0 }, - "core/models.py": { + ".\\core\\paginator.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -143,10 +143,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 91, + "loc": 209, "nosec": 0 }, - "core/paginator.py": { + ".\\core\\thread.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -155,10 +155,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 214, + "loc": 993, "nosec": 0 }, - "core/thread.py": { + ".\\core\\time.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -167,10 +167,10 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 716, + "loc": 158, "nosec": 0 }, - "core/time.py": { + ".\\core\\utils.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -179,65 +179,103 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 169, + "loc": 283, "nosec": 0 }, - "core/utils.py": { - "CONFIDENCE.HIGH": 0.0, + "_totals": { + "CONFIDENCE.HIGH": 4.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 1.0, "CONFIDENCE.UNDEFINED": 0.0, "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 1.0, - "SEVERITY.MEDIUM": 0.0, + "SEVERITY.LOW": 4.0, + "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 199, + "loc": 8989, "nosec": 0 } }, "results": [ { - "code": "14 from site import USER_SITE\n15 from subprocess import PIPE\n16 \n17 import discord\n", - "filename": "cogs/plugins.py", + "code": "11 from datetime import datetime\n12 from subprocess import PIPE\n13 from types import SimpleNamespace\n", + "filename": ".\\bot.py", + "issue_confidence": "HIGH", + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with PIPE module.", + "line_number": 12, + "line_range": [ + 12 + ], + "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "13 from site import USER_SITE\n14 from subprocess import PIPE\n15 \n16 import discord\n", + "filename": ".\\cogs\\plugins.py", + "issue_confidence": "HIGH", + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with PIPE module.", + "line_number": 14, + "line_range": [ + 14, + 15 + ], + "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "12 from json import JSONDecodeError, loads\n13 from subprocess import PIPE\n14 from textwrap import indent\n", + "filename": ".\\cogs\\utility.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", - "line_number": 15, + "line_number": 13, "line_range": [ - 15, - 16 + 13 ], "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", "test_id": "B404", "test_name": "blacklist" }, { - "code": "1824 try:\n1825 exec(to_compile, env) # pylint: disable=exec-used\n1826 except Exception as exc:\n", - "filename": "cogs/utility.py", + "code": "1985 try:\n1986 exec(to_compile, env) # pylint: disable=exec-used\n1987 except Exception as exc:\n", + "filename": ".\\cogs\\utility.py", "issue_confidence": "HIGH", "issue_severity": "MEDIUM", "issue_text": "Use of exec detected.", - "line_number": 1825, + "line_number": 1986, "line_range": [ - 1825 + 1986 ], "more_info": "https://bandit.readthedocs.io/en/latest/plugins/b102_exec_used.html", "test_id": "B102", "test_name": "exec_used" }, { - "code": "219 for token in shlex.shlex(alias, punctuation_chars=\"&\"):\n220 if token != \"&&\":\n221 buffer += \" \" + token\n", - "filename": "core/utils.py", + "code": "68 \n69 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n70 self.bot = bot\n71 self.session = bot.session\n72 self.headers: dict = None\n73 self.access_token = access_token\n74 self.username = username\n75 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n76 self.url: str = kwargs.pop(\"url\", \"\")\n77 if self.access_token:\n78 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n79 \n80 async def request(\n", + "filename": ".\\core\\clients.py", "issue_confidence": "MEDIUM", "issue_severity": "LOW", - "issue_text": "Possible hardcoded password: '&&'", - "line_number": 220, + "issue_text": "Possible hardcoded password: ''", + "line_number": 69, "line_range": [ - 220 + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79 ], - "more_info": "https://bandit.readthedocs.io/en/latest/plugins/b105_hardcoded_password_string.html", - "test_id": "B105", - "test_name": "hardcoded_password_string" + "more_info": "https://bandit.readthedocs.io/en/latest/plugins/b107_hardcoded_password_default.html", + "test_id": "B107", + "test_name": "hardcoded_password_default" } ] } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 87faf160e0..14a5065a7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev18 +# v3.7.0-dev19 ### Added diff --git a/bot.py b/bot.py index 1827bb7e50..a9d1fe6a0b 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev18" +__version__ = "3.7.0-dev19" import asyncio From abff6857daffcb01e7385ea33cd5fa525299c980 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:23:47 +0800 Subject: [PATCH 182/705] Fix issues with update --- .bandit_baseline.json | 40 ++++++++++++++++++++-------------------- cogs/utility.py | 8 +++++--- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/.bandit_baseline.json b/.bandit_baseline.json index df81a6fecc..94fcfd0fc3 100644 --- a/.bandit_baseline.json +++ b/.bandit_baseline.json @@ -2,7 +2,7 @@ "errors": [], "generated_at": "2020-11-12T15:17:38Z", "metrics": { - ".\\bot.py": { + "./bot.py": { "CONFIDENCE.HIGH": 1.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -14,7 +14,7 @@ "loc": 1264, "nosec": 0 }, - ".\\cogs\\modmail.py": { + "./cogs/modmail.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -26,7 +26,7 @@ "loc": 1280, "nosec": 0 }, - ".\\cogs\\plugins.py": { + "./cogs/plugins.py": { "CONFIDENCE.HIGH": 1.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -38,7 +38,7 @@ "loc": 572, "nosec": 0 }, - ".\\cogs\\utility.py": { + "./cogs/utility.py": { "CONFIDENCE.HIGH": 2.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -50,7 +50,7 @@ "loc": 1710, "nosec": 0 }, - ".\\core\\_color_data.py": { + "./core/_color_data.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -62,7 +62,7 @@ "loc": 1166, "nosec": 0 }, - ".\\core\\changelog.py": { + "./core/changelog.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -74,7 +74,7 @@ "loc": 145, "nosec": 0 }, - ".\\core\\checks.py": { + "./core/checks.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -86,7 +86,7 @@ "loc": 89, "nosec": 0 }, - ".\\core\\clients.py": { + "./core/clients.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 1.0, @@ -98,7 +98,7 @@ "loc": 585, "nosec": 0 }, - ".\\core\\config.py": { + "./core/config.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -110,7 +110,7 @@ "loc": 327, "nosec": 0 }, - ".\\core\\decorators.py": { + "./core/decorators.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -122,7 +122,7 @@ "loc": 9, "nosec": 0 }, - ".\\core\\models.py": { + "./core/models.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -134,7 +134,7 @@ "loc": 199, "nosec": 0 }, - ".\\core\\paginator.py": { + "./core/paginator.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -146,7 +146,7 @@ "loc": 209, "nosec": 0 }, - ".\\core\\thread.py": { + "./core/thread.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -158,7 +158,7 @@ "loc": 993, "nosec": 0 }, - ".\\core\\time.py": { + "./core/time.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -170,7 +170,7 @@ "loc": 158, "nosec": 0 }, - ".\\core\\utils.py": { + "./core/utils.py": { "CONFIDENCE.HIGH": 0.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, @@ -198,7 +198,7 @@ "results": [ { "code": "11 from datetime import datetime\n12 from subprocess import PIPE\n13 from types import SimpleNamespace\n", - "filename": ".\\bot.py", + "filename": "./bot.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", @@ -212,7 +212,7 @@ }, { "code": "13 from site import USER_SITE\n14 from subprocess import PIPE\n15 \n16 import discord\n", - "filename": ".\\cogs\\plugins.py", + "filename": "./cogs/plugins.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", @@ -227,7 +227,7 @@ }, { "code": "12 from json import JSONDecodeError, loads\n13 from subprocess import PIPE\n14 from textwrap import indent\n", - "filename": ".\\cogs\\utility.py", + "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", @@ -241,7 +241,7 @@ }, { "code": "1985 try:\n1986 exec(to_compile, env) # pylint: disable=exec-used\n1987 except Exception as exc:\n", - "filename": ".\\cogs\\utility.py", + "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "MEDIUM", "issue_text": "Use of exec detected.", @@ -255,7 +255,7 @@ }, { "code": "68 \n69 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n70 self.bot = bot\n71 self.session = bot.session\n72 self.headers: dict = None\n73 self.access_token = access_token\n74 self.username = username\n75 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n76 self.url: str = kwargs.pop(\"url\", \"\")\n77 if self.access_token:\n78 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n79 \n80 async def request(\n", - "filename": ".\\core\\clients.py", + "filename": "./core/clients.py", "issue_confidence": "MEDIUM", "issue_severity": "LOW", "issue_text": "Possible hardcoded password: ''", diff --git a/cogs/utility.py b/cogs/utility.py index 0b228bbdd2..cf83e92f67 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1928,17 +1928,19 @@ async def update(self, ctx, *, flag: str = ""): logger.info("Bot has been updated.") if self.bot.hosting_method == HostingMethod.PM2: embed = discord.Embed( - title="Bot has been updated", color=self.bot.main_color + title="Bot has been updated", + description=f"Version: {latest.version}", + color=self.bot.main_color, ) await ctx.send(embed=embed) else: embed = discord.Embed( title="Bot has been updated and is logging out.", - description="If you do not have an auto-restart setup, please manually start the bot.", + description=f"Version: {latest.version}\nIf you do not have an auto-restart setup, please manually start the bot.", color=self.bot.main_color, ) await ctx.send(embed=embed) - await self.bot.logout() + await self.bot.logout() else: embed = discord.Embed(title="Already up to date.", color=self.bot.main_color,) await ctx.send(embed=embed) From 342dc2091e130a94ea1f1b77dc2e9c9159b931d0 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:27:06 +0800 Subject: [PATCH 183/705] Bump version --- CHANGELOG.md | 2 +- bot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14a5065a7d..09a7d5dab6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev19 +# v3.7.0-dev20 ### Added diff --git a/bot.py b/bot.py index a9d1fe6a0b..d69290d969 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev19" +__version__ = "3.7.0-dev20" import asyncio From a6eef115176cef5aeb8fdbc406f785c5368f6afc Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:31:16 +0800 Subject: [PATCH 184/705] Support heroku in prerelease update --- core/clients.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/clients.py b/core/clients.py index 90a9d23294..db4e9936b4 100644 --- a/core/clients.py +++ b/core/clients.py @@ -61,7 +61,6 @@ class GitHub: BASE = "https://api.github.com" REPO = BASE + "/repos/kyb3r/modmail" - HEAD = REPO + "/git/refs/heads/master" MERGE_URL = BASE + "/repos/{username}/modmail/merges" FORK_URL = REPO + "/forks" STAR_URL = BASE + "/user/starred/kyb3r/modmail" @@ -77,6 +76,10 @@ def __init__(self, bot, access_token: str = "", username: str = "", **kwargs): if self.access_token: self.headers = {"Authorization": "token " + str(access_token)} + @property + def BRANCH(self): + return "master" if not self.bot.version.is_prerelease else "development" + async def request( self, url: str, @@ -151,10 +154,10 @@ async def update_repository(self, sha: str = None) -> Optional[dict]: raise commands.CommandInvokeError("Username not found.") if sha is None: - resp: dict = await self.request(self.HEAD) + resp: dict = await self.request(self.REPO + "/git/refs/heads/" + self.BRANCH) sha = resp["object"]["sha"] - payload = {"base": "master", "head": sha, "commit_message": "Updating bot"} + payload = {"base": self.BRANCH, "head": sha, "commit_message": "Updating bot"} merge_url = self.MERGE_URL.format(username=self.username) From 1ae3cf6b8570da2a4492654b8606ba24df75c149 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:50:48 +0800 Subject: [PATCH 185/705] Hotfix heroku logging --- CHANGELOG.md | 2 +- bot.py | 6 +----- cogs/utility.py | 13 ++++++++++--- core/models.py | 6 ++++++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09a7d5dab6..688f8559b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev20 +# v3.7.0-dev21 ### Added diff --git a/bot.py b/bot.py index d69290d969..8c67b9ffa0 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev20" +__version__ = "3.7.0-dev21" import asyncio @@ -109,10 +109,6 @@ def hosting_method(self) -> HostingMethod: return HostingMethod.OTHER - @property - def is_pm2(self) -> bool: - return ".heroku" in os.environ.get("PYTHONHOME", "") - def startup(self): logger.line() if os.name != "nt": diff --git a/cogs/utility.py b/cogs/utility.py index cf83e92f67..064d88b250 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1929,20 +1929,25 @@ async def update(self, ctx, *, flag: str = ""): if self.bot.hosting_method == HostingMethod.PM2: embed = discord.Embed( title="Bot has been updated", - description=f"Version: {latest.version}", color=self.bot.main_color, ) + embed.set_footer( + text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" + ) await ctx.send(embed=embed) else: embed = discord.Embed( title="Bot has been updated and is logging out.", - description=f"Version: {latest.version}\nIf you do not have an auto-restart setup, please manually start the bot.", + description="If you do not have an auto-restart setup, please manually start the bot.", color=self.bot.main_color, ) + embed.set_footer( + text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" + ) await ctx.send(embed=embed) await self.bot.logout() else: - embed = discord.Embed(title="Already up to date.", color=self.bot.main_color,) + embed = discord.Embed(title="Already up to date", description=desc, color=self.bot.main_color,) await ctx.send(embed=embed) @commands.command(hidden=True, name="eval") @@ -2023,6 +2028,8 @@ def paginate(text: str): break await ctx.send(f"```py\n{page}\n```") + await self.bot.add_reaction(ctx.message, "\u2705") + def setup(bot): bot.add_cog(Utility(bot)) diff --git a/core/models.py b/core/models.py index 6882fe6b5f..66965a6d88 100644 --- a/core/models.py +++ b/core/models.py @@ -1,6 +1,7 @@ import logging import re import sys +import os from enum import IntEnum from logging.handlers import RotatingFileHandler from string import Formatter @@ -16,6 +17,11 @@ Fore = Style = type("Dummy", (object,), {"__getattr__": lambda self, item: ""})() +if ".heroku" in os.environ.get("PYTHONHOME", ""): + # heroku + Fore = Style = type("Dummy", (object,), {"__getattr__": lambda self, item: ""})() + + class PermissionLevel(IntEnum): OWNER = 5 ADMINISTRATOR = 4 From 56496591da130707d0fc061b7b185d24f2177c7c Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:55:12 +0800 Subject: [PATCH 186/705] Failsafe for long changelogs --- cogs/utility.py | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 064d88b250..e4b90f4011 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1902,8 +1902,10 @@ async def update(self, ctx, *, flag: str = ""): embed.description = latest.description for name, value in latest.fields.items(): + if value > 200: + value = value[:200] + "..." + embed.add_field(name=name, value=value) - # message = commit_data['commit']['message'] html_url = commit_data["html_url"] short_sha = commit_data["sha"][:6] embed.add_field(name="Merge Commit", value=f"[`{short_sha}`]({html_url})") @@ -1926,28 +1928,29 @@ async def update(self, ctx, *, flag: str = ""): if res != "Already up to date.": logger.info("Bot has been updated.") - if self.bot.hosting_method == HostingMethod.PM2: - embed = discord.Embed( - title="Bot has been updated", - color=self.bot.main_color, - ) - embed.set_footer( - text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" - ) - await ctx.send(embed=embed) - else: - embed = discord.Embed( - title="Bot has been updated and is logging out.", - description="If you do not have an auto-restart setup, please manually start the bot.", - color=self.bot.main_color, - ) - embed.set_footer( - text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" + + embed = discord.Embed(title="Bot has been updated", color=self.bot.main_color,) + embed.set_footer( + text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}" + ) + embed.description = latest.description + for name, value in latest.fields.items(): + if value > 200: + value = value[:200] + "..." + + embed.add_field(name=name, value=value) + + if self.bot.hosting_method == HostingMethod.OTHER: + embed.description = ( + "If you do not have an auto-restart setup, please manually start the bot.", ) - await ctx.send(embed=embed) + + await ctx.send(embed=embed) await self.bot.logout() else: - embed = discord.Embed(title="Already up to date", description=desc, color=self.bot.main_color,) + embed = discord.Embed( + title="Already up to date", description=desc, color=self.bot.main_color, + ) await ctx.send(embed=embed) @commands.command(hidden=True, name="eval") From bd187704a033e8bccc6a0d96ec8152faefc3f331 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:58:14 +0800 Subject: [PATCH 187/705] Tese --- CHANGELOG.md | 2 +- bot.py | 2 +- cogs/utility.py | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 688f8559b2..fd5f060d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev21 +# v3.7.0-dev22 ### Added diff --git a/bot.py b/bot.py index 8c67b9ffa0..370e583882 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev21" +__version__ = "3.7.0-dev22" import asyncio diff --git a/cogs/utility.py b/cogs/utility.py index e4b90f4011..5b379609d0 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1885,6 +1885,7 @@ async def update(self, ctx, *, flag: str = ""): data = await self.bot.api.update_repository() commit_data = data["data"] + print(commit_data) user = data["user"] if commit_data: @@ -1906,6 +1907,7 @@ async def update(self, ctx, *, flag: str = ""): value = value[:200] + "..." embed.add_field(name=name, value=value) + html_url = commit_data["html_url"] short_sha = commit_data["sha"][:6] embed.add_field(name="Merge Commit", value=f"[`{short_sha}`]({html_url})") From eddee03f1e885160864128e81077be1893141338 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:59:49 +0800 Subject: [PATCH 188/705] Test --- cogs/utility.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/utility.py b/cogs/utility.py index 5b379609d0..96bfb48adb 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1886,6 +1886,7 @@ async def update(self, ctx, *, flag: str = ""): commit_data = data["data"] print(commit_data) + user = data["user"] if commit_data: From 37edddc582d43dcce8f561e834baba17375de9ed Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 00:08:14 +0800 Subject: [PATCH 189/705] test again --- cogs/utility.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 96bfb48adb..5acc592fc9 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1889,7 +1889,7 @@ async def update(self, ctx, *, flag: str = ""): user = data["user"] - if commit_data: + if not commit_data or not commit_data.get("html_url"): embed = discord.Embed(color=self.bot.main_color) embed.set_footer( @@ -1904,7 +1904,7 @@ async def update(self, ctx, *, flag: str = ""): embed.description = latest.description for name, value in latest.fields.items(): - if value > 200: + if len(value) > 200: value = value[:200] + "..." embed.add_field(name=name, value=value) From 4afc8d0e32f70a67ed28bd5fb9c2a3ec338bf51f Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 00:11:46 +0800 Subject: [PATCH 190/705] Fixes --- cogs/utility.py | 4 ++-- core/clients.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 5acc592fc9..145bb34602 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1889,7 +1889,7 @@ async def update(self, ctx, *, flag: str = ""): user = data["user"] - if not commit_data or not commit_data.get("html_url"): + if commit_data and commit_data.get("html_url"): embed = discord.Embed(color=self.bot.main_color) embed.set_footer( @@ -1914,7 +1914,7 @@ async def update(self, ctx, *, flag: str = ""): embed.add_field(name="Merge Commit", value=f"[`{short_sha}`]({html_url})") else: embed = discord.Embed( - title="Already up to date with master repository.", + title="Already up to date", description="No further updates required", color=self.bot.main_color, ) diff --git a/core/clients.py b/core/clients.py index db4e9936b4..2a1517fbc4 100644 --- a/core/clients.py +++ b/core/clients.py @@ -159,6 +159,8 @@ async def update_repository(self, sha: str = None) -> Optional[dict]: payload = {"base": self.BRANCH, "head": sha, "commit_message": "Updating bot"} + print(payload) + merge_url = self.MERGE_URL.format(username=self.username) resp = await self.request(merge_url, method="POST", payload=payload) From e6ebf912f3f9a9cfd3eef22ff5b338db2b1b8b6e Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 00:15:37 +0800 Subject: [PATCH 191/705] test again --- cogs/utility.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index 145bb34602..ccffd5ccaa 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1886,7 +1886,6 @@ async def update(self, ctx, *, flag: str = ""): commit_data = data["data"] print(commit_data) - user = data["user"] if commit_data and commit_data.get("html_url"): From c5f999f3f11a0a2b30bb117e18c46db6236faa68 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 00:16:57 +0800 Subject: [PATCH 192/705] Remove debug notes --- cogs/utility.py | 1 - core/clients.py | 1 - 2 files changed, 2 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index ccffd5ccaa..bf38021314 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1885,7 +1885,6 @@ async def update(self, ctx, *, flag: str = ""): data = await self.bot.api.update_repository() commit_data = data["data"] - print(commit_data) user = data["user"] if commit_data and commit_data.get("html_url"): diff --git a/core/clients.py b/core/clients.py index 2a1517fbc4..922b48d8af 100644 --- a/core/clients.py +++ b/core/clients.py @@ -159,7 +159,6 @@ async def update_repository(self, sha: str = None) -> Optional[dict]: payload = {"base": self.BRANCH, "head": sha, "commit_message": "Updating bot"} - print(payload) merge_url = self.MERGE_URL.format(username=self.username) From 02465e7d0e30d08f72f887945021d99117853721 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 00:17:37 +0800 Subject: [PATCH 193/705] Linting --- core/clients.py | 1 - 1 file changed, 1 deletion(-) diff --git a/core/clients.py b/core/clients.py index 922b48d8af..db4e9936b4 100644 --- a/core/clients.py +++ b/core/clients.py @@ -159,7 +159,6 @@ async def update_repository(self, sha: str = None) -> Optional[dict]: payload = {"base": self.BRANCH, "head": sha, "commit_message": "Updating bot"} - merge_url = self.MERGE_URL.format(username=self.username) resp = await self.request(merge_url, method="POST", payload=payload) From 771ff966f9515e803dff4490d97fb7d31547d828 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 13:21:55 +0800 Subject: [PATCH 194/705] Cleanup and add to app.json --- app.json | 4 ++++ cogs/modmail.py | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/app.json b/app.json index 41697cf064..326c54273e 100644 --- a/app.json +++ b/app.json @@ -30,6 +30,10 @@ "LOG_URL": { "description": "The url of the log viewer app for viewing self-hosted logs.", "required": true + }, + "GITHUB_TOKEN": { + "description": "A github personal access token with the repo scope.", + "required": true } } } \ No newline at end of file diff --git a/cogs/modmail.py b/cogs/modmail.py index d036a6ee01..ed9a3dfec7 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1535,15 +1535,6 @@ async def isenable(self, ctx): return await ctx.send(embed=embed) - @commands.command(usage="[after] [close message]") - @checks.has_permissions(PermissionLevel.SUPPORTER) - @checks.thread_only() - async def adduser(self, ctx, *, member: discord.Member = None): - await ctx.thread.add_user(member) - - sent_emoji, _ = await self.bot.retrieve_emoji() - await self.bot.add_reaction(ctx.message, sent_emoji) - def setup(bot): bot.add_cog(Modmail(bot)) From 97bfaccaa5b55abfd656d1e6005c5b2521496e7a Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 13:23:11 +0800 Subject: [PATCH 195/705] fix bug --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index bf38021314..80496d4f1d 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1936,7 +1936,7 @@ async def update(self, ctx, *, flag: str = ""): ) embed.description = latest.description for name, value in latest.fields.items(): - if value > 200: + if len(value) > 200: value = value[:200] + "..." embed.add_field(name=name, value=value) From 9497f17310e936c8c549d11eb94a21c781ded53b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 13:47:11 +0800 Subject: [PATCH 196/705] Cleanup --- bot.py | 8 ++------ cogs/plugins.py | 1 - cogs/utility.py | 12 +++--------- core/changelog.py | 2 +- core/utils.py | 1 - 5 files changed, 6 insertions(+), 18 deletions(-) diff --git a/bot.py b/bot.py index 370e583882..3ae6ed03fa 100644 --- a/bot.py +++ b/bot.py @@ -45,7 +45,7 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import human_join, match_title, normalize_alias +from core.utils import human_join, normalize_alias, truncate logger = getLogger(__name__) @@ -996,13 +996,9 @@ async def on_message(self, message): and self.config["alert_on_mention"] and not message.author.bot ): - if len(message.content) > 50: - extra = "..." - else: - extra = "" em = discord.Embed( title="Bot mention", - description=f"[Jump URL]({message.jump_url})\n{message.content[:50]}{extra}", + description=f"[Jump URL]({message.jump_url})\n{truncate(message.content, 50)}", color=self.main_color, timestamp=datetime.utcnow(), ) diff --git a/cogs/plugins.py b/cogs/plugins.py index fe70b5225b..cdea3a4ce8 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -15,7 +15,6 @@ import discord from discord.ext import commands -from discord.utils import async_all from pkg_resources import parse_version diff --git a/cogs/utility.py b/cogs/utility.py index 80496d4f1d..129551af87 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -31,7 +31,7 @@ UnseenFormatter, getLogger, ) -from core.utils import trigger_typing +from core.utils import trigger_typing, truncate from core.paginator import EmbedPaginatorSession, MessagePaginatorSession @@ -1902,10 +1902,7 @@ async def update(self, ctx, *, flag: str = ""): embed.description = latest.description for name, value in latest.fields.items(): - if len(value) > 200: - value = value[:200] + "..." - - embed.add_field(name=name, value=value) + embed.add_field(name=name, value=truncate(value, 200)) html_url = commit_data["html_url"] short_sha = commit_data["sha"][:6] @@ -1936,10 +1933,7 @@ async def update(self, ctx, *, flag: str = ""): ) embed.description = latest.description for name, value in latest.fields.items(): - if len(value) > 200: - value = value[:200] + "..." - - embed.add_field(name=name, value=value) + embed.add_field(name=name, value=truncate(value, 200)) if self.bot.hosting_method == HostingMethod.OTHER: embed.description = ( diff --git a/core/changelog.py b/core/changelog.py index ace825482f..60d0179609 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -93,7 +93,7 @@ def embed(self) -> Embed: ) for name, value in self.fields.items(): - embed.add_field(name=name, value=truncate(value, 1024)) + embed.add_field(name=name, value=truncate(value, 1024), inline=False) embed.set_footer(text=f"Current version: v{self.bot.version}") embed.set_thumbnail(url=self.bot.user.avatar_url) return embed diff --git a/core/utils.py b/core/utils.py index 5eb8ea1680..b6640eaed8 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,5 +1,4 @@ import base64 -from core.models import HostingMethod import functools import re import string From a73afc34adca5b458384469bc3902778a3c6dde6 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 21:39:54 +0800 Subject: [PATCH 197/705] Update a docstirng, push v --- CHANGELOG.md | 2 +- bot.py | 2 +- cogs/utility.py | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd5f060d58..8e69d44d8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.0-dev22 +# v3.7.0 ### Added diff --git a/bot.py b/bot.py index 3ae6ed03fa..3737f35471 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0-dev22" +__version__ = "3.7.0" import asyncio diff --git a/cogs/utility.py b/cogs/utility.py index 129551af87..a525c7b131 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1855,9 +1855,7 @@ async def github(self, ctx): async def update(self, ctx, *, flag: str = ""): """ Update Modmail. - This only works for PM2 or Heroku users who have configured their bot for updates. - To stay up-to-date with the latest commit - from GitHub, specify "force" as the flag. + To stay up-to-date with the latest commit rom GitHub, specify "force" as the flag. """ changelog = await Changelog.from_url(self.bot) From c5db7b91024d4ae86d5e301cf91e3de190c39261 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 13 Nov 2020 22:55:36 +0800 Subject: [PATCH 198/705] Improve react to contact, add docstring to selfcontact --- CHANGELOG.md | 7 +++++++ bot.py | 19 +++++++++++-------- cogs/modmail.py | 1 + 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e69d44d8d..38b43c0b7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.1 + +### Fixed + +- Bot will now leave a reaction on the react to contact message. +- Added docstring to selfcontact + # v3.7.0 ### Added diff --git a/bot.py b/bot.py index 3737f35471..ffd0621ba5 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.0" +__version__ = "3.7.1" import asyncio @@ -1166,14 +1166,17 @@ async def on_raw_reaction_add(self, payload): if emoji_fmt == react_message_emoji: channel = self.get_channel(payload.channel_id) member = channel.guild.get_member(payload.user_id) - message = await channel.fetch_message(payload.message_id) - await message.remove_reaction(payload.emoji, member) + if not member.bot: + message = await channel.fetch_message(payload.message_id) + await message.remove_reaction(payload.emoji, member) + + ctx = await self.get_context(message) + ctx.author = member + await ctx.invoke( + self.get_command("contact"), user=member, manual_trigger=False + ) - ctx = await self.get_context(message) - ctx.author = member - await ctx.invoke( - self.get_command("contact"), user=member, manual_trigger=False - ) + await message.add_reaction(emoji_fmt) # bot adds as well async def on_raw_reaction_remove(self, payload): if self.config["transfer_reactions"]: diff --git a/cogs/modmail.py b/cogs/modmail.py index ed9a3dfec7..2a47124ad8 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -940,6 +940,7 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str): @commands.command() @checks.has_permissions(PermissionLevel.REGULAR) async def selfcontact(self, ctx): + """Creates a thread with yourself""" await ctx.invoke(self.contact, user=ctx.author) @commands.command(usage=" [category] [options]") From 7da3dc7d4122586341de9b72b28c41edb66f7cb0 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 13 Nov 2020 16:16:10 +0100 Subject: [PATCH 199/705] Update PRIVACY.md typo fix --- PRIVACY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVACY.md b/PRIVACY.md index 8ff361b702..ebe5ce6954 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -32,7 +32,7 @@ The Modmail Team collect some metadata to keep us updated on the number of insta - Bot uptime - Bot latency - Bot version -- Whether the bot is seflhosted +- Whether the bot is selfhosted No tokens/passwords/private data is ever being collected or sent to our servers. From dd9e25e4c2177ff840377dd5e4ccc778f6193045 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 00:07:45 +0800 Subject: [PATCH 200/705] check dpy v, mention_chnanel_id, resolves #2880 --- CHANGELOG.md | 5 +++++ bot.py | 27 +++++++++++++++++++++++++-- cogs/utility.py | 1 + core/config.py | 1 + core/config_help.json | 11 +++++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38b43c0b7e..eb7f5f664a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# 3.7.2 + +### Added +- Added `mention_channel_id` to specify which channel `alert_on_mention` was being sent to ([GH #2880](https://github.com/kyb3r/modmail/issues/2880)) + # v3.7.1 ### Fixed diff --git a/bot.py b/bot.py index ffd0621ba5..363784147d 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.1" +__version__ = "3.7.2" import asyncio @@ -252,6 +252,21 @@ def log_channel(self) -> typing.Optional[discord.TextChannel]: ) return None + @property + def mention_channel(self): + channel_id = self.config["mention_channel_id"] + if channel_id is not None: + try: + channel = self.get_channel(int(channel_id)) + if channel is not None: + return channel + except ValueError: + pass + logger.debug("MENTION_CHANNEL_ID was invalid, removed.") + self.config.remove("mention_channel_id") + + return self.log_channel + async def wait_for_connected(self) -> None: await self.wait_until_ready() await self._connected.wait() @@ -1002,7 +1017,7 @@ async def on_message(self, message): color=self.main_color, timestamp=datetime.utcnow(), ) - await self.log_channel.send(content=self.config["mention"], embed=em) + await self.mention_channel.send(content=self.config["mention"], embed=em) await self.process_commands(message) @@ -1504,6 +1519,14 @@ def main(): except ImportError: pass + # check discord version + if discord.__version__ != "1.5.2": + logger.error( + "Dependencies are not updated, run pipenv install. discord.py version expected 1.5.2, recieved %s", + discord.__version__, + ) + sys.exit(0) + bot = ModmailBot() bot.run() diff --git a/cogs/utility.py b/cogs/utility.py index a525c7b131..35fa482416 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -324,6 +324,7 @@ async def about(self, ctx): embed.add_field(name="Latency", value=f"{self.bot.latency * 1000:.2f} ms") embed.add_field(name="Version", value=f"`{self.bot.version}`") embed.add_field(name="Authors", value="`kyb3r`, `Taki`, `fourjr`") + embed.add_field(name="Hosting Method", value=self.bot.hosting_method.name) changelog = await Changelog.from_url(self.bot) latest = changelog.latest_version diff --git a/core/config.py b/core/config.py index 9aab61acf2..58061b8ae2 100644 --- a/core/config.py +++ b/core/config.py @@ -42,6 +42,7 @@ class ConfigManager: "plain_reply_without_command": False, # logging "log_channel_id": None, + "mention_channel_id": None, # threads "sent_emoji": "✅", "blocked_emoji": "🚫", diff --git a/core/config_help.json b/core/config_help.json index 32cc694f32..f935e8657c 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -174,6 +174,17 @@ "If the Modmail logging channel ended up being non-existent/invalid, no logs will be sent." ] }, + "mention_channel_id": { + "default": "Log Channel (normally `#bot-logs`)", + "description": "This is the channel where bot mentions are sent to.", + "examples": [ + "`{prefix}config set mention_channel_id 9234932582312` (9234932582312 is the channel ID)" + ], + "notes": [ + "This has no effect unless `alert_on_mention` is set to yes.", + "See also: `log_channel_id`" + ] + }, "sent_emoji": { "default": "✅", "description": "This is the emoji added to the message when when a Modmail action is invoked successfully (ie. DM Modmail, edit message, etc.).", From 6b58f3521228b18e04fb0a863163f95dcfc38af9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 00:11:12 +0800 Subject: [PATCH 201/705] fix issue with config set --- CHANGELOG.md | 6 ++++++ cogs/utility.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb7f5f664a..f56d6fcbbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,14 @@ however, insignificant breaking changes do not guarantee a major version bump, s # 3.7.2 ### Added + - Added `mention_channel_id` to specify which channel `alert_on_mention` was being sent to ([GH #2880](https://github.com/kyb3r/modmail/issues/2880)) +### Fixed + +- `?config set` would not respond if an invalid key was provided. + + # v3.7.1 ### Fixed diff --git a/cogs/utility.py b/cogs/utility.py index 35fa482416..801069d125 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -772,7 +772,7 @@ async def config_set(self, ctx, key: str.lower, *, value: str): title="Error", color=self.bot.error_color, description=f"{key} is an invalid key." ) valid_keys = [f"`{k}`" for k in sorted(keys)] - embed.add_field(name="Valid keys", value=", ".join(valid_keys)) + embed.add_field(name="Valid keys", value=truncate(", ".join(valid_keys), 1024)) return await ctx.send(embed=embed) From 49bd8d036ae80ac415b0b5b11ca7ab330e4c186b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 00:12:14 +0800 Subject: [PATCH 202/705] Add dpy version --- bot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bot.py b/bot.py index 363784147d..56d518d17a 100644 --- a/bot.py +++ b/bot.py @@ -120,6 +120,8 @@ def startup(self): logger.info("v%s", __version__) logger.info("Authors: kyb3r, fourjr, Taaku18") logger.line() + logger.info("discord.py: v%s", discord.__version__) + logger.line() for cog in self.loaded_cogs: logger.debug("Loading %s.", cog) From bf8535adf372e69f9c16adea8a24782345a746a1 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 00:23:50 +0800 Subject: [PATCH 203/705] React to contact threads were treated like normal contact threads. --- CHANGELOG.md | 10 ++++++++-- core/thread.py | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f56d6fcbbd..07c670c5c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# 3.7.2 +# v3.7.3 + +### Fixed + +- React to contact threads were treated like normal contact threads. ([GH #2881](https://github.com/kyb3r/modmail/issues/2881)) + +# v3.7.2 ### Added -- Added `mention_channel_id` to specify which channel `alert_on_mention` was being sent to ([GH #2880](https://github.com/kyb3r/modmail/issues/2880)) +- Added `mention_channel_id` to specify which channel `alert_on_mention` was being sent to. ([GH #2880](https://github.com/kyb3r/modmail/issues/2880)) ### Fixed diff --git a/core/thread.py b/core/thread.py index 2713afd273..1cbf2720a4 100644 --- a/core/thread.py +++ b/core/thread.py @@ -155,7 +155,7 @@ async def setup(self, *, creator=None, category=None, initial_message=None): await channel.edit(topic=f"User ID: {recipient.id}") self.ready = True - if creator: + if creator != recipient: mention = None else: mention = self.bot.config["mention"] @@ -191,7 +191,7 @@ async def send_recipient_genesis_message(): embed.set_footer(text=footer, icon_url=self.bot.guild.icon_url) embed.title = self.bot.config["thread_creation_title"] - if creator is None: + if creator != recipient: msg = await recipient.send(embed=embed) if recipient_thread_close: From b578d7737ed85c0884d59866d217cdff7de7f211 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 00:29:54 +0800 Subject: [PATCH 204/705] Bump version --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 56d518d17a..c6f14ee924 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.2" +__version__ = "3.7.3" import asyncio From bfef29a98b6bf2cd6e35718afc209e895ff1bd36 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 01:06:32 +0800 Subject: [PATCH 205/705] fix close on emoji --- CHANGELOG.md | 6 ++++++ bot.py | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07c670c5c8..0c368cfd1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.4 + +### Fixed + +- Close on emoji was not working. + # v3.7.3 ### Fixed diff --git a/bot.py b/bot.py index c6f14ee924..4378c9c4f9 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.3" +__version__ = "3.7.4" import asyncio @@ -1157,19 +1157,19 @@ async def handle_reaction_events(self, payload): logger.warning("Failed to find linked message for reactions: %s", e) return - if payload.event_type == "REACTION_ADD": - if await self.add_reaction(linked_message, reaction): - await self.add_reaction(message, reaction) - else: - try: - await linked_message.remove_reaction(reaction, self.user) - await message.remove_reaction(reaction, self.user) - except (discord.HTTPException, discord.InvalidArgument) as e: - logger.warning("Failed to remove reaction: %s", e) + if self.config["transfer_reactions"]: + if payload.event_type == "REACTION_ADD": + if await self.add_reaction(linked_message, reaction): + await self.add_reaction(message, reaction) + else: + try: + await linked_message.remove_reaction(reaction, self.user) + await message.remove_reaction(reaction, self.user) + except (discord.HTTPException, discord.InvalidArgument) as e: + logger.warning("Failed to remove reaction: %s", e) async def on_raw_reaction_add(self, payload): - if self.config["transfer_reactions"]: - await self.handle_reaction_events(payload) + await self.handle_reaction_events(payload) react_message_id = tryint(self.config.get("react_to_contact_message")) react_message_emoji = self.config.get("react_to_contact_emoji") From a7d3345864462efc27bc1d5084e95619d923165c Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 01:21:53 +0800 Subject: [PATCH 206/705] fix close on emoji --- CHANGELOG.md | 2 +- bot.py | 2 +- core/thread.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c368cfd1f..e8fe10301e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.4 +# v3.7.5 ### Fixed diff --git a/bot.py b/bot.py index 4378c9c4f9..ad22ad0381 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.4" +__version__ = "3.7.5" import asyncio diff --git a/core/thread.py b/core/thread.py index 1cbf2720a4..b49a7b7eda 100644 --- a/core/thread.py +++ b/core/thread.py @@ -191,7 +191,7 @@ async def send_recipient_genesis_message(): embed.set_footer(text=footer, icon_url=self.bot.guild.icon_url) embed.title = self.bot.config["thread_creation_title"] - if creator != recipient: + if creator is None or creator == recipient: msg = await recipient.send(embed=embed) if recipient_thread_close: From d5ebae68e66a036d3a785766f9528b3fd45383cc Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Fri, 13 Nov 2020 19:07:52 +0100 Subject: [PATCH 207/705] Update registry.json removal of the music plugin, youtubedl source it used got striked and blocked --- plugins/registry.json | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/registry.json b/plugins/registry.json index ce2b76afc0..609345c395 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -8,15 +8,6 @@ "icon_url": "https://i.imgur.com/951szZ3.jpg", "thumbnail_url": "https://i.imgur.com/951szZ3.jpg" }, - "music": { - "repository": "lorenzo132/modmail-plugins", - "branch": "master", - "description": "Play your favourite music on your bot! Note: Only works on VPS follow this guide: https://gist.github.com/lorenzo132/5ef328e5dfcfaec19cb81dc7a63eaffa", - "bot_version": "2.20.1", - "title": "Music", - "icon_url": "https://i.imgur.com/R2olclk.png", - "thumbnail_url": "https://i.imgur.com/xuoQjPu.gif" - }, "dragory-migrate": { "repository": "kyb3r/modmail-plugins", "branch": "master", From c3052f66e62c08ce73b98720348324deda7a1bd2 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 14:22:59 +0800 Subject: [PATCH 208/705] Fix mention, spam in autoupdate --- CHANGELOG.md | 7 +++++++ bot.py | 11 +++++++++-- cogs/utility.py | 11 ++++++++++- core/thread.py | 2 +- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8fe10301e..03a6468a97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed +- Autoupdate persists despite errors +- Mention when normal thread created was not working. + +# v3.7.5 + +### Fixed + - Close on emoji was not working. # v3.7.3 diff --git a/bot.py b/bot.py index ad22ad0381..dbd013ba12 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.5" +__version__ = "3.7.6" import asyncio @@ -1479,10 +1479,17 @@ async def autoupdate(self): else: command = "git pull" proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + err = await proc.stderr.read() + err = err.decode("utf-8").rstrip() res = await proc.stdout.read() res = res.decode("utf-8").rstrip() - if res != "Already up to date.": + if err: + logger.warning(f"Autoupdate failed: {err}") + self.autoupdate_loop.cancel() + return + + elif res != "Already up to date.": logger.info("Bot has been updated.") channel = self.log_channel if self.hosting_method == HostingMethod.PM2: diff --git a/cogs/utility.py b/cogs/utility.py index 801069d125..64a1ec6fe4 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -3,6 +3,7 @@ import os import random import re +from sys import stdout import traceback from contextlib import redirect_stdout from datetime import datetime @@ -1920,10 +1921,18 @@ async def update(self, ctx, *, flag: str = ""): command = "git pull" proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) + err = await proc.stderr.read() + err = err.decode("utf-8").rstrip() res = await proc.stdout.read() res = res.decode("utf-8").rstrip() - if res != "Already up to date.": + if err: + embed = discord.Embed( + title="Update failed", description=err, color=self.bot.error_color + ) + await ctx.send(embed=embed) + + elif res != "Already up to date.": logger.info("Bot has been updated.") embed = discord.Embed(title="Bot has been updated", color=self.bot.main_color,) diff --git a/core/thread.py b/core/thread.py index b49a7b7eda..28ceef7548 100644 --- a/core/thread.py +++ b/core/thread.py @@ -155,7 +155,7 @@ async def setup(self, *, creator=None, category=None, initial_message=None): await channel.edit(topic=f"User ID: {recipient.id}") self.ready = True - if creator != recipient: + if creator is not None and creator != recipient: mention = None else: mention = self.bot.config["mention"] From dff4955a5d23350c67276bd23c8852e846f9be12 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 20:00:44 +0800 Subject: [PATCH 209/705] Fix error in requirements --- pyproject.toml | 2 +- requirements.min.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e618107561..e7c56eb749 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ keywords = ['discord', 'modmail'] [tool.poetry.dependencies] python = "^3.7" -"discord.py" = "./discord.py-1.5.1.tar.gz" +"discord.py" = "./discord.py-1.5.2.tar.gz" uvloop = {version = ">=0.12.0", markers = "sys_platform != 'win32'"} python-dotenv = ">=0.10.3" parsedatetime = "^2.6" diff --git a/requirements.min.txt b/requirements.min.txt index 6d434f974d..cf1b4bdd26 100644 --- a/requirements.min.txt +++ b/requirements.min.txt @@ -6,7 +6,7 @@ aiohttp==3.6.2 async-timeout==3.0.1 attrs==19.3.0 chardet==3.0.4 -./discord.py-1.5.1.tar.gz +./discord.py-1.5.2.tar.gz dnspython==1.16.0 emoji==0.5.4 future==0.18.2 From a956073f06bff7c975637297f112a04e3384a342 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 21:02:13 +0800 Subject: [PATCH 210/705] Fix another issue with updates --- bot.py | 2 +- cogs/utility.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index dbd013ba12..179b792be1 100644 --- a/bot.py +++ b/bot.py @@ -1484,7 +1484,7 @@ async def autoupdate(self): res = await proc.stdout.read() res = res.decode("utf-8").rstrip() - if err: + if err and not res: logger.warning(f"Autoupdate failed: {err}") self.autoupdate_loop.cancel() return diff --git a/cogs/utility.py b/cogs/utility.py index 64a1ec6fe4..573b32e9b1 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1926,7 +1926,7 @@ async def update(self, ctx, *, flag: str = ""): res = await proc.stdout.read() res = res.decode("utf-8").rstrip() - if err: + if err and not res: embed = discord.Embed( title="Update failed", description=err, color=self.bot.error_color ) From b42277b8de35bf8d48a5cb17c6169917ff52d61f Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 22:30:32 +0800 Subject: [PATCH 211/705] push v --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a6468a97..79a935feab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.5 +# v3.7.6 ### Fixed From 99f5175730523d849470850d8c1b3c982f16228a Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:13:29 +0800 Subject: [PATCH 212/705] Update fork even if not heroku, skip blocked roles --- CHANGELOG.md | 10 +++++++++ bot.py | 58 ++++++++++++++++++++++++++++--------------------- cogs/utility.py | 8 +++++++ 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79a935feab..527b044301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.7 + +### Added + +- Added updating github fork if GITHUB_TOKEN was provided + +### Fixed + +- Skip blocked roles check if user is not in main guild + # v3.7.6 ### Fixed diff --git a/bot.py b/bot.py index 179b792be1..820aa51e9d 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.6" +__version__ = "3.7.7" import asyncio @@ -38,6 +38,7 @@ from core.models import ( DMDisabled, HostingMethod, + InvalidConfigError, PermissionLevel, SafeFormatter, configure_logging, @@ -633,32 +634,33 @@ def check_guild_age(self, author: discord.Member) -> bool: return True def check_manual_blocked_roles(self, author: discord.Member) -> bool: - for r in author.roles: - if str(r.id) in self.blocked_roles: + if isinstance(author, discord.Member): + for r in author.roles: + if str(r.id) in self.blocked_roles: + + blocked_reason = self.blocked_roles.get(str(r.id)) or "" + now = datetime.utcnow() + + # etc "blah blah blah... until 2019-10-14T21:12:45.559948." + end_time = re.search(r"until ([^`]+?)\.$", blocked_reason) + if end_time is None: + # backwards compat + end_time = re.search(r"%([^%]+?)%", blocked_reason) + if end_time is not None: + logger.warning( + r"Deprecated time message for user %s, block and unblock again to update.", + author.name, + ) - blocked_reason = self.blocked_roles.get(str(r.id)) or "" - now = datetime.utcnow() - - # etc "blah blah blah... until 2019-10-14T21:12:45.559948." - end_time = re.search(r"until ([^`]+?)\.$", blocked_reason) - if end_time is None: - # backwards compat - end_time = re.search(r"%([^%]+?)%", blocked_reason) if end_time is not None: - logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", - author.name, - ) - - if end_time is not None: - after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() - if after <= 0: - # No longer blocked - self.blocked_users.pop(str(author.id)) - logger.debug("No longer blocked, user %s.", author.name) - return True - logger.debug("User blocked, user %s.", author.name) - return False + after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() + if after <= 0: + # No longer blocked + self.blocked_users.pop(str(author.id)) + logger.debug("No longer blocked, user %s.", author.name) + return True + logger.debug("User blocked, user %s.", author.name) + return False return True @@ -1477,6 +1479,12 @@ async def autoupdate(self): channel = self.log_channel await channel.send(embed=embed) else: + try: + # update fork if gh_token exists + await self.api.update_repository() + except InvalidConfigError: + pass + command = "git pull" proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) err = await proc.stderr.read() diff --git a/cogs/utility.py b/cogs/utility.py index 573b32e9b1..be8a0c4ba6 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1913,11 +1913,18 @@ async def update(self, ctx, *, flag: str = ""): description="No further updates required", color=self.bot.main_color, ) + embed.set_footer(text="Force update") embed.set_author( name=user["username"], icon_url=user["avatar_url"], url=user["url"] ) await ctx.send(embed=embed) else: + # update fork if gh_token exists + try: + await self.bot.api.update_repository() + except InvalidConfigError: + pass + command = "git pull" proc = await asyncio.create_subprocess_shell(command, stderr=PIPE, stdout=PIPE,) @@ -1954,6 +1961,7 @@ async def update(self, ctx, *, flag: str = ""): embed = discord.Embed( title="Already up to date", description=desc, color=self.bot.main_color, ) + embed.set_footer(text="Force update") await ctx.send(embed=embed) @commands.command(hidden=True, name="eval") From 0d09d179debca7210376b4ed9d0a03890b17212f Mon Sep 17 00:00:00 2001 From: Zoe Martin Date: Sun, 15 Nov 2020 16:15:44 +0100 Subject: [PATCH 213/705] Added `thread_auto_open_silently` with default 'false' to restore old functionality if desired --- CHANGELOG.md | 6 ++++++ cogs/modmail.py | 2 +- core/config.py | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 527b044301..fb0ccc854d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.8 + +### Added + +- Added `thread_auto_open_silently` to allow opening threads silently by default + # v3.7.7 ### Added diff --git a/cogs/modmail.py b/cogs/modmail.py index 2a47124ad8..beb647b87d 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -989,7 +989,7 @@ async def contact( if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): logger.info("Contacting user %s when Modmail DM is disabled.", user) - if not silent: + if not silent and not self.bot.config.get("thread_auto_open_silently"): if ctx.author.id == user.id: description = "You have opened a Modmail thread." else: diff --git a/core/config.py b/core/config.py index 58061b8ae2..198d2bec55 100644 --- a/core/config.py +++ b/core/config.py @@ -49,6 +49,7 @@ class ConfigManager: "close_emoji": "🔒", "recipient_thread_close": False, "thread_auto_close_silently": False, + "thread_auto_open_silently": False, "thread_auto_close": isodate.Duration(), "thread_auto_close_response": "This thread has been closed automatically due to inactivity after {timeout}.", "thread_creation_response": "The staff team will get back to you as soon as possible.", From 5cb9bdf63309c557fac59839efb0a8c5d72f9e20 Mon Sep 17 00:00:00 2001 From: Zoe Martin Date: Sun, 15 Nov 2020 16:35:41 +0100 Subject: [PATCH 214/705] Fixed broken link to CONTRIBUTING.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index baf7c84c3b..70deada435 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ Plugins requests and support is available in our [Modmail Plugins Server](https: ## Contributing -Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/kyb3r/modmail/blob/master/CONTRIBUTING.md) before you get started. +Contributions to Modmail are always welcome, whether it be improvements to the documentation or new functionality, please feel free to make the change. Check out our [contributing guidelines](https://github.com/kyb3r/modmail/blob/master/.github/CONTRIBUTING.md) before you get started. If you like this project and would like to show your appreciation, support us on **[Patreon](https://www.patreon.com/kyber)**! From 348f6ce2bd9c33efb7c73d0de23cad2d00bcb33b Mon Sep 17 00:00:00 2001 From: Zoe Martin Date: Mon, 16 Nov 2020 14:34:07 +0100 Subject: [PATCH 215/705] Changed `thread_auto_open_silently` to `thread_creation_silent` to be more consistent with the other names and added it to config_help.json --- CHANGELOG.md | 2 +- cogs/modmail.py | 2 +- core/config.py | 2 +- core/config_help.json | 11 +++++++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb0ccc854d..4648482afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added -- Added `thread_auto_open_silently` to allow opening threads silently by default +- Added `thread_creation_silent` to allow opening threads silently by default # v3.7.7 diff --git a/cogs/modmail.py b/cogs/modmail.py index beb647b87d..70b43b2046 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -989,7 +989,7 @@ async def contact( if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS): logger.info("Contacting user %s when Modmail DM is disabled.", user) - if not silent and not self.bot.config.get("thread_auto_open_silently"): + if not silent and not self.bot.config.get("thread_creation_silent"): if ctx.author.id == user.id: description = "You have opened a Modmail thread." else: diff --git a/core/config.py b/core/config.py index 198d2bec55..f0b18196a6 100644 --- a/core/config.py +++ b/core/config.py @@ -49,11 +49,11 @@ class ConfigManager: "close_emoji": "🔒", "recipient_thread_close": False, "thread_auto_close_silently": False, - "thread_auto_open_silently": False, "thread_auto_close": isodate.Duration(), "thread_auto_close_response": "This thread has been closed automatically due to inactivity after {timeout}.", "thread_creation_response": "The staff team will get back to you as soon as possible.", "thread_creation_footer": "Your message has been sent", + "thread_creation_silent": False, "thread_self_closable_creation_footer": "Click the lock to close the thread", "thread_creation_title": "Thread Created", "thread_close_footer": "Replying will create a new thread", diff --git a/core/config_help.json b/core/config_help.json index f935e8657c..da51149791 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -303,6 +303,17 @@ "See also: `thread_creation_title`, `thread_creation_response`, `thread_self_closable_creation_footer`, `thread_close_footer`." ] }, + "thread_creation_silent": { + "default": "No", + "description": "Setting this configuration will open a new thread silently by default.", + "examples": [ + "`{prefix}config set thread_creation_silent yes`", + "`{prefix}config set thread_creation_silent no`" + ], + "notes": [ + "Works like `{prefix}contact silent` for every new thread." + ] + }, "thread_self_closable_creation_footer": { "default": "\"Click the lock to close the thread\"", "description": "This is the message embed footer sent to the recipient upon the creation of a new thread.", From c534164169db1aeaa49a265844db90fb42f096e9 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Mon, 16 Nov 2020 20:13:41 +0100 Subject: [PATCH 216/705] Update README.md update latest version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index baf7c84c3b..c41f691c36 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      From 2a0e93e5d3fea4ce9f8905fe65f9b9ed8bbdf075 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 18 Nov 2020 22:39:09 +0800 Subject: [PATCH 217/705] bugfixing and optimisations --- CHANGELOG.md | 10 ++++++++++ bot.py | 8 +++++++- cogs/utility.py | 8 +++++--- core/checks.py | 4 ++-- core/config.py | 45 +++++++++++++++++++++++++++++++++++++-------- core/utils.py | 4 ++-- 6 files changed, 63 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 527b044301..360c8dbddb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.8 + +### Fixed +- Permission levels were not respected +- `perms remove` was not working +- `logs` and `block` would not recognise users in a seperate server setup. + +### Internal +- Optimised `perms get`, bot should respond faster now + # v3.7.7 ### Added diff --git a/bot.py b/bot.py index 820aa51e9d..bec8dbda5f 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.7" +__version__ = "3.7.8" import asyncio @@ -1002,6 +1002,11 @@ async def update_perms( else: if value in permissions[name]: permissions[name].remove(value) + + if isinstance(name, PermissionLevel): + self.config["level_permissions"] = permissions + else: + self.config["command_permissions"] = permissions logger.info("Updating permissions for %s, %s (add=%s).", name, value, add) await self.config.update() @@ -1355,6 +1360,7 @@ async def on_error(self, event_method, *args, **kwargs): async def on_command_error(self, context, exception): if isinstance(exception, commands.BadUnionArgument): + logger.error("Expected exception:", exc_info=exception) msg = "Could not find the specified " + human_join( [c.__name__ for c in exception.converters] ) diff --git a/cogs/utility.py b/cogs/utility.py index be8a0c4ba6..4b6d72ee8b 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1496,23 +1496,25 @@ async def permissions_get( """ if name is None and user_or_role not in {"command", "level", "override"}: - value = self._verify_user_or_role(user_or_role) + value = str(self._verify_user_or_role(user_or_role)) cmds = [] levels = [] done = set() + command_permissions = self.bot.config["command_permissions"] + level_permissions = self.bot.config["level_permissions"] for command in self.bot.walk_commands(): if command not in done: done.add(command) - permissions = self.bot.config["command_permissions"].get( + permissions = command_permissions.get( command.qualified_name, [] ) if value in permissions: cmds.append(command.qualified_name) for level in PermissionLevel: - permissions = self.bot.config["level_permissions"].get(level.name, []) + permissions = level_permissions.get(level.name, []) if value in permissions: levels.append(level.name) diff --git a/core/checks.py b/core/checks.py index 0b7b2acfa3..22de08f2ce 100644 --- a/core/checks.py +++ b/core/checks.py @@ -62,7 +62,7 @@ async def check_permissions(ctx, command_name) -> bool: if command_name in command_permissions: # -1 is for @everyone return -1 in command_permissions[command_name] or any( - check.id in command_permissions[command_name] for check in checkables + str(check.id) in command_permissions[command_name] for check in checkables ) level_permissions = ctx.bot.config["level_permissions"] @@ -71,7 +71,7 @@ async def check_permissions(ctx, command_name) -> bool: if level >= permission_level and level.name in level_permissions: # -1 is for @everyone if -1 in level_permissions[level.name] or any( - check.id in level_permissions[level.name] for check in checkables + str(check.id) in level_permissions[level.name] for check in checkables ): return True return False diff --git a/core/config.py b/core/config.py index 58061b8ae2..cd1047b68e 100644 --- a/core/config.py +++ b/core/config.py @@ -14,7 +14,7 @@ from core._color_data import ALL_COLORS from core.models import DMDisabled, InvalidConfigError, Default, getLogger from core.time import UserFriendlyTimeSync -from core.utils import strtobool +from core.utils import strtobool, tryint logger = getLogger(__name__) load_dotenv() @@ -175,6 +175,11 @@ class ConfigManager: "activity_type": discord.ActivityType, } + force_str = { + "command_permissions", + "level_permissions" + } + defaults = {**public_keys, **private_keys, **protected_keys} all_keys = set(defaults.keys()) @@ -245,18 +250,19 @@ def __setitem__(self, key: str, item: typing.Any) -> None: self._cache[key] = item def __getitem__(self, key: str) -> typing.Any: - key = key.lower() - if key not in self.all_keys: - raise InvalidConfigError(f'Configuration "{key}" is invalid.') - if key not in self._cache: - self._cache[key] = deepcopy(self.defaults[key]) - return self._cache[key] + # make use of the custom methods in func:get: + return self.get(key) def __delitem__(self, key: str) -> None: return self.remove(key) def get(self, key: str, convert=True) -> typing.Any: - value = self.__getitem__(key) + key = key.lower() + if key not in self.all_keys: + raise InvalidConfigError(f'Configuration "{key}" is invalid.') + if key not in self._cache: + self._cache[key] = deepcopy(self.defaults[key]) + value = self._cache[key] if not convert: return value @@ -295,6 +301,29 @@ def get(self, key: str, convert=True) -> typing.Any: logger.warning("Invalid %s %s.", key, value) value = self.remove(key) + elif key in self.force_str: + # Temporary: as we saved in int previously, leading to int32 overflow, + # this is transitioning IDs to strings + new_value = {} + changed = False + for k, v in value.items(): + new_v = v + if isinstance(v, list): + new_v = [] + for n in v: + print('x', n, v) + if n != -1 and not isinstance(n, str): + changed = True + n = str(n) + new_v.append(n) + new_value[k] = new_v + + if changed: + # transition the database as well + self.set(key, new_value) + + value = new_value + return value def set(self, key: str, item: typing.Any, convert=True) -> None: diff --git a/core/utils.py b/core/utils.py index b6640eaed8..6803b97d1e 100644 --- a/core/utils.py +++ b/core/utils.py @@ -56,11 +56,11 @@ class User(commands.IDConverter): # noinspection PyCallByClass,PyTypeChecker async def convert(self, ctx, argument): try: - return await commands.MemberConverter.convert(self, ctx, argument) + return await commands.MemberConverter().convert(ctx, argument) except commands.BadArgument: pass try: - return await commands.UserConverter.convert(self, ctx, argument) + return await commands.UserConverter().convert(ctx, argument) except commands.BadArgument: pass match = self._get_id_match(argument) From d160b2b73f1bcd604ee74fe9d9051dde371be1e1 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Wed, 18 Nov 2020 22:52:49 +0800 Subject: [PATCH 218/705] linting --- bot.py | 2 +- cogs/utility.py | 4 +--- core/config.py | 9 +++------ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index bec8dbda5f..f93343854d 100644 --- a/bot.py +++ b/bot.py @@ -1002,7 +1002,7 @@ async def update_perms( else: if value in permissions[name]: permissions[name].remove(value) - + if isinstance(name, PermissionLevel): self.config["level_permissions"] = permissions else: diff --git a/cogs/utility.py b/cogs/utility.py index 4b6d72ee8b..aa916274f1 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1507,9 +1507,7 @@ async def permissions_get( for command in self.bot.walk_commands(): if command not in done: done.add(command) - permissions = command_permissions.get( - command.qualified_name, [] - ) + permissions = command_permissions.get(command.qualified_name, []) if value in permissions: cmds.append(command.qualified_name) diff --git a/core/config.py b/core/config.py index cd1047b68e..304b9fa837 100644 --- a/core/config.py +++ b/core/config.py @@ -175,11 +175,8 @@ class ConfigManager: "activity_type": discord.ActivityType, } - force_str = { - "command_permissions", - "level_permissions" - } - + force_str = {"command_permissions", "level_permissions"} + defaults = {**public_keys, **private_keys, **protected_keys} all_keys = set(defaults.keys()) @@ -311,7 +308,7 @@ def get(self, key: str, convert=True) -> typing.Any: if isinstance(v, list): new_v = [] for n in v: - print('x', n, v) + print("x", n, v) if n != -1 and not isinstance(n, str): changed = True n = str(n) From d52c2d4c76216703907744157a5c0da481082f16 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 19 Nov 2020 22:42:20 +0800 Subject: [PATCH 219/705] Typos --- core/config_help.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/config_help.json b/core/config_help.json index f935e8657c..187ed606c8 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -644,7 +644,7 @@ "`{prefix}config set confirm_thread_creation yes`" ], "notes": [ - "See also: `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + "See also: `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny``" ] }, "confirm_thread_creation_title": { @@ -654,7 +654,7 @@ "`{prefix}config set confirm_thread_creation_title Are you sure you want to create a new thread?`" ], "notes": [ - "See also: `confirm_thread_creation`, `confirm_thread_response`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + "See also: `confirm_thread_creation`, `confirm_thread_response`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny`" ] }, "confirm_thread_response": { @@ -664,7 +664,7 @@ "`{prefix}config set confirm_thread_response React to confirm`" ], "notes": [ - "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_accept`, confirm_thread_creation_deny`" + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny`" ] }, "confirm_thread_creation_accept": { @@ -675,7 +675,7 @@ ], "notes": [ "This has no effect unless `confirm_thread_creation` is set", - "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_deny`" + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_deny`" ] }, "confirm_thread_creation_deny": { @@ -686,7 +686,7 @@ ], "notes": [ "This has no effect unless `confirm_thread_creation` is set", - "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, confirm_thread_creation_accept`" + "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_response`, `confirm_thread_creation_accept`" ] }, "use_regex_autotrigger": { From 92f5c8ec7af694094688973a38ea376ba90e72b0 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 19 Nov 2020 22:53:16 +0800 Subject: [PATCH 220/705] Fix various bugs with threads glitching --- bot.py | 2 +- core/thread.py | 31 ++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/bot.py b/bot.py index f93343854d..bfdd837bce 100644 --- a/bot.py +++ b/bot.py @@ -1164,7 +1164,7 @@ async def handle_reaction_events(self, payload): logger.warning("Failed to find linked message for reactions: %s", e) return - if self.config["transfer_reactions"]: + if self.config["transfer_reactions"] and linked_message is not None: if payload.event_type == "REACTION_ADD": if await self.add_reaction(linked_message, reaction): await self.add_reaction(message, reaction) diff --git a/core/thread.py b/core/thread.py index 28ceef7548..ba6443c35a 100644 --- a/core/thread.py +++ b/core/thread.py @@ -663,22 +663,23 @@ async def find_linked_message_from_dm(self, message, either_direction=False): else: compare_url = None - async for linked_message in self.channel.history(): - if not linked_message.embeds: - continue - url = linked_message.embeds[0].author.url - if not url: - continue - if url == compare_url: - return linked_message + if self.channel is not None: + async for linked_message in self.channel.history(): + if not linked_message.embeds: + continue + url = linked_message.embeds[0].author.url + if not url: + continue + if url == compare_url: + return linked_message - msg_id = url.split("#")[-1] - if not msg_id.isdigit(): - continue - msg_id = int(msg_id) - if int(msg_id) == message.id: - return linked_message - raise ValueError("Thread channel message not found.") + msg_id = url.split("#")[-1] + if not msg_id.isdigit(): + continue + msg_id = int(msg_id) + if int(msg_id) == message.id: + return linked_message + raise ValueError("Thread channel message not found.") async def edit_dm_message(self, message: discord.Message, content: str) -> None: try: From fae05a5cc4e2120e2d4829deaae3131fa914baba Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:01:06 +0800 Subject: [PATCH 221/705] Fix custom emojis not working in confirm thread creation --- CHANGELOG.md | 1 + core/thread.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d2d599fd3..16021fcf93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Permission levels were not respected - `perms remove` was not working - `logs` and `block` would not recognise users in a seperate server setup. +- Custom emojis were not working with `confirm_thread_creation` ### Internal - Optimised `perms get`, bot should respond faster now diff --git a/core/thread.py b/core/thread.py index ba6443c35a..c4a3217da4 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1182,7 +1182,7 @@ async def create( check=lambda r, u: u.id == message.author.id and r.message.id == confirm.id and r.message.channel.id == confirm.channel.id - and r.emoji in (accept_emoji, deny_emoji), + and str(r.emoji) in (accept_emoji, deny_emoji), timeout=20, ) except asyncio.TimeoutError: From efc9feec1661fcfaebe47da3c1ad84361571e1f9 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:02:09 +0800 Subject: [PATCH 222/705] Push v --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16021fcf93..e6078ffac3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.8 +# v3.7.8-dev1 ### Added diff --git a/README.md b/README.md index baf7c84c3b..c41f691c36 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index bfdd837bce..4c41b88b6e 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.8" +__version__ = "3.7.8-dev1" import asyncio From 4acbbe4a90efd9fe85c09c9e85f0776d3de20250 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:06:01 +0800 Subject: [PATCH 223/705] Fix discord server link in about, resolve #2890 --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index aa916274f1..9214553cfd 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -345,7 +345,7 @@ async def about(self, ctx): embed.add_field( name="Want Modmail in Your Server?", value="Follow the installation guide on [GitHub](https://github.com/kyb3r/modmail/) " - "and join our [Discord server](https://discord.gg/F34cRU8/)!", + "and join our [Discord server](https://discord.gg/F34cRU8)!", inline=False, ) From 23534f6d90d5d08fc7d9e6fe03e88323510d4a80 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:07:00 +0800 Subject: [PATCH 224/705] 3.7.8! --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6078ffac3..16021fcf93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.8-dev1 +# v3.7.8 ### Added diff --git a/README.md b/README.md index 978f83aa07..03b41ab0da 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 4c41b88b6e..bfdd837bce 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.8-dev1" +__version__ = "3.7.8" import asyncio From 802e74040797c9c64b285d50c4267625b4a5b82e Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:20:07 +0800 Subject: [PATCH 225/705] Cleanup changelog --- CHANGELOG.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16021fcf93..9e4c4c5fef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,16 +10,16 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Added -- Added `thread_contact_silently` to allow opening threads silently by default +- Added `thread_contact_silently` to allow opening threads silently by default. ([PR #2887](https://github.com/kyb3r/modmail/pull/2887)) ### Fixed -- Permission levels were not respected -- `perms remove` was not working +- Permission levels were not respected. +- `perms remove` was not working. - `logs` and `block` would not recognise users in a seperate server setup. -- Custom emojis were not working with `confirm_thread_creation` +- Custom emojis were not working with `confirm_thread_creation`. ### Internal -- Optimised `perms get`, bot should respond faster now +- Optimised `perms get`, bot should respond faster now. # v3.7.7 @@ -29,14 +29,14 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed -- Skip blocked roles check if user is not in main guild +- Skip blocked roles check if user is not in main guild. # v3.7.6 ### Fixed -- Autoupdate persists despite errors -- Mention when normal thread created was not working. +- Autoupdate persists despite errors. +- Mention when normal thread created was not working. ([GH #2883](https://github.com/kyb3r/modmail/issues/2883)) # v3.7.5 @@ -60,7 +60,6 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?config set` would not respond if an invalid key was provided. - # v3.7.1 ### Fixed From 03899d28a2c9fa84c8f52cd00a9927a0edac1f15 Mon Sep 17 00:00:00 2001 From: Zoe Martin Date: Fri, 20 Nov 2020 00:30:47 +0100 Subject: [PATCH 226/705] Fixes kyb3r/modmail#2892 --- CHANGELOG.md | 6 ++++++ bot.py | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e4c4c5fef..01bdac54db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.9 + +### Fixed + +- `perms add/remove` should now work again + # v3.7.8 ### Added diff --git a/bot.py b/bot.py index bfdd837bce..2cd261218a 100644 --- a/bot.py +++ b/bot.py @@ -988,9 +988,11 @@ async def update_perms( ) -> None: value = str(value) if isinstance(name, PermissionLevel): + level = True permissions = self.config["level_permissions"] name = name.name else: + level = False permissions = self.config["command_permissions"] if name not in permissions: if add: @@ -1003,7 +1005,7 @@ async def update_perms( if value in permissions[name]: permissions[name].remove(value) - if isinstance(name, PermissionLevel): + if level: self.config["level_permissions"] = permissions else: self.config["command_permissions"] = permissions From 794384029c28bbe87e80d9ca821dd1b592c58e2e Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 20 Nov 2020 14:51:07 +0800 Subject: [PATCH 227/705] Add pr attribution --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01bdac54db..78b25fa76f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed -- `perms add/remove` should now work again +- `perms add/remove` should now work again. ([PR #2893](https://github.com/kyb3r/modmail/pull/2893)) # v3.7.8 From ded1bb6b9373404d4363fb2e980b8bedba5b3555 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 20 Nov 2020 15:31:35 +0800 Subject: [PATCH 228/705] Fix more bugs in permlevels --- CHANGELOG.md | 2 +- README.md | 2 +- bot.py | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b25fa76f..71463960a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed -- `perms add/remove` should now work again. ([PR #2893](https://github.com/kyb3r/modmail/pull/2893)) +- `perms add/remove` with permission levels should now work again. ([PR #2893](https://github.com/kyb3r/modmail/pull/2893)) # v3.7.8 diff --git a/README.md b/README.md index 03b41ab0da..114fc5aa41 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 2cd261218a..b72e183fd3 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.8" +__version__ = "3.7.9" import asyncio @@ -986,7 +986,8 @@ async def get_context(self, message, *, cls=commands.Context): async def update_perms( self, name: typing.Union[PermissionLevel, str], value: int, add: bool = True ) -> None: - value = str(value) + if value != -1: + value = str(value) if isinstance(name, PermissionLevel): level = True permissions = self.config["level_permissions"] From 306df8a2d15cc9c6d5014df1f5207b59d4d0f661 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 20 Nov 2020 15:44:11 +0800 Subject: [PATCH 229/705] Clearer plugin debug messages when plugins are disabled --- CHANGELOG.md | 4 ++++ cogs/plugins.py | 8 ++++++++ core/config.py | 1 - 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71463960a4..ead227ffd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `perms add/remove` with permission levels should now work again. ([PR #2893](https://github.com/kyb3r/modmail/pull/2893)) +### Improved + +- Clearer plugin debug messages when plugins are disabled + # v3.7.8 ### Added diff --git a/cogs/plugins.py b/cogs/plugins.py index cdea3a4ce8..ce21551831 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -248,6 +248,14 @@ async def load_plugin(self, plugin): async def parse_user_input(self, ctx, plugin_name, check_version=False): + if not self.bot.config["enable_plugins"]: + embed = discord.Embed( + description="Plugins are disabled, enable them by setting `ENABLE_PLUGINS=true`", + color=self.bot.main_color, + ) + await ctx.send(embed=em) + return + if not self._ready_event.is_set(): embed = discord.Embed( description="Plugins are still loading, please try again later.", diff --git a/core/config.py b/core/config.py index 1fa2d9070c..38a022b769 100644 --- a/core/config.py +++ b/core/config.py @@ -310,7 +310,6 @@ def get(self, key: str, convert=True) -> typing.Any: if isinstance(v, list): new_v = [] for n in v: - print("x", n, v) if n != -1 and not isinstance(n, str): changed = True n = str(n) From 34befb593824aaeee2979fc7d30f837509ccfc9a Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 20 Nov 2020 21:14:13 +0800 Subject: [PATCH 230/705] update channel id and show timestamp config, resolves #2885 --- CHANGELOG.md | 9 ++++++++- README.md | 2 +- bot.py | 22 +++++++++++++++++++--- cogs/modmail.py | 7 +++---- core/config.py | 3 +++ core/config_help.json | 18 ++++++++++++++++++ core/thread.py | 10 ++++++---- 7 files changed, 58 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ead227ffd0..a7a13c67f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.10 + +### Added + +- Added `update_channel_id` to specify which channel autoupdate notifications were being sent to. +- Added `show_timestamp` to specify if timestamps should be displayed in message embeds. ([GH #2885](https://github.com/kyb3r/modmail/issues/2885)) + # v3.7.9 ### Fixed -- `perms add/remove` with permission levels should now work again. ([PR #2893](https://github.com/kyb3r/modmail/pull/2893)) +- `perms add/remove` with permission levels should now work again. ([GH #2892](https://github.com/kyb3r/modmail/issues/2892), [PR #2893](https://github.com/kyb3r/modmail/pull/2893)) ### Improved diff --git a/README.md b/README.md index 114fc5aa41..755d9e5ffa 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index b72e183fd3..151d4bbe60 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.9" +__version__ = "3.7.10" import asyncio @@ -270,6 +270,21 @@ def mention_channel(self): return self.log_channel + @property + def update_channel(self): + channel_id = self.config["update_channel_id"] + if channel_id is not None: + try: + channel = self.get_channel(int(channel_id)) + if channel is not None: + return channel + except ValueError: + pass + logger.debug("UPDATE_CHANNEL_ID was invalid, removed.") + self.config.remove("update_channel_id") + + return self.log_channel + async def wait_for_connected(self) -> None: await self.wait_until_ready() await self._connected.wait() @@ -1027,8 +1042,9 @@ async def on_message(self, message): title="Bot mention", description=f"[Jump URL]({message.jump_url})\n{truncate(message.content, 50)}", color=self.main_color, - timestamp=datetime.utcnow(), ) + if self.config["show_timestamp"]: + em.timestamp = datetime.utcnow() await self.mention_channel.send(content=self.config["mention"], embed=em) await self.process_commands(message) @@ -1508,7 +1524,7 @@ async def autoupdate(self): elif res != "Already up to date.": logger.info("Bot has been updated.") - channel = self.log_channel + channel = self.update_channel if self.hosting_method == HostingMethod.PM2: embed = discord.Embed(title="Bot has been updated", color=self.main_color) await channel.send(embed=embed) diff --git a/cogs/modmail.py b/cogs/modmail.py index c6491076c2..fe8cbce972 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -996,11 +996,10 @@ async def contact( description = f"{ctx.author.name} has opened a Modmail thread." em = discord.Embed( - title="New Thread", - description=description, - color=self.bot.main_color, - timestamp=datetime.utcnow(), + title="New Thread", description=description, color=self.bot.main_color, ) + if self.bot.config["show_timestamp"]: + em.timestamp = datetime.utcnow() em.set_footer(icon_url=ctx.author.avatar_url) await user.send(embed=em) diff --git a/core/config.py b/core/config.py index 38a022b769..888275c1fb 100644 --- a/core/config.py +++ b/core/config.py @@ -43,6 +43,7 @@ class ConfigManager: # logging "log_channel_id": None, "mention_channel_id": None, + "update_channel_id": None, # threads "sent_emoji": "✅", "blocked_emoji": "🚫", @@ -76,6 +77,7 @@ class ConfigManager: "close_on_leave": False, "close_on_leave_reason": "The recipient has left the server.", "alert_on_mention": False, + "show_timestamp": True, # moderation "recipient_color": str(discord.Color.gold()), "mod_color": str(discord.Color.green()), @@ -162,6 +164,7 @@ class ConfigManager: "transfer_reactions", "close_on_leave", "alert_on_mention", + "show_timestamp", "confirm_thread_creation", "use_regex_autotrigger", "enable_plugins", diff --git a/core/config_help.json b/core/config_help.json index f5ccc0d17d..7c36f75cbc 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -185,6 +185,17 @@ "See also: `log_channel_id`" ] }, + "update_channel_id": { + "default": "Log Channel (normally `#bot-logs`)", + "description": "This is the channel where update notifications are sent to.", + "examples": [ + "`{prefix}config set update_channel_id 9234932582312` (9234932582312 is the channel ID)" + ], + "notes": [ + "This has no effect unless `disable_autoupdates` is set to no.", + "See also: `log_channel_id`" + ] + }, "sent_emoji": { "default": "✅", "description": "This is the emoji added to the message when when a Modmail action is invoked successfully (ie. DM Modmail, edit message, etc.).", @@ -648,6 +659,13 @@ "See also: `mention`" ] }, + "show_timestamp": { + "default": "Yes", + "description": "Shows timestamps on thread embeds", + "examples":[ + "`{prefix}config set show_timestamp no`" + ] + }, "confirm_thread_creation": { "default": "No", "description": "Ensure users confirm that they want to create a new thread", diff --git a/core/thread.py b/core/thread.py index c4a3217da4..5e1c28f15f 100644 --- a/core/thread.py +++ b/core/thread.py @@ -460,10 +460,10 @@ async def _close( # Thread closed message embed = discord.Embed( - title=self.bot.config["thread_close_title"], - color=self.bot.error_color, - timestamp=datetime.utcnow(), + title=self.bot.config["thread_close_title"], color=self.bot.error_color, ) + if self.bot.config["show_timestamp"]: + embed.timestamp = datetime.utcnow() if not message: if self.id == closer.id: @@ -823,7 +823,9 @@ async def send( author = message.author - embed = discord.Embed(description=message.content, timestamp=message.created_at) + embed = discord.Embed(description=message.content) + if self.bot.config["show_timestamp"]: + embed.timestamp = message.created_at system_avatar_url = "https://discordapp.com/assets/f78426a064bc9dd24847519259bc42af.png" From eefb6c7c4a3d8212a807005373d4ea28f2c83b2d Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 20 Nov 2020 21:54:57 +0800 Subject: [PATCH 231/705] Improve role block, fix bot restart pm2 --- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- bot.py | 22 +++++++++++++--------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7a13c67f2..03ec6214a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.11 + +### Improved + +- Role block will now work better with seperate server setups. + +### Fixed + +- Bot not restarting after autoupdate on PM2. + +### Internal + +- Removed unnecessary loggings. + # v3.7.10 ### Added diff --git a/README.md b/README.md index 755d9e5ffa..ac1fb6966c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 151d4bbe60..51a238a109 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.10" +__version__ = "3.7.11" import asyncio @@ -559,7 +559,7 @@ async def on_ready(self): ] if any(other_guilds): logger.warning( - "The bot is in more servers other than the main and staff server." + "The bot is in more servers other than the main and staff server. " "This may cause data compromise (%s).", ", ".join(guild.name for guild in other_guilds), ) @@ -729,8 +729,16 @@ async def is_blocked( member = self.guild.get_member(author.id) if member is None: - logger.debug("User not in guild, %s.", author.id) - else: + # try to find in other guilds + for g in self.guilds: + member = g.get_member(author.id) + if member: + break + + if member is None: + logger.debug("User not in guild, %s.", author.id) + + if member is not None: author = member if str(author.id) in self.blocked_whitelisted_users: @@ -1379,10 +1387,6 @@ async def on_error(self, event_method, *args, **kwargs): async def on_command_error(self, context, exception): if isinstance(exception, commands.BadUnionArgument): - logger.error("Expected exception:", exc_info=exception) - msg = "Could not find the specified " + human_join( - [c.__name__ for c in exception.converters] - ) await context.trigger_typing() await context.send(embed=discord.Embed(color=self.error_color, description=msg)) @@ -1535,7 +1539,7 @@ async def autoupdate(self): color=self.main_color, ) await channel.send(embed=embed) - await self.logout() + await self.logout() async def before_autoupdate(self): await self.wait_for_connected() From 6bec4d34c117c00cc81cd04c66713acf95f01e00 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Fri, 20 Nov 2020 21:57:05 +0800 Subject: [PATCH 232/705] lint --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 51a238a109..40b040c684 100644 --- a/bot.py +++ b/bot.py @@ -737,7 +737,7 @@ async def is_blocked( if member is None: logger.debug("User not in guild, %s.", author.id) - + if member is not None: author = member From 358de8a529821f522788cb7bcf59190a2040e237 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 21 Nov 2020 15:22:50 +0800 Subject: [PATCH 233/705] Fix bug in block, thread reason not working --- CHANGELOG.md | 7 +++++++ README.md | 2 +- bot.py | 8 ++------ cogs/modmail.py | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03ec6214a0..21e9b7dde6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.12 + +### Fixed + +- Bot was not responding to union errors. +- `?block [reason]` now works in threads. + # v3.7.11 ### Improved diff --git a/README.md b/README.md index ac1fb6966c..04b343c85f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index 40b040c684..e520d9302f 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.11" +__version__ = "3.7.12" import asyncio @@ -1386,11 +1386,7 @@ async def on_error(self, event_method, *args, **kwargs): logger.error("Unexpected exception:", exc_info=sys.exc_info()) async def on_command_error(self, context, exception): - if isinstance(exception, commands.BadUnionArgument): - await context.trigger_typing() - await context.send(embed=discord.Embed(color=self.error_color, description=msg)) - - elif isinstance(exception, commands.BadArgument): + if isinstance(exception, commands.BadArgument): await context.trigger_typing() await context.send( embed=discord.Embed(color=self.error_color, description=str(exception)) diff --git a/cogs/modmail.py b/cogs/modmail.py index fe8cbce972..e71214d335 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1147,7 +1147,7 @@ async def blocked_whitelist(self, ctx, *, user: User = None): async def block( self, ctx, - user_or_role: Union[User, discord.Role] = None, + user_or_role: Optional[Union[User, discord.Role]] = None, *, after: UserFriendlyTime = None, ): From c4b90cbbc1f7908c86c68354e49db595bb08f40e Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 23 Nov 2020 19:46:01 +0800 Subject: [PATCH 234/705] Notes in config help are optional --- CHANGELOG.md | 6 ++++++ README.md | 2 +- bot.py | 2 +- cogs/utility.py | 2 +- core/config_help.json | 3 ++- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e9b7dde6..ab7f5adc6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.13 + +### Fixed + +- Notes in config help are now optional. + # v3.7.12 ### Fixed diff --git a/README.md b/README.md index 04b343c85f..8e40426dd1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
      - +
      diff --git a/bot.py b/bot.py index e520d9302f..f670e7e76d 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.12" +__version__ = "3.7.13" import asyncio diff --git a/cogs/utility.py b/cogs/utility.py index 9214553cfd..03a90efe54 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -892,7 +892,7 @@ def fmt(val): embed.add_field(name="Example(s):", value=example_text, inline=False) note_text = "" - for note in info["notes"]: + for note in info.get("notes", []): note_text += f"- {fmt(note)}\n" if note_text: embed.add_field(name="Note(s):", value=note_text, inline=False) diff --git a/core/config_help.json b/core/config_help.json index 7c36f75cbc..549e3d9486 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -664,7 +664,8 @@ "description": "Shows timestamps on thread embeds", "examples":[ "`{prefix}config set show_timestamp no`" - ] + ], + "notes": [] }, "confirm_thread_creation": { "default": "No", From fc086bf731427846486cfa978c2178c68aba878e Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Tue, 24 Nov 2020 15:14:16 +0100 Subject: [PATCH 235/705] Update utility.py added new competing bot-presence to the help list --- cogs/utility.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/utility.py b/cogs/utility.py index 03a90efe54..ee61509dc8 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -506,6 +506,7 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): - `streaming` - `listening` - `watching` + - `competing` When activity type is set to `listening`, it must be followed by a "to": "listening to..." From 63461bbb276fe4f160d6da545fec7fd62d7338d5 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 26 Nov 2020 18:22:58 +0800 Subject: [PATCH 236/705] add update_notifications, resolves #2896 --- CHANGELOG.md | 10 ++++++++++ bot.py | 13 +++++++++---- core/config.py | 3 +++ core/config_help.json | 13 ++++++++++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab7f5adc6f..73767c86bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v3.7.14-dev0 + +### Fixed + +- Mentioned `competing` as an activity type ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) + +### Added + +- `update_notifications` configuration option to toggle bot autoupdate notifications ([GH #2896](https://github.com/kyb3r/modmail/issues/2896)) + # v3.7.13 ### Fixed diff --git a/bot.py b/bot.py index f670e7e76d..e46d50f73b 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.13" +__version__ = "3.7.14-dev0" import asyncio @@ -1502,7 +1502,8 @@ async def autoupdate(self): ) logger.info("Bot has been updated.") channel = self.log_channel - await channel.send(embed=embed) + if self.bot.config["update_notifications"]: + await channel.send(embed=embed) else: try: # update fork if gh_token exists @@ -1527,14 +1528,18 @@ async def autoupdate(self): channel = self.update_channel if self.hosting_method == HostingMethod.PM2: embed = discord.Embed(title="Bot has been updated", color=self.main_color) - await channel.send(embed=embed) + embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + if self.bot.config["update_notifications"]: + await channel.send(embed=embed) else: embed = discord.Embed( title="Bot has been updated and is logging out.", description="If you do not have an auto-restart setup, please manually start the bot.", color=self.main_color, ) - await channel.send(embed=embed) + embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + if self.bot.config["update_notifications"]: + await channel.send(embed=embed) await self.logout() async def before_autoupdate(self): diff --git a/core/config.py b/core/config.py index 888275c1fb..8317ed7df6 100644 --- a/core/config.py +++ b/core/config.py @@ -44,6 +44,8 @@ class ConfigManager: "log_channel_id": None, "mention_channel_id": None, "update_channel_id": None, + # updates + "update_notifications": True, # threads "sent_emoji": "✅", "blocked_emoji": "🚫", @@ -171,6 +173,7 @@ class ConfigManager: "data_collection", "enable_eval", "disable_autoupdates", + "update_notifications", "thread_contact_silently", } diff --git a/core/config_help.json b/core/config_help.json index 549e3d9486..815d2a6b17 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -192,10 +192,21 @@ "`{prefix}config set update_channel_id 9234932582312` (9234932582312 is the channel ID)" ], "notes": [ - "This has no effect unless `disable_autoupdates` is set to no.", + "This has no effect unless `disable_autoupdates` is set to no and `update_notifications` is set to yes.", "See also: `log_channel_id`" ] }, + "update_notifications": { + "default": "Yes", + "description": "This is the channel where update notifications are sent to.", + "examples": [ + "`{prefix}config set update_notifications no" + ], + "notes": [ + "This has no effect unless `disable_autoupdates` is set to no.", + "See also: `update_channel_id`" + ] + }, "sent_emoji": { "default": "✅", "description": "This is the emoji added to the message when when a Modmail action is invoked successfully (ie. DM Modmail, edit message, etc.).", From a97119d160942f67b90198a610a8c1f908eb8a5c Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 26 Nov 2020 18:35:48 +0800 Subject: [PATCH 237/705] Added command validation to autotrigger --- CHANGELOG.md | 12 ++++++---- bot.py | 9 +++++--- cogs/utility.py | 60 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73767c86bb..ae277a9b61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,17 @@ however, insignificant breaking changes do not guarantee a major version bump, s # v3.7.14-dev0 -### Fixed +### Added -- Mentioned `competing` as an activity type ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) +- `update_notifications` configuration option to toggle bot autoupdate notifications. ([GH #2896](https://github.com/kyb3r/modmail/issues/2896)) -### Added +### Improved + +- Added command validation to `autotrigger add/edit`. + +### Fixed -- `update_notifications` configuration option to toggle bot autoupdate notifications ([GH #2896](https://github.com/kyb3r/modmail/issues/2896)) +- Mentioned `competing` as an activity type. ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) # v3.7.13 diff --git a/bot.py b/bot.py index e46d50f73b..c663f2bb84 100644 --- a/bot.py +++ b/bot.py @@ -937,7 +937,6 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) invoked_prefix = self.prefix invoker = None - # Check if there is any aliases being called. if self.config.get("use_regex_autotrigger"): trigger = next( filter(lambda x: re.match(x, message.content), self.auto_triggers.keys()) @@ -1528,7 +1527,9 @@ async def autoupdate(self): channel = self.update_channel if self.hosting_method == HostingMethod.PM2: embed = discord.Embed(title="Bot has been updated", color=self.main_color) - embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + embed.set_footer( + text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" + ) if self.bot.config["update_notifications"]: await channel.send(embed=embed) else: @@ -1537,7 +1538,9 @@ async def autoupdate(self): description="If you do not have an auto-restart setup, please manually start the bot.", color=self.main_color, ) - embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}") + embed.set_footer( + text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" + ) if self.bot.config["update_notifications"]: await channel.send(embed=embed) await self.logout() diff --git a/cogs/utility.py b/cogs/utility.py index ee61509dc8..eb17e9c212 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1727,14 +1727,30 @@ async def autotrigger_add(self, ctx, keyword, *, command): description=f"Another autotrigger with the same name already exists: `{keyword}`.", ) else: - self.bot.auto_triggers[keyword] = command - await self.bot.config.update() + # command validation + valid = False + split_cmd = command.split(" ") + for n in range(1, len(split_cmd) + 1): + if self.bot.get_command(" ".join(split_cmd[0:n])): + print(self.bot.get_command(" ".join(split_cmd[0:n]))) + valid = True + break + + if valid: + self.bot.auto_triggers[keyword] = command + await self.bot.config.update() - embed = discord.Embed( - title="Success", - color=self.bot.main_color, - description=f"Keyword `{keyword}` has been linked to `{command}`.", - ) + embed = discord.Embed( + title="Success", + color=self.bot.main_color, + description=f"Keyword `{keyword}` has been linked to `{command}`.", + ) + else: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description="Invalid command. Note that autotriggers do not work with aliases.", + ) await ctx.send(embed=embed) @@ -1747,14 +1763,30 @@ async def autotrigger_edit(self, ctx, keyword, *, command): keyword, self.bot.auto_triggers.keys(), "Autotrigger" ) else: - self.bot.auto_triggers[keyword] = command - await self.bot.config.update() + # command validation + valid = False + split_cmd = command.split(" ") + for n in range(1, len(split_cmd) + 1): + if self.bot.get_command(" ".join(split_cmd[0:n])): + print(self.bot.get_command(" ".join(split_cmd[0:n]))) + valid = True + break + + if valid: + self.bot.auto_triggers[keyword] = command + await self.bot.config.update() - embed = discord.Embed( - title="Success", - color=self.bot.main_color, - description=f"Keyword `{keyword}` has been linked to `{command}`.", - ) + embed = discord.Embed( + title="Success", + color=self.bot.main_color, + description=f"Keyword `{keyword}` has been linked to `{command}`.", + ) + else: + embed = discord.Embed( + title="Error", + color=self.bot.error_color, + description="Invalid command. Note that autotriggers do not work with aliases.", + ) await ctx.send(embed=embed) From ccde7b0f5740ad945f872404773e614849d36624 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 26 Nov 2020 18:45:44 +0800 Subject: [PATCH 238/705] Make use of `git branch --show-current` to retrieve branch --- CHANGELOG.md | 4 ++++ core/changelog.py | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae277a9b61..4fe715b883 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Mentioned `competing` as an activity type. ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) +### Internal + +- Make use of `git branch --show-current` to retrieve branch insteasd of using prerelease version check. + # v3.7.13 ### Fixed diff --git a/core/changelog.py b/core/changelog.py index 60d0179609..163aa0f340 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -1,4 +1,6 @@ +import asyncio import re +from subprocess import PIPE from typing import List from discord import Embed @@ -167,7 +169,17 @@ async def from_url(cls, bot, url: str = "") -> "Changelog": Changelog The newly created `Changelog` parsed from the `url`. """ - branch = "master" if not bot.version.is_prerelease else "development" + # get branch via git cli if available + proc = await asyncio.create_subprocess_shell( + "git branch --show-current", stderr=PIPE, stdout=PIPE, + ) + err = await proc.stderr.read() + err = err.decode("utf-8").rstrip() + res = await proc.stdout.read() + branch = res.decode("utf-8").rstrip() + if not branch or err: + branch = "master" if not bot.version.is_prerelease else "development" + url = url or f"https://raw.githubusercontent.com/kyb3r/modmail/{branch}/CHANGELOG.md" async with await bot.session.get(url) as resp: From f335d265c85aafd80d9d6d99721af5a5e20bddfd Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 26 Nov 2020 18:57:37 +0800 Subject: [PATCH 239/705] Fix bug where level permissions were not being checked if cmd perms were set --- CHANGELOG.md | 1 + core/checks.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fe715b883..a1547479c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Fixed - Mentioned `competing` as an activity type. ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) +- Level permissions were not checked if command permissions were set. ### Internal diff --git a/core/checks.py b/core/checks.py index 22de08f2ce..b7c56a1a7d 100644 --- a/core/checks.py +++ b/core/checks.py @@ -61,9 +61,10 @@ async def check_permissions(ctx, command_name) -> bool: if command_name in command_permissions: # -1 is for @everyone - return -1 in command_permissions[command_name] or any( + if -1 in command_permissions[command_name] or any( str(check.id) in command_permissions[command_name] for check in checkables - ) + ): + return True level_permissions = ctx.bot.config["level_permissions"] From 8b2bea4e533c11df3b1ac401f95a281549384ed4 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 26 Nov 2020 19:01:49 +0800 Subject: [PATCH 240/705] Resolve linting issues --- .bandit_baseline.json | 77 +++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/.bandit_baseline.json b/.bandit_baseline.json index 94fcfd0fc3..28a4e47b9c 100644 --- a/.bandit_baseline.json +++ b/.bandit_baseline.json @@ -1,6 +1,6 @@ { "errors": [], - "generated_at": "2020-11-12T15:17:38Z", + "generated_at": "2020-11-26T11:00:36Z", "metrics": { "./bot.py": { "CONFIDENCE.HIGH": 1.0, @@ -11,7 +11,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1264, + "loc": 1321, "nosec": 0 }, "./cogs/modmail.py": { @@ -23,7 +23,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1280, + "loc": 1273, "nosec": 0 }, "./cogs/plugins.py": { @@ -35,7 +35,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 572, + "loc": 578, "nosec": 0 }, "./cogs/utility.py": { @@ -47,7 +47,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 1710, + "loc": 1755, "nosec": 0 }, "./core/_color_data.py": { @@ -63,15 +63,15 @@ "nosec": 0 }, "./core/changelog.py": { - "CONFIDENCE.HIGH": 0.0, + "CONFIDENCE.HIGH": 1.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 0.0, "CONFIDENCE.UNDEFINED": 0.0, "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 0.0, + "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 145, + "loc": 155, "nosec": 0 }, "./core/checks.py": { @@ -83,7 +83,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 89, + "loc": 90, "nosec": 0 }, "./core/clients.py": { @@ -95,7 +95,7 @@ "SEVERITY.LOW": 1.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 585, + "loc": 587, "nosec": 0 }, "./core/config.py": { @@ -107,7 +107,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 327, + "loc": 352, "nosec": 0 }, "./core/decorators.py": { @@ -131,7 +131,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 199, + "loc": 202, "nosec": 0 }, "./core/paginator.py": { @@ -155,7 +155,7 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 993, + "loc": 996, "nosec": 0 }, "./core/time.py": { @@ -179,19 +179,31 @@ "SEVERITY.LOW": 0.0, "SEVERITY.MEDIUM": 0.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 283, + "loc": 282, + "nosec": 0 + }, + "./plugins/kyb3r/modmail-plugins/profanity-filter-master/profanity-filter.py": { + "CONFIDENCE.HIGH": 0.0, + "CONFIDENCE.LOW": 0.0, + "CONFIDENCE.MEDIUM": 0.0, + "CONFIDENCE.UNDEFINED": 0.0, + "SEVERITY.HIGH": 0.0, + "SEVERITY.LOW": 0.0, + "SEVERITY.MEDIUM": 0.0, + "SEVERITY.UNDEFINED": 0.0, + "loc": 81, "nosec": 0 }, "_totals": { - "CONFIDENCE.HIGH": 4.0, + "CONFIDENCE.HIGH": 5.0, "CONFIDENCE.LOW": 0.0, "CONFIDENCE.MEDIUM": 1.0, "CONFIDENCE.UNDEFINED": 0.0, "SEVERITY.HIGH": 0.0, - "SEVERITY.LOW": 4.0, + "SEVERITY.LOW": 5.0, "SEVERITY.MEDIUM": 1.0, "SEVERITY.UNDEFINED": 0.0, - "loc": 8989, + "loc": 9214, "nosec": 0 } }, @@ -226,41 +238,56 @@ "test_name": "blacklist" }, { - "code": "12 from json import JSONDecodeError, loads\n13 from subprocess import PIPE\n14 from textwrap import indent\n", + "code": "13 from json import JSONDecodeError, loads\n14 from subprocess import PIPE\n15 from textwrap import indent\n", "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "LOW", "issue_text": "Consider possible security implications associated with PIPE module.", - "line_number": 13, + "line_number": 14, "line_range": [ - 13 + 14 ], "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", "test_id": "B404", "test_name": "blacklist" }, { - "code": "1985 try:\n1986 exec(to_compile, env) # pylint: disable=exec-used\n1987 except Exception as exc:\n", + "code": "2039 try:\n2040 exec(to_compile, env) # pylint: disable=exec-used\n2041 except Exception as exc:\n", "filename": "./cogs/utility.py", "issue_confidence": "HIGH", "issue_severity": "MEDIUM", "issue_text": "Use of exec detected.", - "line_number": 1986, + "line_number": 2040, "line_range": [ - 1986 + 2040 ], "more_info": "https://bandit.readthedocs.io/en/latest/plugins/b102_exec_used.html", "test_id": "B102", "test_name": "exec_used" }, { - "code": "68 \n69 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n70 self.bot = bot\n71 self.session = bot.session\n72 self.headers: dict = None\n73 self.access_token = access_token\n74 self.username = username\n75 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n76 self.url: str = kwargs.pop(\"url\", \"\")\n77 if self.access_token:\n78 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n79 \n80 async def request(\n", + "code": "2 import re\n3 from subprocess import PIPE\n4 from typing import List\n", + "filename": "./core/changelog.py", + "issue_confidence": "HIGH", + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with PIPE module.", + "line_number": 3, + "line_range": [ + 3 + ], + "more_info": "https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "67 \n68 def __init__(self, bot, access_token: str = \"\", username: str = \"\", **kwargs):\n69 self.bot = bot\n70 self.session = bot.session\n71 self.headers: dict = None\n72 self.access_token = access_token\n73 self.username = username\n74 self.avatar_url: str = kwargs.pop(\"avatar_url\", \"\")\n75 self.url: str = kwargs.pop(\"url\", \"\")\n76 if self.access_token:\n77 self.headers = {\"Authorization\": \"token \" + str(access_token)}\n78 \n79 @property\n80 def BRANCH(self):\n", "filename": "./core/clients.py", "issue_confidence": "MEDIUM", "issue_severity": "LOW", "issue_text": "Possible hardcoded password: ''", - "line_number": 69, + "line_number": 68, "line_range": [ + 68, 69, 70, 71, From 812494aede7b4d62655fb5c4d20c2ae26cfa54e1 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 26 Nov 2020 20:14:54 +0800 Subject: [PATCH 241/705] trim 'in' from competing activity --- CHANGELOG.md | 2 +- bot.py | 2 +- cogs/utility.py | 10 ++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1547479c9..c8ffdf67c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.14-dev0 +# v3.7.14-dev1 ### Added diff --git a/bot.py b/bot.py index c663f2bb84..59b0e7341b 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev0" +__version__ = "3.7.14-dev1" import asyncio diff --git a/cogs/utility.py b/cogs/utility.py index eb17e9c212..64f9c679c9 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -511,6 +511,9 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): When activity type is set to `listening`, it must be followed by a "to": "listening to..." + When activity type is set to `competing`, + it must be followed by a "in": "competing in..." + When activity type is set to `streaming`, you can set the linked twitch page: - `{prefix}config set twitch_url https://www.twitch.tv/somechannel/` @@ -545,6 +548,8 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): msg = f"Activity set to: {activity.type.name.capitalize()} " if activity.type == ActivityType.listening: msg += f"to {activity.name}." + elif activity.type == ActivityType.competing: + msg += f"in {activity.name}." else: msg += f"{activity.name}." @@ -609,6 +614,11 @@ async def set_presence(self, *, status=None, activity_type=None, activity_messag # The actual message is after listening to [...] # discord automatically add the "to" activity_message = activity_message[3:].strip() + elif activity_type == ActivityType.competing: + if activity_message.lower().startswith("in "): + # The actual message is after listening to [...] + # discord automatically add the "in" + activity_message = activity_message[3:].strip() elif activity_type == ActivityType.streaming: url = self.bot.config["twitch_url"] From f5916be39e5af0731545c8d797913093fe30774d Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 30 Nov 2020 20:37:41 +0800 Subject: [PATCH 242/705] fareply, anonsnippet config, disable_updates config --- CHANGELOG.md | 6 +++++- app.json | 2 +- bot.py | 7 +++++-- cogs/modmail.py | 23 +++++++++++++++++++++++ cogs/utility.py | 1 + core/checks.py | 16 ++++++++++++++++ core/config.py | 4 ++++ core/config_help.json | 9 +++++++++ 8 files changed, 64 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8ffdf67c9..bf908d4bb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.14-dev1 +# v3.7.14-dev2 ### Added - `update_notifications` configuration option to toggle bot autoupdate notifications. ([GH #2896](https://github.com/kyb3r/modmail/issues/2896)) +- `?fareply`, anonymously reply with variables. +- `anonymous_snippets` config variable to toggle if snippets should be anonymous. ([GH #2905](https://github.com/kyb3r/modmail/issues/2905)) +- `disable_updates` config variable to control if the update command should be disabled or not. ### Improved - Added command validation to `autotrigger add/edit`. +- `GITHUB_TOKEN` is now no longer required in Heroku setups. ### Fixed diff --git a/app.json b/app.json index 326c54273e..66b5c77752 100644 --- a/app.json +++ b/app.json @@ -33,7 +33,7 @@ }, "GITHUB_TOKEN": { "description": "A github personal access token with the repo scope.", - "required": true + "required": false } } } \ No newline at end of file diff --git a/bot.py b/bot.py index 59b0e7341b..e1955ff667 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev1" +__version__ = "3.7.14-dev2" import asyncio @@ -1069,7 +1069,10 @@ async def process_commands(self, message): # Process snippets if cmd in self.snippets: snippet = self.snippets[cmd] - message.content = f"{self.prefix}freply {snippet}" + if self.config["anonymous_snippets"]: + message.content = f"{self.prefix}fareply {snippet}" + else: + message.content = f"{self.prefix}freply {snippet}" ctxs = await self.get_contexts(message) for ctx in ctxs: diff --git a/cogs/modmail.py b/cogs/modmail.py index e71214d335..8ba509078c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1,4 +1,5 @@ import asyncio +from operator import truediv import re from datetime import datetime from itertools import zip_longest @@ -835,6 +836,28 @@ async def freply(self, ctx, *, msg: str = ""): async with ctx.typing(): await ctx.thread.reply(ctx.message) + @commands.command(aliases=["formatanonreply"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def fareply(self, ctx, *, msg: str = ""): + """ + Anonymously reply to a Modmail thread with variables. + + Works just like `{prefix}areply`, however with the addition of three variables: + - `{{channel}}` - the `discord.TextChannel` object + - `{{recipient}}` - the `discord.User` object of the recipient + - `{{author}}` - the `discord.User` object of the author + + Supports attachments and images as well as + automatically embedding image URLs. + """ + msg = self.bot.formatter.format( + msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + ) + ctx.message.content = msg + async with ctx.typing(): + await ctx.thread.reply(ctx.message, anonymous=True) + @commands.command(aliases=["anonreply", "anonymousreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() diff --git a/cogs/utility.py b/cogs/utility.py index 64f9c679c9..401f1aa37c 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1896,6 +1896,7 @@ async def github(self, ctx): @commands.command() @checks.has_permissions(PermissionLevel.OWNER) @checks.github_token_required(ignore_if_not_heroku=True) + @checks.updates_enabled() @trigger_typing async def update(self, ctx, *, flag: str = ""): """ diff --git a/core/checks.py b/core/checks.py index b7c56a1a7d..1ff2a67126 100644 --- a/core/checks.py +++ b/core/checks.py @@ -121,3 +121,19 @@ async def predicate(ctx): "personal access token from developer settings." ) return commands.check(predicate) + +def updates_enabled(): + """ + A decorator that ensures + updates are enabled + """ + + async def predicate(ctx): + return not ctx.bot.config["disable_updates"] + + predicate.fail_msg = ( + "Updates are disabled on this bot instance. " + "View `?config help disable_updates` for " + "more information." + ) + return commands.check(predicate) diff --git a/core/config.py b/core/config.py index 8317ed7df6..6b827e74c0 100644 --- a/core/config.py +++ b/core/config.py @@ -80,6 +80,7 @@ class ConfigManager: "close_on_leave_reason": "The recipient has left the server.", "alert_on_mention": False, "show_timestamp": True, + "anonymous_snippets": False, # moderation "recipient_color": str(discord.Color.gold()), "mod_color": str(discord.Color.green()), @@ -143,6 +144,7 @@ class ConfigManager: # github access token for private repositories "github_token": None, "disable_autoupdates": False, + "disable_updates": False, # Logging "log_level": "INFO", # data collection @@ -173,8 +175,10 @@ class ConfigManager: "data_collection", "enable_eval", "disable_autoupdates", + "disable_updates", "update_notifications", "thread_contact_silently", + "anonymous_snippets", } enums = { diff --git a/core/config_help.json b/core/config_help.json index 815d2a6b17..506b9e57bd 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -849,5 +849,14 @@ "notes": [ "This configuration can only to be set through `.env` file or environment (config) variables." ] + }, + "disable_updates": { + "default": "No", + "description": "Controls if the update command should be disabled or not.", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] } } From 05b261b8ce87fb264e4fa992e0e769519f90c329 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 30 Nov 2020 20:37:41 +0800 Subject: [PATCH 243/705] fareply, anonsnippet config, disable_updates config, resolves #2905 --- CHANGELOG.md | 6 +++++- app.json | 2 +- bot.py | 7 +++++-- cogs/modmail.py | 23 +++++++++++++++++++++++ cogs/utility.py | 1 + core/checks.py | 16 ++++++++++++++++ core/config.py | 4 ++++ core/config_help.json | 9 +++++++++ 8 files changed, 64 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8ffdf67c9..bf908d4bb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.14-dev1 +# v3.7.14-dev2 ### Added - `update_notifications` configuration option to toggle bot autoupdate notifications. ([GH #2896](https://github.com/kyb3r/modmail/issues/2896)) +- `?fareply`, anonymously reply with variables. +- `anonymous_snippets` config variable to toggle if snippets should be anonymous. ([GH #2905](https://github.com/kyb3r/modmail/issues/2905)) +- `disable_updates` config variable to control if the update command should be disabled or not. ### Improved - Added command validation to `autotrigger add/edit`. +- `GITHUB_TOKEN` is now no longer required in Heroku setups. ### Fixed diff --git a/app.json b/app.json index 326c54273e..66b5c77752 100644 --- a/app.json +++ b/app.json @@ -33,7 +33,7 @@ }, "GITHUB_TOKEN": { "description": "A github personal access token with the repo scope.", - "required": true + "required": false } } } \ No newline at end of file diff --git a/bot.py b/bot.py index 59b0e7341b..e1955ff667 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev1" +__version__ = "3.7.14-dev2" import asyncio @@ -1069,7 +1069,10 @@ async def process_commands(self, message): # Process snippets if cmd in self.snippets: snippet = self.snippets[cmd] - message.content = f"{self.prefix}freply {snippet}" + if self.config["anonymous_snippets"]: + message.content = f"{self.prefix}fareply {snippet}" + else: + message.content = f"{self.prefix}freply {snippet}" ctxs = await self.get_contexts(message) for ctx in ctxs: diff --git a/cogs/modmail.py b/cogs/modmail.py index e71214d335..8ba509078c 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1,4 +1,5 @@ import asyncio +from operator import truediv import re from datetime import datetime from itertools import zip_longest @@ -835,6 +836,28 @@ async def freply(self, ctx, *, msg: str = ""): async with ctx.typing(): await ctx.thread.reply(ctx.message) + @commands.command(aliases=["formatanonreply"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + @checks.thread_only() + async def fareply(self, ctx, *, msg: str = ""): + """ + Anonymously reply to a Modmail thread with variables. + + Works just like `{prefix}areply`, however with the addition of three variables: + - `{{channel}}` - the `discord.TextChannel` object + - `{{recipient}}` - the `discord.User` object of the recipient + - `{{author}}` - the `discord.User` object of the author + + Supports attachments and images as well as + automatically embedding image URLs. + """ + msg = self.bot.formatter.format( + msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author + ) + ctx.message.content = msg + async with ctx.typing(): + await ctx.thread.reply(ctx.message, anonymous=True) + @commands.command(aliases=["anonreply", "anonymousreply"]) @checks.has_permissions(PermissionLevel.SUPPORTER) @checks.thread_only() diff --git a/cogs/utility.py b/cogs/utility.py index 64f9c679c9..401f1aa37c 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1896,6 +1896,7 @@ async def github(self, ctx): @commands.command() @checks.has_permissions(PermissionLevel.OWNER) @checks.github_token_required(ignore_if_not_heroku=True) + @checks.updates_enabled() @trigger_typing async def update(self, ctx, *, flag: str = ""): """ diff --git a/core/checks.py b/core/checks.py index b7c56a1a7d..1ff2a67126 100644 --- a/core/checks.py +++ b/core/checks.py @@ -121,3 +121,19 @@ async def predicate(ctx): "personal access token from developer settings." ) return commands.check(predicate) + +def updates_enabled(): + """ + A decorator that ensures + updates are enabled + """ + + async def predicate(ctx): + return not ctx.bot.config["disable_updates"] + + predicate.fail_msg = ( + "Updates are disabled on this bot instance. " + "View `?config help disable_updates` for " + "more information." + ) + return commands.check(predicate) diff --git a/core/config.py b/core/config.py index 8317ed7df6..6b827e74c0 100644 --- a/core/config.py +++ b/core/config.py @@ -80,6 +80,7 @@ class ConfigManager: "close_on_leave_reason": "The recipient has left the server.", "alert_on_mention": False, "show_timestamp": True, + "anonymous_snippets": False, # moderation "recipient_color": str(discord.Color.gold()), "mod_color": str(discord.Color.green()), @@ -143,6 +144,7 @@ class ConfigManager: # github access token for private repositories "github_token": None, "disable_autoupdates": False, + "disable_updates": False, # Logging "log_level": "INFO", # data collection @@ -173,8 +175,10 @@ class ConfigManager: "data_collection", "enable_eval", "disable_autoupdates", + "disable_updates", "update_notifications", "thread_contact_silently", + "anonymous_snippets", } enums = { diff --git a/core/config_help.json b/core/config_help.json index 815d2a6b17..506b9e57bd 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -849,5 +849,14 @@ "notes": [ "This configuration can only to be set through `.env` file or environment (config) variables." ] + }, + "disable_updates": { + "default": "No", + "description": "Controls if the update command should be disabled or not.", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] } } From 0eab4f3c2aaa000df923e96ecb3c304f3242635c Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Mon, 30 Nov 2020 20:44:24 +0800 Subject: [PATCH 244/705] lint --- core/checks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/checks.py b/core/checks.py index 1ff2a67126..55eb4d4ea8 100644 --- a/core/checks.py +++ b/core/checks.py @@ -122,6 +122,7 @@ async def predicate(ctx): ) return commands.check(predicate) + def updates_enabled(): """ A decorator that ensures From e8be5d1855eaa8c3d2131fca57b632255082ece0 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 3 Dec 2020 21:25:48 +0800 Subject: [PATCH 245/705] Support only serverv members intent --- CHANGELOG.md | 1 + bot.py | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf908d4bb8..34a2b416f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?fareply`, anonymously reply with variables. - `anonymous_snippets` config variable to toggle if snippets should be anonymous. ([GH #2905](https://github.com/kyb3r/modmail/issues/2905)) - `disable_updates` config variable to control if the update command should be disabled or not. +- Support for only the "Server Members" intent. ### Improved diff --git a/bot.py b/bot.py index e1955ff667..fa980fe5a3 100644 --- a/bot.py +++ b/bot.py @@ -192,9 +192,17 @@ def run(self, *args, **kwargs): except discord.LoginFailure: logger.critical("Invalid token") except discord.PrivilegedIntentsRequired: - logger.critical( - "Privileged intents are not explicitly granted in the discord developers dashboard." - ) + intents = discord.Intents.default() + intents.members = True + # Try again with members intent + super().__init__(command_prefix=None, intents=intents) # implemented in `get_prefix` + logger.warning("Attempting to login with only the server members privileged intent. Some plugins might not work correctly.") + try: + self.loop.run_until_complete(self.start(self.token)) + except discord.PrivilegedIntentsRequired: + logger.critical( + "Privileged intents are not explicitly granted in the discord developers dashboard." + ) except Exception: logger.critical("Fatal exception", exc_info=True) finally: From d922683283ab47206a5de761ddfd5560f225a4e7 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 3 Dec 2020 21:33:33 +0800 Subject: [PATCH 246/705] silent_alert_on_mention, resolve #2907 --- bot.py | 9 +++++++-- core/config.py | 2 ++ core/config_help.json | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/bot.py b/bot.py index fa980fe5a3..f51899127e 100644 --- a/bot.py +++ b/bot.py @@ -195,7 +195,7 @@ def run(self, *args, **kwargs): intents = discord.Intents.default() intents.members = True # Try again with members intent - super().__init__(command_prefix=None, intents=intents) # implemented in `get_prefix` + self._connection._intents = intents logger.warning("Attempting to login with only the server members privileged intent. Some plugins might not work correctly.") try: self.loop.run_until_complete(self.start(self.token)) @@ -1060,7 +1060,12 @@ async def on_message(self, message): ) if self.config["show_timestamp"]: em.timestamp = datetime.utcnow() - await self.mention_channel.send(content=self.config["mention"], embed=em) + + if not self.config["silent_alert_on_mention"]: + content = self.config["mention"] + else: + content = "" + await self.mention_channel.send(content=content, embed=em) await self.process_commands(message) diff --git a/core/config.py b/core/config.py index 6b827e74c0..2c88b10d14 100644 --- a/core/config.py +++ b/core/config.py @@ -79,6 +79,7 @@ class ConfigManager: "close_on_leave": False, "close_on_leave_reason": "The recipient has left the server.", "alert_on_mention": False, + "silent_alert_on_mention": False, "show_timestamp": True, "anonymous_snippets": False, # moderation @@ -168,6 +169,7 @@ class ConfigManager: "transfer_reactions", "close_on_leave", "alert_on_mention", + "silent_alert_on_mention", "show_timestamp", "confirm_thread_creation", "use_regex_autotrigger", diff --git a/core/config_help.json b/core/config_help.json index 506b9e57bd..e5fc4c6d17 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -662,12 +662,23 @@ }, "alert_on_mention": { "default": "No", - "description": "Mentions all mods (mention) in logs channel when bot is mentioned", + "description": "Mentions all mods (mention) in mention channel when bot is mentioned", "examples":[ "`{prefix}config set alert_on_mention yes`" ], "notes": [ - "See also: `mention`" + "See also: `mention`, `mention_channel_id`" + ] + }, + "silent_alert_on_mention": { + "default": "No", + "description": "Send a message in the mention channel without mentioning all mods (mention).", + "examples":[ + "`{prefix}config set alert_on_mention yes`" + ], + "notes": [ + "This has no effect unless `alert_on_mention` is set to yes.", + "See also: `mention`, `mention_channel_id`" ] }, "show_timestamp": { From a318aa43d12d9f8e8ceaa75c66aec45d00dc0f17 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 3 Dec 2020 21:35:57 +0800 Subject: [PATCH 247/705] Linting --- CHANGELOG.md | 3 ++- bot.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34a2b416f5..f9a7c8afe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.14-dev2 +# v3.7.14-dev3 ### Added @@ -14,6 +14,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?fareply`, anonymously reply with variables. - `anonymous_snippets` config variable to toggle if snippets should be anonymous. ([GH #2905](https://github.com/kyb3r/modmail/issues/2905)) - `disable_updates` config variable to control if the update command should be disabled or not. +- `silent_alert_on_mention` to alert mods silently. ([GH #2907](https://github.com/kyb3r/modmail/issues/2907)) - Support for only the "Server Members" intent. ### Improved diff --git a/bot.py b/bot.py index f51899127e..a920011205 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev2" +__version__ = "3.7.14-dev3" import asyncio @@ -196,7 +196,9 @@ def run(self, *args, **kwargs): intents.members = True # Try again with members intent self._connection._intents = intents - logger.warning("Attempting to login with only the server members privileged intent. Some plugins might not work correctly.") + logger.warning( + "Attempting to login with only the server members privileged intent. Some plugins might not work correctly." + ) try: self.loop.run_until_complete(self.start(self.token)) except discord.PrivilegedIntentsRequired: From 460758f9f364b1c416b12bc69a340beb41a4e7db Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Thu, 10 Dec 2020 00:07:34 +0800 Subject: [PATCH 248/705] use re.search not re.match in autotriggers --- CHANGELOG.md | 3 ++- bot.py | 6 +++--- cogs/utility.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9a7c8afe9..a4b3741dd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.14-dev3 +# v3.7.14-dev4 ### Added @@ -26,6 +26,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Mentioned `competing` as an activity type. ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) - Level permissions were not checked if command permissions were set. +- Regex autotriggers were not working if term was in the middle of strings. ### Internal diff --git a/bot.py b/bot.py index a920011205..c0388dcb3e 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev3" +__version__ = "3.7.14-dev4" import asyncio @@ -949,10 +949,10 @@ async def trigger_auto_triggers(self, message, channel, *, cls=commands.Context) if self.config.get("use_regex_autotrigger"): trigger = next( - filter(lambda x: re.match(x, message.content), self.auto_triggers.keys()) + filter(lambda x: re.search(x, message.content), self.auto_triggers.keys()) ) if trigger: - invoker = re.match(trigger, message.content).group(0) + invoker = re.search(trigger, message.content).group(0) else: trigger = next( filter(lambda x: x.lower() in message.content.lower(), self.auto_triggers.keys()) diff --git a/cogs/utility.py b/cogs/utility.py index 401f1aa37c..93fbc36ad8 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1829,7 +1829,7 @@ async def autotrigger_test(self, ctx, *, text): """Tests a string against the current autotrigger setup""" for keyword in self.bot.auto_triggers: if self.bot.config.get("use_regex_autotrigger"): - check = re.match(keyword, text) + check = re.search(keyword, text) regex = True else: check = keyword.lower() in text.lower() From b8a8f48dfe602202bf67fc7033aa3c17771ab40b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sun, 13 Dec 2020 20:51:53 +0800 Subject: [PATCH 249/705] Add anon snippets into config help --- bot.py | 2 +- core/config_help.json | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index c0388dcb3e..aacae88639 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev4" +__version__ = "3.7.14-dev5" import asyncio diff --git a/core/config_help.json b/core/config_help.json index e5fc4c6d17..e6bf3730ab 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -689,6 +689,16 @@ ], "notes": [] }, + "anonymous_snippets": { + "default": "No", + "description": "Sends snippets anonymously.", + "examples":[ + "`{prefix}config set anonymous_snippets yes`" + ], + "notes": [ + "See also: `anon_avatar_url`, `anon_tag`." + ] + }, "confirm_thread_creation": { "default": "No", "description": "Ensure users confirm that they want to create a new thread", From 6e62ce86b717dd5123baff9fec456c77b579c150 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 15 Dec 2020 16:10:42 +0800 Subject: [PATCH 250/705] add Berkand Karadere sponsor --- README.md | 5 +++++ SPONSORS.json | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e40426dd1..5741f1db6e 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,11 @@ Special thanks to our sponsors for supporting the project. + + + + + Become a sponsor on [Patreon](https://patreon.com/kyber). ## Plugins diff --git a/SPONSORS.json b/SPONSORS.json index ceed37be23..fcabb119ac 100644 --- a/SPONSORS.json +++ b/SPONSORS.json @@ -26,5 +26,21 @@ } ] } + }, + { + "embed": { + "title": "Berkand Karadere", + "description": "Berkand Karadere is an German Community Manager who integrated new systems into the game industry. He also is hosting and developing web servers and game servers. He also plays American Football for the Dortmund Giants and his journey has just begun.", + "color": 2968248, + "thumbnail": { + "url": "https://i.imgur.com/cs2QEcp.png" + }, + "fields": [ + { + "name": "Discord Server!", + "value": "[**Click here**](https://discord.gg/BanCwptMJV)" + } + ] + } } -] +] \ No newline at end of file From 7ac59e0d841c5bf81e43be667f234c9373c588a7 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Tue, 15 Dec 2020 23:59:33 +0800 Subject: [PATCH 251/705] `?blocked` now no longers show blocks that have expired. --- CHANGELOG.md | 1 + bot.py | 2 +- cogs/modmail.py | 53 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4b3741dd2..8e941cd863 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Mentioned `competing` as an activity type. ([PR #2902](https://github.com/kyb3r/modmail/pull/2902)) - Level permissions were not checked if command permissions were set. - Regex autotriggers were not working if term was in the middle of strings. +- `?blocked` now no longers show blocks that have expired. ### Internal diff --git a/bot.py b/bot.py index aacae88639..08a8cec02d 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev5" +__version__ = "3.7.14-dev6" import asyncio diff --git a/cogs/modmail.py b/cogs/modmail.py index 8ba509078c..29a3c79df4 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -1050,8 +1050,30 @@ async def blocked(self, ctx): roles = [] users = [] + now = ctx.message.created_at + + blocked_users = list(self.bot.blocked_users.items()) + for id_, reason in blocked_users: + # parse "reason" and check if block is expired + # etc "blah blah blah... until 2019-10-14T21:12:45.559948." + end_time = re.search(r"until ([^`]+?)\.$", reason) + if end_time is None: + # backwards compat + end_time = re.search(r"%([^%]+?)%", reason) + if end_time is not None: + logger.warning( + r"Deprecated time message for user %s, block and unblock again to update.", + id_, + ) + + if end_time is not None: + after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() + if after <= 0: + # No longer blocked + self.bot.blocked_users.pop(str(id_)) + logger.debug("No longer blocked, user %s.", id_) + continue - for id_, reason in self.bot.blocked_users.items(): user = self.bot.get_user(int(id_)) if user: users.append((user.mention, reason)) @@ -1062,7 +1084,28 @@ async def blocked(self, ctx): except discord.NotFound: users.append((id_, reason)) - for id_, reason in self.bot.blocked_roles.items(): + blocked_roles = list(self.bot.blocked_roles.items()) + for id_, reason in blocked_roles: + # parse "reason" and check if block is expired + # etc "blah blah blah... until 2019-10-14T21:12:45.559948." + end_time = re.search(r"until ([^`]+?)\.$", reason) + if end_time is None: + # backwards compat + end_time = re.search(r"%([^%]+?)%", reason) + if end_time is not None: + logger.warning( + r"Deprecated time message for role %s, block and unblock again to update.", + id_, + ) + + if end_time is not None: + after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() + if after <= 0: + # No longer blocked + self.bot.blocked_roles.pop(str(id_)) + logger.debug("No longer blocked, role %s.", id_) + continue + role = self.bot.guild.get_role(int(id_)) if role: roles.append((role.mention, reason)) @@ -1175,7 +1218,7 @@ async def block( after: UserFriendlyTime = None, ): """ - Block a user from using Modmail. + Block a user or role from using Modmail. You may choose to set a time as to when the user will automatically be unblocked. @@ -1190,9 +1233,9 @@ async def block( if thread: user_or_role = thread.recipient elif after is None: - raise commands.MissingRequiredArgument(SimpleNamespace(name="user")) + raise commands.MissingRequiredArgument(SimpleNamespace(name="user or role")) else: - raise commands.BadArgument(f'User "{after.arg}" not found.') + raise commands.BadArgument(f'User or role "{after.arg}" not found.') mention = getattr(user_or_role, "mention", f"`{user_or_role.id}`") From 450e341ad2010d70f765a40430ce584881f5c213 Mon Sep 17 00:00:00 2001 From: Matthew <57693543+XiehCanCode@users.noreply.github.com> Date: Tue, 22 Dec 2020 10:33:34 +0000 Subject: [PATCH 252/705] fix typo --- PRIVACY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVACY.md b/PRIVACY.md index ebe5ce6954..b4283e3660 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -81,7 +81,7 @@ The Modmail team does not track any data by users. ### Opting out -There is no way for users or moderators to opt out frmo this data collection. +There is no way for users or moderators to opt out from this data collection. ### Data deletion From b0df2b3ccde968e9c6a2af0932e6d69f49fb2d50 Mon Sep 17 00:00:00 2001 From: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Date: Wed, 23 Dec 2020 22:19:46 +0100 Subject: [PATCH 253/705] Update utility.py (#2918) Change of domain for hastebin, old domain forwards to a different site now --- cogs/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utility.py b/cogs/utility.py index 03a90efe54..634ca71de9 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -441,7 +441,7 @@ async def debug(self, ctx): async def debug_hastebin(self, ctx): """Posts application-logs to Hastebin.""" - haste_url = os.environ.get("HASTE_URL", "https://hasteb.in") + haste_url = os.environ.get("HASTE_URL", "https://hastebin.cc") log_file_name = self.bot.token.split(".")[0] with open( From b33812159240f9e81bf899b9bc794bfce1b13478 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 2 Jan 2021 23:05:42 +0800 Subject: [PATCH 254/705] Blocked roles will no longer trigger an error during unblock --- CHANGELOG.md | 1 + bot.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e941cd863..f152053862 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Level permissions were not checked if command permissions were set. - Regex autotriggers were not working if term was in the middle of strings. - `?blocked` now no longers show blocks that have expired. +- Blocked roles will no longer trigger an error during unblock ### Internal diff --git a/bot.py b/bot.py index 08a8cec02d..623228bb19 100644 --- a/bot.py +++ b/bot.py @@ -673,18 +673,18 @@ def check_manual_blocked_roles(self, author: discord.Member) -> bool: end_time = re.search(r"%([^%]+?)%", blocked_reason) if end_time is not None: logger.warning( - r"Deprecated time message for user %s, block and unblock again to update.", - author.name, + r"Deprecated time message for role %s, block and unblock again to update.", + r.name, ) if end_time is not None: after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds() if after <= 0: # No longer blocked - self.blocked_users.pop(str(author.id)) - logger.debug("No longer blocked, user %s.", author.name) + self.blocked_roles.pop(str(r.id)) + logger.debug("No longer blocked, role %s.", r.name) return True - logger.debug("User blocked, user %s.", author.name) + logger.debug("User blocked, role %s.", r.name) return False return True From e31b07dda3e1a35e51c8f3d49c191acee7bd67d2 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 2 Jan 2021 23:10:11 +0800 Subject: [PATCH 255/705] Fix custom emojis in confirm_thread_creation_deny, resolves #2916 --- CHANGELOG.md | 3 ++- core/thread.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f152053862..48365b7701 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,8 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Level permissions were not checked if command permissions were set. - Regex autotriggers were not working if term was in the middle of strings. - `?blocked` now no longers show blocks that have expired. -- Blocked roles will no longer trigger an error during unblock +- Blocked roles will no longer trigger an error during unblock. +- Custom emojis are now supported in `confirm_thread_creation_deny`. ([GH #2916](https://github.com/kyb3r/modmail/issues/2916)) ### Internal diff --git a/core/thread.py b/core/thread.py index 5e1c28f15f..b1248bd738 100644 --- a/core/thread.py +++ b/core/thread.py @@ -1201,7 +1201,7 @@ async def create( del self.cache[recipient.id] return thread else: - if r.emoji == deny_emoji: + if str(r.emoji) == deny_emoji: thread.cancelled = True await confirm.remove_reaction(accept_emoji, self.bot.user) From 99c3c99095b3beb09525c501ea7a006f59a16cfd Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 2 Jan 2021 23:14:11 +0800 Subject: [PATCH 256/705] Finding linked messages in replies work now, resolves #2920 --- CHANGELOG.md | 1 + core/thread.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48365b7701..835ab48e02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - `?blocked` now no longers show blocks that have expired. - Blocked roles will no longer trigger an error during unblock. - Custom emojis are now supported in `confirm_thread_creation_deny`. ([GH #2916](https://github.com/kyb3r/modmail/issues/2916)) +- Finding linked messages in replies work now. ([GH #2920](https://github.com/kyb3r/modmail/issues/2920), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2920#issuecomment-751530495)) ### Internal diff --git a/core/thread.py b/core/thread.py index b1248bd738..adb122dd79 100644 --- a/core/thread.py +++ b/core/thread.py @@ -660,8 +660,10 @@ async def delete_message( async def find_linked_message_from_dm(self, message, either_direction=False): if either_direction and message.embeds: compare_url = message.embeds[0].author.url + compare_id = compare_url.split('#')[-1] else: compare_url = None + compare_id = None if self.channel is not None: async for linked_message in self.channel.history(): @@ -679,6 +681,11 @@ async def find_linked_message_from_dm(self, message, either_direction=False): msg_id = int(msg_id) if int(msg_id) == message.id: return linked_message + + if compare_id is not None and compare_id.isdigit(): + if int(msg_id) == int (compare_id): + return linked_message + raise ValueError("Thread channel message not found.") async def edit_dm_message(self, message: discord.Message, content: str) -> None: From 1b24283e674e2fbf6abf9e4880e572b92a31df4b Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 2 Jan 2021 23:21:20 +0800 Subject: [PATCH 257/705] Up version to v3.8-dev7 --- CHANGELOG.md | 2 +- bot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 835ab48e02..ab29f6922d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.7.14-dev4 +# v3.8.0-dev7 ### Added diff --git a/bot.py b/bot.py index 623228bb19..fdd348e269 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.7.14-dev6" +__version__ = "3.8.0-dev7" import asyncio From 528dcdbcfca681a76c45fc293425c584cd83595d Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sat, 2 Jan 2021 23:29:58 +0800 Subject: [PATCH 258/705] Linting --- core/thread.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/thread.py b/core/thread.py index adb122dd79..71acdb8610 100644 --- a/core/thread.py +++ b/core/thread.py @@ -660,7 +660,7 @@ async def delete_message( async def find_linked_message_from_dm(self, message, either_direction=False): if either_direction and message.embeds: compare_url = message.embeds[0].author.url - compare_id = compare_url.split('#')[-1] + compare_id = compare_url.split("#")[-1] else: compare_url = None compare_id = None @@ -683,7 +683,7 @@ async def find_linked_message_from_dm(self, message, either_direction=False): return linked_message if compare_id is not None and compare_id.isdigit(): - if int(msg_id) == int (compare_id): + if int(msg_id) == int(compare_id): return linked_message raise ValueError("Thread channel message not found.") From fe114483e7d1069ebe76be2cad51d56f9175fad7 Mon Sep 17 00:00:00 2001 From: fourjr <28086837+fourjr@users.noreply.github.com> Date: Sun, 3 Jan 2021 00:02:07 +0800 Subject: [PATCH 259/705] Fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab29f6922d..dc5893f651 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s ### Internal -- Make use of `git branch --show-current` to retrieve branch insteasd of using prerelease version check. +- Make use of `git branch --show-current` to retrieve branch instead of using prerelease version check. # v3.7.13 From c2b75dcaf17cad274828e862b86f421c2307d146 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 6 Jan 2021 21:12:12 +0800 Subject: [PATCH 260/705] Clearer error messages on reply fails. --- CHANGELOG.md | 1 + core/thread.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc5893f651..7b736a69ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Added command validation to `autotrigger add/edit`. - `GITHUB_TOKEN` is now no longer required in Heroku setups. +- Clearer error messages on reply fails. ### Fixed diff --git a/core/thread.py b/core/thread.py index 71acdb8610..c3918b2daa 100644 --- a/core/thread.py +++ b/core/thread.py @@ -747,16 +747,21 @@ async def reply( anonymous=anonymous, plain=plain, ) - except Exception: + except Exception as e: logger.error("Message delivery failed:", exc_info=True) + if isinstance(e, discord.Forbidden): + description = ("Your message could not be delivered as " + "the recipient is only accepting direct " + "messages from friends, or the bot was " + "blocked by the recipient.") + else: + description = ("Your message could not be delivered due " + "to an unknown error. ") tasks.append( message.channel.send( embed=discord.Embed( color=self.bot.error_color, - description="Your message could not be delivered as " - "the recipient is only accepting direct " - "messages from friends, or the bot was " - "blocked by the recipient.", + description=description, ) ) ) From a6ebd81d3fa40f713b2da188bc7a74fa47db8bcb Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 6 Jan 2021 21:18:14 +0800 Subject: [PATCH 261/705] Sending files in threads (non-images) now work. resolves #2926 --- CHANGELOG.md | 1 + core/thread.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b736a69ee..70109c97a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Blocked roles will no longer trigger an error during unblock. - Custom emojis are now supported in `confirm_thread_creation_deny`. ([GH #2916](https://github.com/kyb3r/modmail/issues/2916)) - Finding linked messages in replies work now. ([GH #2920](https://github.com/kyb3r/modmail/issues/2920), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2920#issuecomment-751530495)) +- Sending files in threads (non-images) now work. ([GH #2926](https://github.com/kyb3r/modmail/issues/2926)) ### Internal diff --git a/core/thread.py b/core/thread.py index c3918b2daa..041a601c21 100644 --- a/core/thread.py +++ b/core/thread.py @@ -756,7 +756,8 @@ async def reply( "blocked by the recipient.") else: description = ("Your message could not be delivered due " - "to an unknown error. ") + "to an unknown error. Check `?debug` for " + "more information") tasks.append( message.channel.send( embed=discord.Embed( @@ -933,7 +934,7 @@ async def send( file_upload_count = 1 - for url, filename in attachments: + for url, filename, _ in attachments: embed.add_field( name=f"File upload ({file_upload_count})", value=f"[{filename}]({url})" ) From beb73d8d82960429631c0aef5aea31f4f75f23b1 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 6 Jan 2021 21:24:18 +0800 Subject: [PATCH 262/705] Deleting messages no longer shows a false error, resolves #2910 --- CHANGELOG.md | 1 + core/thread.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70109c97a6..404869adae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Custom emojis are now supported in `confirm_thread_creation_deny`. ([GH #2916](https://github.com/kyb3r/modmail/issues/2916)) - Finding linked messages in replies work now. ([GH #2920](https://github.com/kyb3r/modmail/issues/2920), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2920#issuecomment-751530495)) - Sending files in threads (non-images) now work. ([GH #2926](https://github.com/kyb3r/modmail/issues/2926)) +- Deleting messages no longer shows a false error. ([GH #2910](https://github.com/kyb3r/modmail/issues/2910), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2910#issuecomment-753557313)) ### Internal diff --git a/core/thread.py b/core/thread.py index 041a601c21..5f630654fe 100644 --- a/core/thread.py +++ b/core/thread.py @@ -650,7 +650,7 @@ async def delete_message( tasks = [] if not isinstance(message, discord.Message): tasks += [message1.delete()] - if message2 is not None: + elif message2 is not None: tasks += [message2.delete()] elif message1.embeds[0].author.name.startswith("Persistent Note"): tasks += [self.bot.api.delete_note(message1.id)] From 1de48fd617996846ae7b776f59e03c287ded1846 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Wed, 6 Jan 2021 21:27:56 +0800 Subject: [PATCH 263/705] Linting --- core/changelog.py | 2 +- core/checks.py | 2 +- core/thread.py | 23 ++++++++++++----------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/core/changelog.py b/core/changelog.py index 163aa0f340..ada9fe6984 100644 --- a/core/changelog.py +++ b/core/changelog.py @@ -91,7 +91,7 @@ def embed(self) -> Embed: """ embed = Embed(color=self.bot.main_color, description=self.description) embed.set_author( - name=f"v{self.version} - Changelog", icon_url=self.bot.user.avatar_url, url=self.url + name=f"v{self.version} - Changelog", icon_url=self.bot.user.avatar_url, url=self.url, ) for name, value in self.fields.items(): diff --git a/core/checks.py b/core/checks.py index 55eb4d4ea8..74b7dc38cd 100644 --- a/core/checks.py +++ b/core/checks.py @@ -5,7 +5,7 @@ logger = getLogger(__name__) -def has_permissions_predicate(permission_level: PermissionLevel = PermissionLevel.REGULAR): +def has_permissions_predicate(permission_level: PermissionLevel = PermissionLevel.REGULAR,): async def predicate(ctx): return await check_permissions(ctx, ctx.command.qualified_name) diff --git a/core/thread.py b/core/thread.py index 5f630654fe..6480160e8b 100644 --- a/core/thread.py +++ b/core/thread.py @@ -750,20 +750,21 @@ async def reply( except Exception as e: logger.error("Message delivery failed:", exc_info=True) if isinstance(e, discord.Forbidden): - description = ("Your message could not be delivered as " - "the recipient is only accepting direct " - "messages from friends, or the bot was " - "blocked by the recipient.") + description = ( + "Your message could not be delivered as " + "the recipient is only accepting direct " + "messages from friends, or the bot was " + "blocked by the recipient." + ) else: - description = ("Your message could not be delivered due " - "to an unknown error. Check `?debug` for " - "more information") + description = ( + "Your message could not be delivered due " + "to an unknown error. Check `?debug` for " + "more information" + ) tasks.append( message.channel.send( - embed=discord.Embed( - color=self.bot.error_color, - description=description, - ) + embed=discord.Embed(color=self.bot.error_color, description=description,) ) ) else: From 6cb26a70dd264edcef95205b0661774df8ba4311 Mon Sep 17 00:00:00 2001 From: Jerrie-Aries <70805800+Jerrie-Aries@users.noreply.github.com> Date: Thu, 7 Jan 2021 12:02:37 +0800 Subject: [PATCH 264/705] Fix `?perms get` command showing IDs instead of user or role mentions. --- cogs/utility.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cogs/utility.py b/cogs/utility.py index 93fbc36ad8..c8a0011a33 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1453,15 +1453,15 @@ def _get_perm(self, ctx, name, type_): if perm == -1: values.insert(0, "**everyone**") continue - member = ctx.guild.get_member(perm) + member = ctx.guild.get_member(int(perm)) if member is not None: values.append(member.mention) continue - user = self.bot.get_user(perm) + user = self.bot.get_user(int(perm)) if user is not None: values.append(user.mention) continue - role = ctx.guild.get_role(perm) + role = ctx.guild.get_role(int(perm)) if role is not None: values.append(role.mention) else: From baf9a5b7044c9530cfd45412e277ff08ebfeb974 Mon Sep 17 00:00:00 2001 From: Jia Rong Yee <28086837+fourjr@users.noreply.github.com> Date: Fri, 8 Jan 2021 16:18:30 +0800 Subject: [PATCH 265/705] Support discord.py v1.6 & LOTTIE stickers --- CHANGELOG.md | 4 +- Pipfile | 2 +- Pipfile.lock | 350 ++++++++++++++++++++++------------------ bot.py | 4 +- core/thread.py | 24 ++- discord.py-1.5.2.tar.gz | Bin 649426 -> 0 bytes 6 files changed, 217 insertions(+), 167 deletions(-) delete mode 100644 discord.py-1.5.2.tar.gz diff --git a/CHANGELOG.md b/CHANGELOG.md index 404869adae..bbc9a029b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/kyb3r/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. -# v3.8.0-dev7 +# v3.8.0-dev8 ### Added @@ -34,10 +34,12 @@ however, insignificant breaking changes do not guarantee a major version bump, s - Finding linked messages in replies work now. ([GH #2920](https://github.com/kyb3r/modmail/issues/2920), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2920#issuecomment-751530495)) - Sending files in threads (non-images) now work. ([GH #2926](https://github.com/kyb3r/modmail/issues/2926)) - Deleting messages no longer shows a false error. ([GH #2910](https://github.com/kyb3r/modmail/issues/2910), [Jerrie-Aries](https://github.com/kyb3r/modmail/issues/2910#issuecomment-753557313)) +- Display an error on [Lottie](https://airbnb.io/lottie/#/) stickers, instead of failing the send. ### Internal - Make use of `git branch --show-current` to retrieve branch instead of using prerelease version check. +- Use discord.py 1.6.0 from PyPi instead of the development clone. # v3.7.13 diff --git a/Pipfile b/Pipfile index b878d053e9..f9621c3493 100644 --- a/Pipfile +++ b/Pipfile @@ -27,7 +27,7 @@ parsedatetime = "==2.6" aiohttp = ">=3.6.0,<3.7.0" python-dotenv = ">=0.10.3" pipenv = "*" -"discord.py" = {file = "./discord.py-1.5.2.tar.gz"} +"discord.py" = "==1.6.0" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index 0eacd81d2c..aaa491011e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "1f660c7237deeaa50a7098002c0f3c05cce254d6c0ba8bc02993c5400e335a59" + "sha256": "bfe06c9fe1db25178b01413114093b26f0d32e9a90a031c048ff3ddc7b6644b7" }, "pipfile-spec": 6, "requires": {}, @@ -50,6 +50,7 @@ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], + "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { @@ -57,14 +58,15 @@ "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "certifi": { "hashes": [ - "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd", - "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4" + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" ], - "version": "==2020.11.8" + "version": "==2020.12.5" }, "chardet": { "hashes": [ @@ -82,7 +84,12 @@ "version": "==0.4.4" }, "discord.py": { - "file": "./discord.py-1.5.2.tar.gz" + "hashes": [ + "sha256:3df148daf6fbcc7ab5b11042368a3cd5f7b730b62f09fb5d3cbceff59bcfbb12", + "sha256:ba8be99ff1b8c616f7b6dcb700460d0222b29d4c11048e74366954c465fdd05f" + ], + "index": "pypi", + "version": "==1.6.0" }, "distlib": { "hashes": [ @@ -115,10 +122,11 @@ }, "idna": { "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16", + "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1" ], - "version": "==2.10" + "markers": "python_version >= '3.4'", + "version": "==3.1" }, "isodate": { "hashes": [ @@ -156,6 +164,7 @@ "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" ], + "markers": "python_version >= '3.5'", "version": "==4.7.6" }, "natural": { @@ -175,70 +184,80 @@ }, "pipenv": { "hashes": [ - "sha256:d6ac39d1721517b23aca12cdb4c726dc318ec4d7bdede5c1220bbb81775005c3", - "sha256:dce1fb1a6941f98764c62b00010f52143aed19e2fcd8f100aff4fb3bb1bbbbe3" + "sha256:4ab2f60742184d851ac44b9e1d423afe71dc2ea7a68bde07eb890c8b4ce5a420", + "sha256:8253fe6f9cfb3791a54da8a0571f73c918cb3457dd908684c1800a13a06ec4c1" ], "index": "pypi", - "version": "==2020.11.4" + "version": "==2020.11.15" }, "pymongo": { "hashes": [ - "sha256:03dc64a9aa7a5d405aea5c56db95835f6a2fa31b3502c5af1760e0e99210be30", - "sha256:05fcc6f9c60e6efe5219fbb5a30258adb3d3e5cbd317068f3d73c09727f2abb6", - "sha256:076a7f2f7c251635cf6116ac8e45eefac77758ee5a77ab7bd2f63999e957613b", - "sha256:137e6fa718c7eff270dbd2fc4b90d94b1a69c9e9eb3f3de9e850a7fd33c822dc", - "sha256:1f865b1d1c191d785106f54df9abdc7d2f45a946b45fd1ea0a641b4f982a2a77", - "sha256:213c445fe7e654621c6309e874627c35354b46ef3ee807f5a1927dc4b30e1a67", - "sha256:25e617daf47d8dfd4e152c880cd0741cbdb48e51f54b8de9ddbfe74ecd87dd16", - "sha256:3d9bb1ba935a90ec4809a8031efd988bdb13cdba05d9e9a3e9bf151bf759ecde", - "sha256:40696a9a53faa7d85aaa6fd7bef1cae08f7882640bad08c350fb59dee7ad069b", - "sha256:421aa1b92c291c429668bd8d8d8ec2bd00f183483a756928e3afbf2b6f941f00", - "sha256:4437300eb3a5e9cc1a73b07d22c77302f872f339caca97e9bf8cf45eca8fa0d2", - "sha256:455f4deb00158d5ec8b1d3092df6abb681b225774ab8a59b3510293b4c8530e3", - "sha256:475a34a0745c456ceffaec4ce86b7e0983478f1b6140890dff7b161e7bcd895b", - "sha256:4797c0080f41eba90404335e5ded3aa66731d303293a675ff097ce4ea3025bb9", - "sha256:4ae23fbbe9eadf61279a26eba866bbf161a6f7e2ffad14a42cf20e9cb8e94166", - "sha256:4b32744901ee9990aa8cd488ec85634f443526def1e5190a407dc107148249d7", - "sha256:50127b13b38e8e586d5e97d342689405edbd74ad0bd891d97ee126a8c7b6e45f", - "sha256:50531caa7b4be1c4ed5e2d5793a4e51cc9bd62a919a6fd3299ef7c902e206eab", - "sha256:63a5387e496a98170ffe638b435c0832c0f2011a6f4ff7a2880f17669fff8c03", - "sha256:68220b81850de8e966d4667d5c325a96c6ac0d6adb3d18935d6e3d325d441f48", - "sha256:689142dc0c150e9cb7c012d84cac2c346d40beb891323afb6caf18ec4caafae0", - "sha256:6a15e2bee5c4188369a87ed6f02de804651152634a46cca91966a11c8abd2550", - "sha256:7122ffe597b531fb065d3314e704a6fe152b81820ca5f38543e70ffcc95ecfd4", - "sha256:7307024b18266b302f4265da84bb1effb5d18999ef35b30d17592959568d5c0a", - "sha256:7a4a6f5b818988a3917ec4baa91d1143242bdfece8d38305020463955961266a", - "sha256:83c5a3ecd96a9f3f11cfe6dfcbcec7323265340eb24cc996acaecea129865a3a", - "sha256:890b0f1e18dbd898aeb0ab9eae1ab159c6bcbe87f0abb065b0044581d8614062", - "sha256:8deda1f7b4c03242f2a8037706d9584e703f3d8c74d6d9cac5833db36fe16c42", - "sha256:8ea13d0348b4c96b437d944d7068d59ed4a6c98aaa6c40d8537a2981313f1c66", - "sha256:91e96bf85b7c07c827d339a386e8a3cf2e90ef098c42595227f729922d0851df", - "sha256:96782ebb3c9e91e174c333208b272ea144ed2a684413afb1038e3b3342230d72", - "sha256:9755c726aa6788f076114dfdc03b92b03ff8860316cca00902cce88bcdb5fedd", - "sha256:9dbab90c348c512e03f146e93a5e2610acec76df391043ecd46b6b775d5397e6", - "sha256:9ee0eef254e340cc11c379f797af3977992a7f2c176f1a658740c94bf677e13c", - "sha256:9fc17fdac8f1973850d42e51e8ba6149d93b1993ed6768a24f352f926dd3d587", - "sha256:a2787319dc69854acdfd6452e6a8ba8f929aeb20843c7f090e04159fc18e6245", - "sha256:b7c522292407fa04d8195032493aac937e253ad9ae524aab43b9d9d242571f03", - "sha256:bd312794f51e37dcf77f013d40650fe4fbb211dd55ef2863839c37480bd44369", - "sha256:c0d660a186e36c526366edf8a64391874fe53cf8b7039224137aee0163c046df", - "sha256:c4869141e20769b65d2d72686e7a7eb141ce9f3168106bed3e7dcced54eb2422", - "sha256:cc4057f692ac35bbe82a0a908d42ce3a281c9e913290fac37d7fa3bd01307dfb", - "sha256:cccf1e7806f12300e3a3b48f219e111000c2538483e85c869c35c1ae591e6ce9", - "sha256:ce208f80f398522e49d9db789065c8ad2cd37b21bd6b23d30053474b7416af11", - "sha256:d0565481dc196986c484a7fb13214fc6402201f7fb55c65fd215b3324962fe6c", - "sha256:d1b3366329c45a474b3bbc9b9c95d4c686e03f35da7fd12bc144626d1f2a7c04", - "sha256:d226e0d4b9192d95079a9a29c04dd81816b1ce8903b8c174a39224fe978547cb", - "sha256:d38b35f6eef4237b1d0d8e845fc1546dad85c55eba447e28c211da8c7ef9697c", - "sha256:d64c98277ea80e4484f1332ab107e8dfd173a7dcf1bdbf10a9cccc97aaab145f", - "sha256:d9de8427a5601799784eb0e7fa1b031aa64086ce04de29df775a8ca37eedac41", - "sha256:e6a15cf8f887d9f578dd49c6fb3a99d53e1d922fdd67a245a67488d77bf56eb2", - "sha256:e8c446882cbb3774cd78c738c9f58220606b702b7c1655f1423357dc51674054", - "sha256:e8d188ee39bd0ffe76603da887706e4e7b471f613625899ddf1e27867dc6a0d3", - "sha256:ef76535776c0708a85258f6dc51d36a2df12633c735f6d197ed7dfcaa7449b99", - "sha256:f6efca006a81e1197b925a7d7b16b8f61980697bb6746587aad8842865233218" - ], - "version": "==3.11.0" + "sha256:019ddf7ced8e42cc6c8c608927c799be8097237596c94ffe551f6ef70e55237e", + "sha256:047c325c4a96e7be7d11acf58639bcf71a81ca212d9c6590e3369bc28678647a", + "sha256:047cc2007b280672ddfdf2e7b862aad8d898f481f65bbc9067bfa4e420a019a9", + "sha256:061d59f525831c4051af0b6dbafa62b0b8b168d4ef5b6e3c46d0811b8499d100", + "sha256:082832a59da18efab4d9148cca396451bac99da9757f31767f706e828b5b8500", + "sha256:0a53a751d977ad02f1bd22ddb6288bb4816c4758f44a50225462aeeae9cbf6a0", + "sha256:1222025db539641071a1b67f6950f65a6342a39db5b454bf306abd6954f1ad8a", + "sha256:1580fad512c678b720784e5c9018621b1b3bd37fb5b1633e874738862d6435c7", + "sha256:202ea1d4edc8a5439fc179802d807b49e7e563207fea5610779e56674ac770c6", + "sha256:21d7b48567a1c80f9266e0ab61c1218a31279d911da345679188733e354f81cc", + "sha256:264843ce2af0640994a4331148ef5312989bc004678c457460758766c9b4decc", + "sha256:270a1f6a331eac3a393090af06df68297cb31a8b2df0bdcbd97dc613c5758e78", + "sha256:29a6840c2ac778010547cad5870f3db2e080ad7fad01197b07fff993c08692c8", + "sha256:3646c2286d889618d43e01d9810ac1fc17709d2b4dec61366df5edc8ba228b3e", + "sha256:36b9b98a39565a8f33803c81569442b35e749a72fb1aa7d0bcdb1a33052f8bcc", + "sha256:3ec8f8e106a1476659d8c020228b45614daabdbdb6c6454a843a1d4f77d13339", + "sha256:422069f2cebf58c9dd9e8040b4768f7be4f228c95bc4505e8fa8e7b4f7191ad8", + "sha256:44376a657717de8847d5d71a9305f3595c7e78c91ac77edbb87058d12ede87a6", + "sha256:45728e6aae3023afb5b2829586d1d2bfd9f0d71cfd7d3c924b71a5e9aef617a8", + "sha256:46792b71ab802d9caf1fc9d52e83399ef8e1a36e91eef4d827c06e36b8df2230", + "sha256:4942a5659ae927bb764a123a6409870ca5dd572d83b3bfb71412c9a191bbf792", + "sha256:4be4fe9d18523da98deeb0b554ac76e1dc1562ee879d62572b34dda8593efcc1", + "sha256:523804bd8fcb5255508052b50073a27c701b90a73ea46e29be46dad5fe01bde6", + "sha256:540dafd6f4a0590fc966465c726b80fa7c0804490c39786ef29236fe68c94401", + "sha256:5980509801cbd2942df31714d055d89863684b4de26829c349362e610a48694e", + "sha256:5ad7b96c27acd7e256b33f47cf3d23bd7dd902f9c033ae43f32ffcbc37bebafd", + "sha256:6122470dfa61d4909b75c98012c1577404ba4ab860d0095e0c6980560cb3711f", + "sha256:6175fd105da74a09adb38f93be96e1f64873294c906e5e722cbbc5bd10c44e3b", + "sha256:646d4d30c5aa7c0ddbfe9b990f0f77a88621024a21ad0b792bd9d58caa9611f0", + "sha256:6700e251c6396cc05d7460dc05ef8e19e60a7b53b62c007725b48e123aaa2b1c", + "sha256:6aac7e0e8de92f11a410eb68c24a2decbac6f094e82fd95d22546d0168e7a18b", + "sha256:6e7a6057481a644970e43475292e1c0af095ca39a20fe83781196bd6e6690a38", + "sha256:76579fcf77052b39796fe4a11818d1289dd48cffe15951b3403288fa163c29f6", + "sha256:7e69fa025a1db189443428f345fea5555d16413df6addc056e17bb8c9794b006", + "sha256:7f0c507e1f108790840d6c4b594019ebf595025c324c9f7e9c9b2b15b41f884e", + "sha256:813db97e9955b6b1b50b5cebd18cb148580603bb9b067ea4c5cc656b333bc906", + "sha256:82d5ded5834b6c92380847860eb28dcaf20b847a27cee5811c4aaceef87fd280", + "sha256:82f6e42ba40440a7e0a20bfe12465a3b62d65966a4c7ad1a21b36ffff88de6fe", + "sha256:8d669c720891781e7c82d412cad39f9730ef277e3957b48a3344dae47d3caa03", + "sha256:944ed467feb949e103555863fa934fb84216a096b0004ca364d3ddf9d18e2b9e", + "sha256:96c6aef7ffb0d37206c0342abb82d874fa8cdc344267277ec63f562b94335c22", + "sha256:9be785bd4e1ba0148fb00ca84e4dbfbd1c74df3af3a648559adc60b0782f34de", + "sha256:9d19843568df9d263dc92ae4cc2279879add8a26996473f9155590cac635b321", + "sha256:a118a1df7280ffab7fe0f3eab325868339ff1c4d5b8e0750db0f0a796da8f849", + "sha256:b4294ddf76452459433ecfa6a93258608b5e462c76ef15e4695ed5e2762f009f", + "sha256:b50af6701b4a5288b77fb4db44a363aa9485caf2c3e7a40c0373fd45e34440af", + "sha256:b875bb4b438931dce550e170bfb558597189b8d0160f4ac60f14a21955161699", + "sha256:b95d2c2829b5956bf54d9a22ffec911dea75abf0f0f7e0a8a57423434bfbde91", + "sha256:c046e09e886f4539f8626afba17fa8f2e6552731f9384e2827154e3e3b7fda4e", + "sha256:c1d1992bbdf363b22b5a9543ab7d7c6f27a1498826d50d91319b803ddcf1142e", + "sha256:c2b67881392a9e85aa108e75f62cdbe372d5a3f17ea5f8d3436dcf4662052f14", + "sha256:c6cf288c9e03195d8e12b72a6388b32f18a5e9c2545622417a963e428e1fe496", + "sha256:c812b6e53344e92f10f12235219fb769c491a4a87a02c9c3f93fe632e493bda8", + "sha256:cc421babc687dc52ce0fc19787b2404518ca749d9db59576100946ff886f38ed", + "sha256:ce53c00be204ec4428d3c1f3c478ae89d388efec575544c27f57b61e9fa4a7f2", + "sha256:ce9964c117cbe5cf6269f30a2b334d28675956e988b7dbd0b4f7370924afda2e", + "sha256:d6f82e86896a8db70e8ae8fa4b7556a0f188f1d8a6c53b2ba229889d55a59308", + "sha256:d9d3ae537f61011191b2fd6f8527b9f9f8a848b37d4c85a0f7bb28004c42b546", + "sha256:e565d1e4388765c135052717f15f9e0314f9d172062444c6b3fc0002e93ed04b", + "sha256:ed98683d8f01f1c46ef2d02469e04e9a8fe9a73a9741a4e6e66677a73b59bec8", + "sha256:ef18aa15b1aa18c42933deed5233b3284186e9ed85c25d2704ceff5099a3964c", + "sha256:fa741e9c805567239f845c7e9a016aff797f9bb02ff9bc8ccd2fbd9eafefedd4", + "sha256:fc4946acb6cdada08f60aca103b61334995523da65be5fe816ea8571c9967d46", + "sha256:fcc66d17a3363b7bd6d2655de8706e25a3cd1be2bd1b8e8d8a5c504a6ef893ae" + ], + "version": "==3.11.2" }, "python-dateutil": { "hashes": [ @@ -261,6 +280,7 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "uvloop": { @@ -275,22 +295,23 @@ "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95", "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362" ], - "index": "pypi", "markers": "sys_platform != 'win32'", "version": "==0.14.0" }, "virtualenv": { "hashes": [ - "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2", - "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380" + "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c", + "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b" ], - "version": "==20.1.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.2.2" }, "virtualenv-clone": { "hashes": [ "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.5.4" }, "yarl": { @@ -313,6 +334,7 @@ "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" ], + "markers": "python_version >= '3.5'", "version": "==1.5.1" } }, @@ -329,6 +351,7 @@ "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" ], + "markers": "python_version >= '3.5'", "version": "==2.4.2" }, "attrs": { @@ -336,6 +359,7 @@ "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "bandit": { @@ -359,6 +383,7 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "colorama": { @@ -382,21 +407,24 @@ "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], + "markers": "python_version >= '3.4'", "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b", - "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8" + "sha256:42dbefd8d9e2576c496ed0059f3103dcef7125b9ce16f9d5f9c834aed44a1dac", + "sha256:867ec3dfb126aac0f8296b19fb63b8c4a399f32b4b6fafe84c4b10af5fa9f7b5" ], - "version": "==3.1.11" + "markers": "python_version >= '3.4'", + "version": "==3.1.12" }, "isort": { "hashes": [ - "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7", - "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58" + "sha256:c729845434366216d320e936b8ad6f9d681aab72dc7cbc2d51bedc3582f3ad1e", + "sha256:fff4f0c04e1825522ce6949973e83110a6e907750cd92d128b0d14aaaadbffdc" ], - "version": "==5.6.4" + "markers": "python_version >= '3.6' and python_version < '4.0'", + "version": "==5.7.0" }, "lazy-object-proxy": { "hashes": [ @@ -422,6 +450,7 @@ "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.3" }, "mccabe": { @@ -443,6 +472,7 @@ "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9", "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00" ], + "markers": "python_version >= '2.6'", "version": "==5.5.1" }, "pycodestyle": { @@ -450,6 +480,7 @@ "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.6.0" }, "pyflakes": { @@ -457,6 +488,7 @@ "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.2.0" }, "pylint": { @@ -472,11 +504,13 @@ "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", + "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e", "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" @@ -485,57 +519,56 @@ }, "regex": { "hashes": [ - "sha256:03855ee22980c3e4863dc84c42d6d2901133362db5daf4c36b710dd895d78f0a", - "sha256:06b52815d4ad38d6524666e0d50fe9173533c9cc145a5779b89733284e6f688f", - "sha256:11116d424734fe356d8777f89d625f0df783251ada95d6261b4c36ad27a394bb", - "sha256:119e0355dbdd4cf593b17f2fc5dbd4aec2b8899d0057e4957ba92f941f704bf5", - "sha256:127a9e0c0d91af572fbb9e56d00a504dbd4c65e574ddda3d45b55722462210de", - "sha256:1ec66700a10e3c75f1f92cbde36cca0d3aaee4c73dfa26699495a3a30b09093c", - "sha256:227a8d2e5282c2b8346e7f68aa759e0331a0b4a890b55a5cfbb28bd0261b84c0", - "sha256:2564def9ce0710d510b1fc7e5178ce2d20f75571f788b5197b3c8134c366f50c", - "sha256:297116e79074ec2a2f885d22db00ce6e88b15f75162c5e8b38f66ea734e73c64", - "sha256:2dc522e25e57e88b4980d2bdd334825dbf6fa55f28a922fc3bfa60cc09e5ef53", - "sha256:3a5f08039eee9ea195a89e180c5762bfb55258bfb9abb61a20d3abee3b37fd12", - "sha256:3dfca201fa6b326239e1bccb00b915e058707028809b8ecc0cf6819ad233a740", - "sha256:49461446b783945597c4076aea3f49aee4b4ce922bd241e4fcf62a3e7c61794c", - "sha256:4afa350f162551cf402bfa3cd8302165c8e03e689c897d185f16a167328cc6dd", - "sha256:4b5a9bcb56cc146c3932c648603b24514447eafa6ce9295234767bf92f69b504", - "sha256:52e83a5f28acd621ba8e71c2b816f6541af7144b69cc5859d17da76c436a5427", - "sha256:625116aca6c4b57c56ea3d70369cacc4d62fead4930f8329d242e4fe7a58ce4b", - "sha256:654c1635f2313d0843028487db2191530bca45af61ca85d0b16555c399625b0e", - "sha256:8092a5a06ad9a7a247f2a76ace121183dc4e1a84c259cf9c2ce3bbb69fac3582", - "sha256:832339223b9ce56b7b15168e691ae654d345ac1635eeb367ade9ecfe0e66bee0", - "sha256:8ca9dca965bd86ea3631b975d63b0693566d3cc347e55786d5514988b6f5b84c", - "sha256:96f99219dddb33e235a37283306834700b63170d7bb2a1ee17e41c6d589c8eb9", - "sha256:9b6305295b6591e45f069d3553c54d50cc47629eb5c218aac99e0f7fafbf90a1", - "sha256:a62162be05edf64f819925ea88d09d18b09bebf20971b363ce0c24e8b4aa14c0", - "sha256:aacc8623ffe7999a97935eeabbd24b1ae701d08ea8f874a6ff050e93c3e658cf", - "sha256:b45bab9f224de276b7bc916f6306b86283f6aa8afe7ed4133423efb42015a898", - "sha256:b88fa3b8a3469f22b4f13d045d9bd3eda797aa4e406fde0a2644bc92bbdd4bdd", - "sha256:b8a686a6c98872007aa41fdbb2e86dc03b287d951ff4a7f1da77fb7f14113e4d", - "sha256:bd904c0dec29bbd0769887a816657491721d5f545c29e30fd9d7a1a275dc80ab", - "sha256:bf4f896c42c63d1f22039ad57de2644c72587756c0cfb3cc3b7530cfe228277f", - "sha256:c13d311a4c4a8d671f5860317eb5f09591fbe8259676b86a85769423b544451e", - "sha256:c2c6c56ee97485a127555c9595c069201b5161de9d05495fbe2132b5ac104786", - "sha256:c32c91a0f1ac779cbd73e62430de3d3502bbc45ffe5bb6c376015acfa848144b", - "sha256:c3466a84fce42c2016113101018a9981804097bacbab029c2d5b4fcb224b89de", - "sha256:c454ad88e56e80e44f824ef8366bb7e4c3def12999151fd5c0ea76a18fe9aa3e", - "sha256:c8a2b7ccff330ae4c460aff36626f911f918555660cc28163417cb84ffb25789", - "sha256:cb905f3d2e290a8b8f1579d3984f2cfa7c3a29cc7cba608540ceeed18513f520", - "sha256:cfcf28ed4ce9ced47b9b9670a4f0d3d3c0e4d4779ad4dadb1ad468b097f808aa", - "sha256:dd3e6547ecf842a29cf25123fbf8d2461c53c8d37aa20d87ecee130c89b7079b", - "sha256:de7fd57765398d141949946c84f3590a68cf5887dac3fc52388df0639b01eda4", - "sha256:ea37320877d56a7f0a1e6a625d892cf963aa7f570013499f5b8d5ab8402b5625", - "sha256:f1fce1e4929157b2afeb4bb7069204d4370bab9f4fc03ca1fbec8bd601f8c87d", - "sha256:f43109822df2d3faac7aad79613f5f02e4eab0fc8ad7932d2e70e2a83bd49c26" - ], - "version": "==2020.10.28" + "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538", + "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4", + "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc", + "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa", + "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444", + "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1", + "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af", + "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8", + "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9", + "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88", + "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba", + "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364", + "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e", + "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7", + "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0", + "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31", + "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683", + "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee", + "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b", + "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884", + "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c", + "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e", + "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562", + "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85", + "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c", + "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6", + "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d", + "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b", + "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70", + "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b", + "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b", + "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f", + "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0", + "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5", + "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5", + "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f", + "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e", + "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512", + "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d", + "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917", + "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f" + ], + "version": "==2020.11.13" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "smmap": { @@ -543,56 +576,59 @@ "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.0.4" }, "stevedore": { "hashes": [ - "sha256:5e1ab03eaae06ef6ce23859402de785f08d97780ed774948ef16c4652c41bc62", - "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0" + "sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee", + "sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a" ], - "version": "==3.2.2" + "markers": "python_version >= '3.6'", + "version": "==3.3.0" }, "toml": { "hashes": [ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.10.2" }, "typed-ast": { "hashes": [ - "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", - "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", - "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d", - "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", - "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", - "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", - "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c", - "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", - "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", - "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", - "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", - "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", - "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", - "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d", - "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", - "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", - "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c", - "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", - "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395", - "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", - "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", - "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", - "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", - "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", - "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072", - "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298", - "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91", - "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", - "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f", - "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" - ], - "version": "==1.4.1" + "sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1", + "sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d", + "sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6", + "sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd", + "sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37", + "sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151", + "sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07", + "sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440", + "sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70", + "sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496", + "sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea", + "sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400", + "sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc", + "sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606", + "sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc", + "sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581", + "sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412", + "sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a", + "sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2", + "sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787", + "sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f", + "sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937", + "sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64", + "sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487", + "sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b", + "sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41", + "sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a", + "sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3", + "sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166", + "sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10" + ], + "version": "==1.4.2" }, "wrapt": { "hashes": [ diff --git a/bot.py b/bot.py index fdd348e269..eff4000aca 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "3.8.0-dev7" +__version__ = "3.8.0-dev8" import asyncio @@ -1588,7 +1588,7 @@ def main(): pass # check discord version - if discord.__version__ != "1.5.2": + if discord.__version__ != "1.6.0": logger.error( "Dependencies are not updated, run pipenv install. discord.py version expected 1.5.2, recieved %s", discord.__version__, diff --git a/core/thread.py b/core/thread.py index 6480160e8b..aed4275abc 100644 --- a/core/thread.py +++ b/core/thread.py @@ -898,7 +898,11 @@ async def send( if is_image_url(url, convert_size=False) ] images.extend(image_urls) - images.extend((str(i.image_url), f"{i.name} Sticker", True) for i in message.stickers) + images.extend(( + str(i.image_url) if isinstance(i.image_url, discord.Asset) else i.image_url, + f"{i.name} Sticker", + True + ) for i in message.stickers) embedded_image = False @@ -908,11 +912,16 @@ async def send( additional_count = 1 for url, filename, is_sticker in images: - if not prioritize_uploads or (is_image_url(url) and not embedded_image and filename): - embed.set_image(url=url) + if not prioritize_uploads or ((url is None or is_image_url(url)) and not embedded_image and filename): + if url is not None: + embed.set_image(url=url) if filename: if is_sticker: - embed.add_field(name=filename, value=f"\u200b") + if url is None: + description = 'Unable to retrieve sticker image' + else: + description = "\u200b" + embed.add_field(name=filename, value=description) else: embed.add_field(name="Image", value=f"[{filename}]({url})") embedded_image = True @@ -925,9 +934,12 @@ async def send( color = self.bot.recipient_color img_embed = discord.Embed(color=color) - img_embed.set_image(url=url) + + if url is None: + img_embed.set_image(url=url) + img_embed.url = url + img_embed.title = filename - img_embed.url = url img_embed.set_footer(text=f"Additional Image Upload ({additional_count})") img_embed.timestamp = message.created_at additional_images.append(destination.send(embed=img_embed)) diff --git a/discord.py-1.5.2.tar.gz b/discord.py-1.5.2.tar.gz deleted file mode 100644 index df0732cccac17a0d0b0f878dde24c204773b8d80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 649426 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/Q@d9Q`4-0o)w7tj34MYxDAsHT3*DWV&mBT3N zC8SZn?n&1tr)aXbkL`@KCJVx-T()O<m=6>{VQ{;#%!@1h$>I*GQ%0ROyL26 zF`%nCw$J>(Xa3(a|L>XqcftSLJ8oTr>-Tv7@8y-H)zy6dkK4EJ%<{j^{J&@Z-!uR3 zng92f)c+d;l6BW_poav(_YvJNeXeJeo8;$mAo&w|H8yz-$bl8UP0 zhZh5KzOzI^iwJDIFTx%#zsh0Locc|CMK85c5d3tk@= zPJgxNX(N_A^U7;J2|YTQF_bVce}w|b@)0+4 z5Ju;no_Fe3QF%qr){rk*e{Tctt<^jL*Fy&$vJG1#1`!f^zmLZW-|<4!CUiWNk%U6J zT`5Vf_xe$ik~H3k{Z8Y^D3&D~p zMnI_OVeaakDBZ^Vq_~a!HYwNDfT$b!t~XJgKyNTJ0s4_+W`zxX2muVRM`>OZ*5+&q z{TSmqHr!?tzBQXUlL6}YVF^h?SIMRd^(jHSV!JX6s}Pbw6@b_%y+2LD#lp}!S}&T- z5qGB@L+htgnRdhuH|NzXYPd{}sVDb8rh|D^TOXay)#f=g*r7o7g;^bd-jD?s)E4>^ zDLG*$k4oQWd2Pzea3+wWtTWswC)D3tP#GshVcZntfJ|!&9PHQ}LBRPzdH^3} zv6EI>)D`xF5D(i4svG464DZYXk*lF@;C!k>d1iv)vX~?3gcg+&2f;5_IbLU-IF6#8 z){E^GsA^SU0q;;-Xyc<@+sx}5rRjxAN{b)EtG z2~d7w=_DNu%?V;H%)|w!`|nIhOkaMRn`rRG-SDF~Bf8_jUY~R$TKCHYdu_~?YAVT7 zy1p38hCC-yBgA?lMt+FqTc#2^>m8jZz_Nv<$>_hJ_UQ-(5n;F`X2}FWw z%MKmKZe|f|&3<$y!`9?zWB@}mXs=}-uES7E?AYYH1`b&9r9C2RTqq61MjLwHNq zFh-xApc|55OadyIrXU2iF0E33`En>@Sq9z(WfS0(C_0xTYLtyAHy;S$1s{|xJSClq z>=!&CP?rUMPHjb`H@GaC$`}n%En+IxRKl~NeV>BHS{e4u< zAo_dYdpWjs^k6iUGQg?bIB|!k!ao@|nj2J!%p;LPo?g6fFp-ehRT|>jA*eOW8f!*M z;-OW03Wu3s^K03`C!2P);?Ih0WbkE22&Vd#58|+lolvl_FU3US-m^^3n>dLaqe+%g zyjoF%DAXDL0tEn(WnY|=YDT3a1HRx~zNxL5b01DFb{=2?MyIac7WyJYL8!b5%w|P% zMbP7yHa{h`QL}%&t7{=0OxBr)B7VZgDNb{y6iI&8VAd&Zd&1mQE86Hp_`GotXcfy5 z2s@GF4sv;z^JTOOSHeAgx@X8# z)=P>CDIY&Z7bG5u*Tc;d5+(CnmO@(wxti!RP&V^oa8FsifLo@5?go{q^t~1!e8WM- z)=5G@$vugxwUV>8d}kAs(T7~?q$yNB3LbZGy2E%BdtX3((PmxuBeBhW3C2@@J9vRO zt1pf@ZUUcb04rtFrRHCBgHcSMC8QFA)N<$ob;s~VozP|Sq>J31Nt%N^*NRF%0lH@4 zI*S}|o!T@t1D&AP(^gtAm{cyWNo*QqQm1B=HwOq`Q%YY;ws&pw>@nFtO|rpeVou>< zh&b3Orpk6CtwWz``K8Z*W!!i6EYpZuXHcWYV)tn3+bSGD26S2v^`K@8vdms*sFUqo z3)Z4PRS=pORe;rGaZHb@z`FDhq1xKRFXYT)`pk(I;VKWZPbx>y^91^0p*J_I!Dfq_OVjuIQa%w6rnz@ za}Z^W)`>541_?cEc~*GIxi>&4mg#XVlsms4=u=a>5!Uv zhqGU$cy|Wt(V~VE3A2Vgxa)=W%F`g)YHJQ%m_ajIRb|}*pB;46)+`Z5%4mXU1|2zF z{HKZ!YQ-|TXQWH%&-|?OTGs@}mOVfos#eg*Nz#~WP3V?mRC<=8*~DHEs9T@RA3_>W z^6O8Ykl%jut>m4G^OjUyjoJa%;x#9FQ}CO!`p9u7$>q~ku8B=7FF63??9LFb*-^>v zqT^3;UA1&)fhb`oXz2nBxlB0XqAdDO$f9G}9vl;WAGU)=k_v_zI(3gfX*f?p7;XuT zsM`%gWc|*GNx1Zc+EL7=a6rQ-RgRe|7sW{g{9U$n0WFY|*Sjxf!qWHbQK4HFN$9B9 zLF)l1F5-io%-2e}#=7K~M2)3|(slB!DO|u416$bQ#Gis74I0iMBS=aJFf<@}&^Ga8 zEa;q&V$=3nLFl;}M-f<6dpteW1#h8>hH=?7(bBZ7d3onaoJ9f^QmVa@g$(Mc%8K~n z;^EdLX;+hi4gRpaa;aOKNdjy{N}a;Jo(cw6^ho1v^^QmrC3grF{t2amqsSbL6+R~u z4Z=G0FX$}t0zq9^{Dl%h>qN6jc_H#len4T}o?|BnOmWIwG)4T2&#Zu80xkL*?(IZ- zcrwb6J$XzwD|VkwN!7#vp4BJom4)_YOJ*f9d7@&nJTESDJMUas8MO_T*S*>H%(->5 z*fz?!ZHHt_w06ZUB6t3IjwV?)y+Fi*s*`!I^CHtlWKxG*E|HbN<{Aom-dcFL`(T&Y z7!DH~M3{jT!?8#W(2Ej|)RRnZ7=;V1lVNz8cjLpvu4o1iT;G*_5v(HYvX+M_LbC2; z+Zc|_6TGvn(61B92uoYE6Fi5Kly|^$k{-pMkuRduXm@?7br$q0=N2PmL+qN@ruaRH z>$^q-oD>T3I`B80EtVMTgsi{<@$rc+6CwH#`vcBQiV4I4VS*$teW8G)CS`;|ANv24 z3z8uzyEAht_EoC2ZN#_WWnJn=^NiVBrJ<)GTfI>7PS&xI;PtwGsOIeG2uFW(G=fAZ z_m7F}0i_e6Nfb>qkofIUOfxx*H=GYerVm=_v|#8^%#)l7Pgq|hjv7aRnt>pF$vGoy z-jR7exUS5R0eJ1V8x3dKT`if_m$I~oCBYf0DnMj&mlhOV2`5_6I3-;^&=(~W5STFJ zR)()>G)@>zBO~vVZVltu>eD3-xgsNhc{5n(0Z9fWc#OUh(N&%j*|dOIplwM*2eZHq zb{Lq2w_WBRli066mQFoFwP3z{EQFiv-K4Tj_KfGRF(R5Ie}D^8oJKsSX9YB$h!vSg zL`f{oi$>d)%_aL*E||Q@q)9A1EstX8o)3B+`-CJ$=5cMo@F*hoQ*V1=0k_|Ghkn8y zkX{0(oa^l3<~&D|?z;I7!S47mYmO? z4ylT)lk8uOC=pSO-TexxOuIzLtZj=P8}{coTa>!C3VI<6zvb(Om$=DTZmp`Nbrn?9<7PrQ9O&C|_5x zS|dpTaD9Q!^1LZIe|{~poVz*MS);Rrc0wU8kh>rk7KE(?d0R6pqSQSaL|i;1K2r1e zy{(wchRrA?9wtNE~P39l|i`Jdp!p zX!WY^U7-DtGltm|UAglBI!`_G^k%MrDsuiaB1LGrNU{;*ytG18lo4W-8MW_S9Q#cL zt!NN$XA|XKoe*BZ z*1V0z4x6=kVt_hX2>GHq&B7^k(e$i{6_R^Zn3y{c99z!|N-|qlM`^`O5t)c6?Q&S` z#I!y%tlBRe3#4hH3c>y$$;whzm~V87S5_2fyxr^t;pr%VUYdHXlO`u4 zQpHLq4sT_!%@xg37@6*O=CwKcoFJI8IbpuW)M#b0kf&`rw$8l;cZ| z^ern=*`mySHTx0|Wqc@mCIex4A`3JtY)8y=3pp*)0cFS>4jjRidc$^rxBGQXNew-U zMhR+4Kzo>7kEAz)lPI$9(loMOCGYLY%a~h zjje!QJ9_AW9@Avq8V6GNES&7+MnF$#CBvNB%Cfg`(T8AnTV@JUUT4rDfH19@71u;Tcjq zV4CZaPLpq-;q7zkUz}smq)daGD9i9@6-nkKlDMoCB-NkBiV; zZKOF?v%^SOu7ekB?+ zW6RL8uwjWVkpmW|;WQd~LkW`yafr$gI5)q`<$G_Ko;$=5@o{h^o~xd!5PZ*_p1au(1+QxEMY^ z?R2PbwJUK7Oh!wcQ3ScHmr%%OrP^GfLBXw&&2Uk#TbLmW&oZq+IL9BDn@XD4CxTKjngxy2%Wu0u@lLZeAy;u71g4UY#@t#+626$^urRH;Mm7ju=l=- zpu&rgrMHRXCkid(-0+JHX?rR=5yhQ_!gL`xDw5O%Z)?IScQhGcz$&qWl!kqm`Ebeo zXLaL(Rgi%a<6X8!1(g_(#(QX$#X#^(W-~1#Ap}SFSdl#JgBcH>b1%!%YG#=wE$&+w zS*$imfU1`>sc>>A`8)mL4^}Nq4qH zG|ep*iG{Ic3W4UW9)$=1XD{z)$7_G-f-DlL=^`x_ol8_oS%s0IqUI2u=K@Ec+dS2> zD$h!qGvb2to)-2xlmqUWxFXHrgy1qEiZaLHQD%){Qlfk>GafYgS{*G%)#zw1b~ab) z57}5fOFksgqYwd>4WwrHUt=Ud4{#3~S<@P<^HA3EVPR`VY?z3m@i7ar7YDryN_P<` z53ZKi($yH+lqikgQ})Rv|El9p3OY-AR=C_8Q7_Y2j>j~shGqkyB&LE-IJ#xmoJp;i zl-(0td*Rs>=!oVec~#*gamQ1uw#@@+c?yYW!Mt{Pa{gJrN{TMwk`ubk zs&7e4)E!m{<4BNL6QAh$nO>5eM`S4|az8JQoQ)N{k~Rv0?0e6fKo82&iQ(TCWkC`vFS5@IEihC``GmwJ6bk@)IYc?{MZ%Dxq<%_mMr`4mlWx@4S`S;YGKf>_3uN0MjdXrO~YL z#WFxDO}BK|Qhnp)05W+V^m_7uri>QfGEDE~=&P>jut$uEwH!xWr{o|tifT_7AZTiV9pip-7)B7He?1wG6=zs?3Y?@x zcHri%!AM2AT?`UN&n?um*QzN69G1x*OXgy#-!dHnj@w5G%*=y0P*iMp=T^ zxE$39y-amm**?g2fM~BtD4a7S8~C2EU+2?j#rzXz!d(d4XxNC|(~1nolH#Sk6yaGW zg64wEvwq0n>20xZd5^K2MthF|)@;Fo3?a)z`{Htw=J0yO!xVp=#(YX{Rsw?1;1Ope9)(fZx&l<;>fIF1Vaa5o|ACL!1ZPfg zLS2D3(PBb>JlK`QFJ^@`uLZ9M`Bv(}JyxBmJwQGRG4WB_RSkfCU9?@ngQ|c~GkCx4 zj?uQxj0r1Ul{-wlTun3mA05$B8BPM&IZdafY4(iaU@|$%sO6z2a<|7fd)Eb6{BH9z zk*qrh1ZvcoK@|1{-gCSX#}PnNZ6(a|_Rs^6ZbB3~en6C4x9sj3#Z|y~PNfA2(n2DsLPs|V1gh9IO}UP0 zanL&9okM~^yExk1-$ zBD*Idw2r;jX*VvKsE>UZzpuM^YJK;ePjJFq>%O!+weu^C|En&~l8|5yM9Po^N=a;vYJ33Ktld zeqsO=*Mnwm1^wl-1qm6<8U-wlRjKev%mXSX0!!t)sqoQ7gW81hvOM0`9Gxkp#P=B! zDx>%G4CI;(pHJ8FC_jF`#-DB)HQA1v^90CmkP!eesFOtdDeBm$F^$>=$0cG|%|EW` zou42k&C*_>B@0Ab!sAJM&iSkDgDRVOzMNKDW`w~EN%?%1_!J0tXmZDfEiyb zc7L^28P}h&SzcLQK?Z9IHydiD=+%T!Duom+c5k6FWfM8Y(s<>~3#4vkQTQo-JgXN) z*!+X5c_~Y2UVO4N5C2P9p8l0`H~pK#9%{Y7!en?ad zJ&=}{rdz7SvR0XHcsM|OT3&*_klrJy*mC$_*DyfWjyl91GwzA2>TB28#aE74LVzws zfGeR>8PZIEzmww?&bylQlBCw14D&|N$&nK$4q0RBMsJhrh!aqv+B6fF&(y_35oVm+ zIM&3c>8YdbJ6+fsu|s*%FlVQT4Wzp=*7VvVGk9joMPR|ZT|Y)gHQ*&Dv-ccw9aPWV z;(E6*F)peMqS&ITGq|x^hlLs>jdmj()rGLd0(lT3BYD2_LoFosTDh(gOB_eO^1Nht zXk_LopS8>;)?&r7$jA}f(w=heavWz!8HPJ}BOp1K2N7jYrp%L4ONQUkW74vTClR;jOj14yvBh~*H)EkbEPDc-ThUz zHB|~ZQUge>Ey&5*#m`sukqO%4)L(LMZ$H2-(Tk$fVoIgS<>vCxhfILfRcI=p_GM*f zO=uQ5&)d>E?2QtgM+o|2l}ly)mvd|wFX>WVr(7J=%h21=4iKF5uz392(yQr}r#W%+ z+Yh$pXkSTT zM#(Zr9$!ceBw8&c28#r+j`SGGh2XHJOg4exfi2dJ(Y#*27f%l7#bm1az8db^wf%D1 zo|W!^5$pRp6hCF0GGZ-xNtoq12~h)9GPT%ChS~WURtUP zg}pEo>qcXbwEN;m)Wf5vNvV`20Kk!8Qemqr7Hx+K_59CKx+cBms2T0*hrND9VTytx}dBMy|hHB3_x5rKOTv zr_8u(4BBe3>Kjw&mE9>Pdi1R|$M9Ew*n@fV$$^`4!Lb-^W6QK~Vv~_FyS==!T5~%L zwOY8XQvo6A=vPyN1d@D= z6fGH9u7Fq_HIz?BUvK?HK_?PlUC~l7eR;xf=bS9JeM&u;Qd(e`Jmntb>dptam9+tu zL|mKqKWBm0#hVnKJ+snwjl2qbA9a*2%gfNaI71#6(Tw$`%^lnP9?aoF=pjEZy8-h# zhMdV7W~uE7G+ zSroL;IVnEVlJvZcKkEkw(DXx9^E{sSw+6J-yd>g|{IG~Cd z&KQ3rq|q>4ySwBrAzcv#IAIS)tFH01(Fn(feQ|BtzPx^vCtXE&$~DnolH)&MA7ELK zXjhbwmQ(abFyUG^Cs@o4`i#4}M)3+PflPtvE2d*g>~y8hRQx)EI;>6|CC z?UVl$P(k672dsRAVF4|)+@Nob-yh^0Fube$Mk0Y1AqnQ0tl(ZZbTkDwuW2y8jdqhjUHS2#_ke`S7sp z;40b4j6T!pD`+PKk$cE%D|U(L`h`m%)F`2LK?bk2BwRt5=RtC=M(O{UkyYLTe_eYV}_AP2rECUC_F@?{a2#qNDdiAKrOY0fUmCR#<7z53M z%6!fajmBs#+qp#lqI?e|dQ|~M>yFWln$=T6Wdf;I@GG;LeIFPAqp~9jFeeVDHgb72 zfVflie^aS;tn`1JBFM~CL^`oW~W)e1?aZJWC>iQ!-GLKZbz1uEb2 z=_Iu0oKcI=D7iMi9br^&3->!3gcW4LZK}(Gv}2Cn*zVs>5*s?;HLVNu)e?lLVR_C1OuVVs$IC?QOf8B%p z8TngTar#Jc)|T%s-M)MG{@b_jxl6O%^K+5Ug!e{VVqw-)fObG(Mf8K#|u`}hP8R$@qzw|=~R z=sbc`HH5Rb3O|Us*@y-gFccPDN@VW!q!mKGBXJA`-`K|(O5#iEP^i@#QjmgtomsR2 z6vceO3`i?lo$kD@W0Z2x!B3w?HW-qaUq@z0gpAZtXzcNnLZ@ITi=6JOham9M3nA9Z z{?+;ZA#n#lDyE5r^Aq-qxiPN>L$XI4LZi$XwF_CJ%M7@$aesSrVS~^9#A?3yl`?5#X>n|4wWRe!>vu{ zVE5tShwJ;B&h~+`x4-+r_Jhp_&dv1$_|3s}7k=nPN~cO7g| zz}ntCKxmIQ_cylS=lXlwkG2m#f^~YheYgWqoreH*-Pv2;KiuAU@@ReE*?Y3Tw|lS& z9e4n6ceZyP?n5)1k2iM?U1%1bIh!BA59eTO{m~&E>06Bxigw6yPR?CyQEzy1E! zp|iF7=)opDd~Xx_w*KCuO>PUuwee_u`*GcQu>N@c{Y|R13t;wd%wsw3p!4C@CO*R! z*Wtg7!|mN29LdJ+06##$zs})4{H()3_YYOw54R6C>(2WA_5pMjMz_BU4d9$Ym0f}Y z6?Zln49>S>EDIFD-%k!Uwcb3~Tz>@64zRXf+7bZQuLChx(OY7+-%~d8KgO738eBK2+^`@6=BA#6doL;Ah`BnQxW70qMdH{Q= zlNH~9(<$ofP-=oQZ+Fm_1GD1PRXQF0Zp5T@;`cr2m8lMMti6q?k3i;%dl&3%nMBSu zn{^}+MGF-YY$69}f(GH%Vtgi1xPkFJPPOknZ#c^<_mRj7WqAG#kW5%`sMH_8I}8xv zVd4p#HqiVIg@X_Z3)$00!=Cw=ki@9n!}FsV^vRhrYjAa?roTtu&SHP4^*%0Td3}Cw zua6jYp?3!T1Pjx_!Rp`hMZ7Ky=ouAQ==otcJ!v>AhO4>X&ks8BTXAmGeJ^dD*a!4U zg!QaL9iVBWxMZ*?MU+B=uKa{)&aN_SiZR`o=Y)Ovs>8S^-lIyCx(+?Q2wPdj#OK7D z>H+MdZX$}(d4uOUX$S!qC9*nHim&mew`ghvoE-vRkoqyX$#j)kTI&A1v`@I1x^mk* zBrt2v3!a4SorA;mosCWCzgU|;*xlZNMG(IZ_JHE8AHw_F+WY4I<{v)UJUDDP_hq?{ zb~XUUUGa18(fUV-H8>ib)9!?en`r)HcpAdl&Lv zYr&UxhUpM*w2Z`6!Jc&I4)JyrkCt>~Z~JD_Fs^(Vv%DNsANz=iM^86t&Fkhb&Y1)-wfA#N~?2T_8NW=YgH2qAGIoephjG*yCF z)|VP&H0;TRNi6heEZGr+RfYG9vIWCx{*1K82OP=^f4L;a2gq9qvJA9*vf9(5SO_nC_Cu{ZH@8Cvm+q!3Nr2!n%b{`+Id8c(a?_}Drix?$w`ELcn-v4d zW{9XJt^zWi@<2~=vbAKGiG|KxDUSJ>faDwX-W*fg9}V;iQ!1jD(Klb3H?`eiT!KglE;E^w4Ru+RQ?oXR1HofFLV zK`DF)7sLFr62o`Jwb29%oTzn~U8~S5*wTs%#X8(g9;s`CNtxP4f}|1ATF?mPGD0q-uSzH+pm3bvC*6SnpKz?%L7As67Nt>F zre;Nlz)x0dt}3bu<=9o}(x5Y{a+U;-YLu6rfM$(sI&F2bDa}!l^SEfv<1 z(J#N63Mp+3WO$mdrX#R*Rrx|BsiLf!noDDu8T%KOYq}jz1G()_exA}_Ozxap&tw=xlqNaxTs^RR^Ce1-ij;ETTT@RSVt#o{356heywpt z8h)jVuygmL2tlv%ZHXGrTgf{JkQ*~%^+igZf+H+tZFq5MrVy45ifdp5h0m=e-|M_) z>2?9Z1d?$L`~68WB}@>ScS9F%=aRP#!EkEC%VD|}dRTe^R~cX!{Zs5PW;hnNQtPi6 z!SE%V#Z|Q_Yem7FkJ}<}ff6c%GX1orQYvPtu;?s^k$-*a3c4Cs?1tl>?;0wJqFdOM zYKQD>dRn2rz$_{CL(XmNJN|{uHBGdr(-F(8$ppgJFlQvtBxyAGLd+Tr>{ZQ~CcHF( zc1|>ZbUQ*r%ZHD81M>2wsfz5c2xD8|<`-WqT`s;@zH|p+x8ic*`>JL9b$tY*be@`M zcfG4xkj=gTtEvq)zpC1+FY>Bt-K>lgYZ{3nt(L|k2&_aJ22~dQ>YZe}%5AowhLkmjFnKIgb(u#v) zAIdyOF6<)DYHghOty4~^eI8M_Sr6}jcjy%ogBZ}hF$FY~UdBN@@sgA3^Fo3<9c>U` zC83fd0AV81iQt6#BITp53WkAk+I$nJ<^eGYN2BY-IAU1F1`}6dDz20^7n_s}ql*L* z?^9i%L`f>Ufa`2?R%wzTjw6-3-Z$c_Urpb9x;t!&j*Yd_Ty-rHh~1G zTmhKqzntZtcT7Qo{2b-#mzxtjYF=(ekQz)fA55*`K(MGQC9fzpA5r1jM2b$O&_l+N z?+t#jMD@QBU%q2V3$;nKdj?t8m3$+y$flWD)63^$GE3&ZsH<4Z%35OYUf9&T4eM4F z_ek4Rzm43)=L>1aT0`q%R_fARD*wCcJf`d(mi5vvX~!aUV*FV-Ne{$9yry5tt+x^S zW7|N^R;XjCM_kSXgZyeaRuSK8A|y*G%6sM2iYm&zha5D9$rNIX>fz@uxbPsZPju1Y zU6b&_Ag@DwQIHG)W-QYTOP3<0Dr1~KB%ee@`~%JNi_^4L1K<@tiiU^7W8i-efj4NK z)FyGB)0y^hx3?Zz255K&jRUYA0zVRX%*_Z^B+R_Sx)b+;jyd*v;tu8V4U8P@2nQ}> zgirP#xzoGQAd?mclpzZ5F$($tW@)J<)YeEFFiS?$@lNK&4V>pJlsE}7g7cKd+ zP4_>(TF~%(Lt-JJiB(cVmQ+GZ_L`9%H2S72DF#O`{eN$o2mI< z5g(t62DlDZJ_quexOuq}*Tm1`;;J~&aokx`xpOvke@@ebvzfVYHl;Hl)XY3Jo8=x; zOe1s$(b0aGl)%0a5F}kJDHr=#=Bk--QCWr2{*_HbkCN3I<6hZRd{$Ovgm-0Ax>shU z%bhEmnJ=O?Y%%G@!nzZpRz6#p+Q=xYtjbg|RxiOUYH0u37)C|@reYYi2&K;<*eoO2 zKZ7A=WwS+L_oEPp1M_nzV>v|xs5(ZMWvMhp?fhNoocY4jrFzmr<5Aj{2!jCQBO6jM z)augn<@WL0cW#dx;1_s&L;C<}C0imT!bGg7O{vSy)eYzN{W?gg7zOQopQ4}b3}`;5 zK?!3iNNv6l)6a%ZUkmQMf@U^Mx;nz^w^1OfBUQ}#6Qs-yxnUkpg$~e>*0A4^aXA9n z%EUrl8fD&~Ha?|P~qn2!H9=vK{!Wov%f*YsVT46CPxeB$a z^3+_*9iv$pVMSh3;Tv&U`&?OhZEUqEloBP&FjgNSs7xB9JyJ)|mv6+E4m$lODL&$F z_zdmgr_eDfD85gpyFloZp(hoUs)Qt>tGnrTak3PYyK6O-m{{5i9+34CB;(c`p*f+= z!d0%)AC6B=2Ee^kEC04rsg3Q~g!`AumiMTjy=h}6W4ddU6DHGDx7aOa!5CZ+@={VF zt}u-j^VB>$zN>~(>osaC!7~7nnf@d zCPs^P8?kDozKoU83y6(3Tj+II=5t%tW2z*a7t!mMWO2Ex6KCVWj@ey{AG4*`tj`kN z)-S!y-ac*Ie})2YB@t?aikfl9-{xyWe5GEZFC9kqq|*tm+vNI8=~k)H@* zui*7<{hOF29~pl!t<%TkgDP?LcqPNi1xS<*sy$?OdZLlxKW)F4dIG0pVGR^V1-0Af&XotJ0Py{ zv)PmjzP8p7@bT7Psf3YM29d$fIiS_7*t}kK!<8*zz6$Ie7u4%>3d2c*cgMs4e_3>b zjLTCg1i8v2Dw6ziXN#Dd`KV~rD>dwK^H!@~QIS9xZYdMU-4;Co##tj5mk5(s`E-agM+P`eIjevP0}%A&CSulK}`4s~@hp!uiw*@*-VK+oo$!<@1urNjYX=?<)+E zqUwy7es5%FnY=V6@c+mRT|{!GjjAs1dO5n~m}){98Td2#5S2SeZbi^VWAt=q-oIt@ zZ6DQ`4r#swK+%+%U7-X&9f=dNgDj()t(SIfb|=H^{+HSPFSGk!W`CdW{V#(78V;`E z`j;{HzbvoZUdr$PJFEAWX7|6$?thux|1!J(Wp@9|m+Sr)zG6k*u0mI>sC!o^nv7pO zf$!sQhDkBKwRmv|-}T%r>x02IoM2YFMw-jYjYpkIhKtt{%fJe>G3wTi@yWp#vYS9A z%?LhW7I3|irjU=$(dwe=;lz!oNTp@cYnU;MCLbph&1R;p5j2m!f;WZn8 zIox3&jlHOKs$XX+%^f9+fZd4w?+%05Z^Ak3H|dC+xJ#m{x_N%k^L1k;-a+g{-Y`8` z!BbwdY)~^!2aW*jAttmG9f}97W&~6}2=y4sq8p8o?nP!l-rw7BxH5V?B(#qB4CciT zG4Q`FQ{D{weJ{Q!!}o2O+DYG}XpiJfHc_vQal~S0YT9I~)Cv5axC!H!<5Wd!;*H9B zoklU*TD!!F1V9%CaX{q`zVl>a^u|2boeR7PdDP~`yI$_zhDpFxXj4#?>;|gC4jz05 z_SO4-dKduqq!TyZ9R|HNT|ZFR5J+{Ny|NjlhME7s`+4xfC@&E=ZU^D1-=25~V$Pe% z>G1OyNYIvhAh3(it2^xikGLk~M(J=rV8^xyZQ` zvUXJg7a!HgF9zQgqEs{Q2XS`FVM#pAk0V1`RaC>{X9c(toiS1#r2w~>UY_%EWr$xZ z05SK$cu={0Q%LrXv{Ro<+CuqK+I}($kJxA9?2a#%+-8#qYqJU8aC=YVw52AB zWqTh>igW{CGzM})FLWjcJYIByUaH zXSPz?;hEP9+Us$bHhqaz@y7fI(3=O%gTr-LsU}S25ZR&h_i*o})fYEE8Tehm zC-|g~bN_gNpM$V_6O*B57+lK2v)$~cV67=2A!Linh_F@(X!C02RrhzmGC-3 zs>a6_p?X+sH`VxvU?selYcxP8(M?YZFjczBGRSDuvVhiNwE)~Y-}m8(OKaSh2qrs` zw}+q|3gf-_ydh`$vC}X%u1trnBFd&|VS*4dT_3LB&^lJXjT($h+d=o)tYxvg7`Q7~ zJ~+7DR@ASIR}ce4ilrK>BsO1aSuurPg7!$?hqJYoW51b=igbpX!Ijk|P%?kWZ&ryT1e3y>O+e>fXy=jJraX5;eUr=pzeOopAO-REUW> z4#U7q1{~=!91sETs^)XkXRNk4T_!P}a3u|Ja@NXb%WR=m%SA2GyzqcV-+e^|0oA=> zFO{>XZHoe?SRl!@aVjuX71g?JRamuejMS359X6UY3{)1ysw}eZ89(^RrTb#}^7m