From a8a3e829c926694ba9e95fc712a9cfd5ccf84c2f Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 01:40:11 +0000 Subject: Handling pending flag changes on users --- bot/exts/moderation/verification.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 7aa559617..ff308a3b3 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -182,6 +182,8 @@ class Verification(Cog): self.bot = bot self.bot.loop.create_task(self._maybe_start_tasks()) + self.pending_members = set() + def cog_unload(self) -> None: """ Cancel internal tasks. @@ -570,18 +572,7 @@ class Verification(Cog): # We will send them an alternate DM once they verify with the welcome # video. if raw_member.get("pending"): - await self.member_gating_cache.set(member.id, True) - - # TODO: Temporary, remove soon after asking joe. - await self.mod_log.send_log_message( - icon_url=self.bot.user.avatar_url, - colour=discord.Colour.blurple(), - title="New native gated user", - channel_id=constants.Channels.user_log, - text=f"<@{member.id}> ({member.id})", - ) - - return + self.pending_members.add(member.id) log.trace(f"Sending on join message to new member: {member.id}") try: @@ -589,6 +580,17 @@ class Verification(Cog): except discord.HTTPException: log.exception("DM dispatch failed on unexpected error code") + @Cog.listener() + async def on_socket_response(self, msg: dict) -> None: + """Check if the users pending status has changed and send them them a welcome message.""" + if msg.get("t") == "GUILD_MEMBER_UPDATE": + user_id = int(msg["user"]["id"]) + + if user_id in self.pending_members: + self.pending_members.remove(user_id) + if member := self.bot.get_guild(constants.Guild.id).get_member(user_id): + await safe_dm(member.send(ALTERNATE_VERIFIED_MESSAGE)) + @Cog.listener() async def on_member_update(self, before: discord.Member, after: discord.Member) -> None: """Check if we need to send a verification DM to a gated user.""" -- cgit v1.2.3 From 0be0d86271c84ca1b2980b552aaf31c78e84fcda Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 01:45:54 +0000 Subject: Correctly check if the user is pending --- bot/exts/moderation/verification.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index ff308a3b3..cc8abee42 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -584,12 +584,13 @@ class Verification(Cog): async def on_socket_response(self, msg: dict) -> None: """Check if the users pending status has changed and send them them a welcome message.""" if msg.get("t") == "GUILD_MEMBER_UPDATE": - user_id = int(msg["user"]["id"]) + user_id = int(msg["d"]["user"]["id"]) - if user_id in self.pending_members: - self.pending_members.remove(user_id) - if member := self.bot.get_guild(constants.Guild.id).get_member(user_id): - await safe_dm(member.send(ALTERNATE_VERIFIED_MESSAGE)) + if msg["d"]["pending"] is False: + if user_id in self.pending_members: + self.pending_members.remove(user_id) + if member := self.bot.get_guild(constants.Guild.id).get_member(user_id): + await safe_dm(member.send(ALTERNATE_VERIFIED_MESSAGE)) @Cog.listener() async def on_member_update(self, before: discord.Member, after: discord.Member) -> None: -- cgit v1.2.3 From 583792136152eb4b06ed0dda1bc0b95a0d8ebad1 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 02:11:56 +0000 Subject: Fix minor verification bugs --- bot/exts/moderation/verification.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index cc8abee42..581d7e0bf 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -572,7 +572,7 @@ class Verification(Cog): # We will send them an alternate DM once they verify with the welcome # video. if raw_member.get("pending"): - self.pending_members.add(member.id) + return self.pending_members.add(member.id) log.trace(f"Sending on join message to new member: {member.id}") try: @@ -586,7 +586,7 @@ class Verification(Cog): if msg.get("t") == "GUILD_MEMBER_UPDATE": user_id = int(msg["d"]["user"]["id"]) - if msg["d"]["pending"] is False: + if msg["d"].get("pending") is False: if user_id in self.pending_members: self.pending_members.remove(user_id) if member := self.bot.get_guild(constants.Guild.id).get_member(user_id): -- cgit v1.2.3 From fb4d82ca09c213b88da6845a5eb433e4e5e9961a Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 02:37:15 +0000 Subject: Install git in Docker container --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index 06a538b2a..0b1674e7a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,11 @@ ENV PIP_NO_CACHE_DIR=false \ PIPENV_IGNORE_VIRTUALENVS=1 \ PIPENV_NOSPIN=1 +RUN apt-get -y update \ + && apt-get install -y \ + git \ + && rm -rf /var/lib/apt/lists/* + # Install pipenv RUN pip install -U pipenv -- cgit v1.2.3 From 6ed94dab7f2b7d0a71775670664b661fa1766e5c Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 02:40:39 +0000 Subject: Bump discord.py to a unreleased ref --- Pipfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index ae80ae2ae..02b60b681 100644 --- a/Pipfile +++ b/Pipfile @@ -14,7 +14,7 @@ beautifulsoup4 = "~=4.9" colorama = {version = "~=0.4.3",sys_platform = "== 'win32'"} coloredlogs = "~=14.0" deepdiff = "~=4.0" -"discord.py" = "~=1.5.0" +discord-py = {git = "https://github.com/Rapptz/discord.py.git", ref = "93f102ca907af6722ee03638766afd53dfe93a7f"} feedparser = "~=5.2" fuzzywuzzy = "~=0.17" lxml = "~=4.4" -- cgit v1.2.3 From 9e61bed6bb3b8485c4b829a7072f4cea1e52e079 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 02:41:20 +0000 Subject: Update verification.py to use on_member_update, closes #1330 --- bot/exts/moderation/verification.py | 39 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 581d7e0bf..ad05888df 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -570,9 +570,9 @@ class Verification(Cog): # If the user has the pending flag set, they will be using the alternate # gate and will not need a welcome DM with verification instructions. # We will send them an alternate DM once they verify with the welcome - # video. + # video when they pass the gate. if raw_member.get("pending"): - return self.pending_members.add(member.id) + return log.trace(f"Sending on join message to new member: {member.id}") try: @@ -580,34 +580,19 @@ class Verification(Cog): except discord.HTTPException: log.exception("DM dispatch failed on unexpected error code") - @Cog.listener() - async def on_socket_response(self, msg: dict) -> None: - """Check if the users pending status has changed and send them them a welcome message.""" - if msg.get("t") == "GUILD_MEMBER_UPDATE": - user_id = int(msg["d"]["user"]["id"]) - - if msg["d"].get("pending") is False: - if user_id in self.pending_members: - self.pending_members.remove(user_id) - if member := self.bot.get_guild(constants.Guild.id).get_member(user_id): - await safe_dm(member.send(ALTERNATE_VERIFIED_MESSAGE)) - @Cog.listener() async def on_member_update(self, before: discord.Member, after: discord.Member) -> None: """Check if we need to send a verification DM to a gated user.""" - before_roles = [role.id for role in before.roles] - after_roles = [role.id for role in after.roles] - - if constants.Roles.verified not in before_roles and constants.Roles.verified in after_roles: - if await self.member_gating_cache.pop(after.id): - try: - # If the member has not received a DM from our !accept command - # and has gone through the alternate gating system we should send - # our alternate welcome DM which includes info such as our welcome - # video. - await safe_dm(after.send(ALTERNATE_VERIFIED_MESSAGE)) - except discord.HTTPException: - log.exception("DM dispatch failed on unexpected error code") + + if before.pending is True and after.pending is False: + try: + # If the member has not received a DM from our !accept command + # and has gone through the alternate gating system we should send + # our alternate welcome DM which includes info such as our welcome + # video. + await safe_dm(after.send(ALTERNATE_VERIFIED_MESSAGE)) + except discord.HTTPException: + log.exception("DM dispatch failed on unexpected error code") @Cog.listener() async def on_message(self, message: discord.Message) -> None: -- cgit v1.2.3 From fe7f7ad3e54a99f1861c20c9afa50c88bad4d7f3 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 02:47:51 +0000 Subject: Lock Pipfile --- Pipfile.lock | 470 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 269 insertions(+), 201 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 541db1627..c99a1d07d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3ccb368599709d2970f839fc3721cfeebcd5a2700fed7231b2ce38a080828325" + "sha256": "1a759ddc72f37c3861b988fc99013690188e7c3e053eadc346d08054e912ec10" }, "pipfile-spec": 6, "requires": { @@ -34,22 +34,46 @@ }, "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:0b795072bb1bf87b8620120a6373a3c61bfcb8da7e5c2377f4bb23ff4f0b62c9", + "sha256:0d438c8ca703b1b714e82ed5b7a4412c82577040dadff479c08405e2a715564f", + "sha256:16a3cb5df5c56f696234ea9e65e227d1ebe9c18aa774d36ff42f532139066a5f", + "sha256:1edfd82a98c5161497bbb111b2b70c0813102ad7e0aa81cbeb34e64c93863005", + "sha256:2406dc1dda01c7f6060ab586e4601f18affb7a6b965c50a8c90ff07569cf782a", + "sha256:2858b2504c8697beb9357be01dc47ef86438cc1cb36ecb6991796d19475faa3e", + "sha256:2a7b7640167ab536c3cb90cfc3977c7094f1c5890d7eeede8b273c175c3910fd", + "sha256:3228b7a51e3ed533f5472f54f70fd0b0a64c48dc1649a0f0e809bec312934d7a", + "sha256:328b552513d4f95b0a2eea4c8573e112866107227661834652a8984766aa7656", + "sha256:39f4b0a6ae22a1c567cb0630c30dd082481f95c13ca528dc501a7766b9c718c0", + "sha256:3b0036c978cbcc4a4512278e98e3e6d9e6b834dc973206162eddf98b586ef1c6", + "sha256:3ea8c252d8df5e9166bcf3d9edced2af132f4ead8ac422eac723c5781063709a", + "sha256:41608c0acbe0899c852281978492f9ce2c6fbfaf60aff0cefc54a7c4516b822c", + "sha256:59d11674964b74a81b149d4ceaff2b674b3b0e4d0f10f0be1533e49c4a28408b", + "sha256:5e479df4b2d0f8f02133b7e4430098699450e1b2a826438af6bec9a400530957", + "sha256:684850fb1e3e55c9220aad007f8386d8e3e477c4ec9211ae54d968ecdca8c6f9", + "sha256:6ccc43d68b81c424e46192a778f97da94ee0630337c9bbe5b2ecc9b0c1c59001", + "sha256:6d42debaf55450643146fabe4b6817bb2a55b23698b0434107e892a43117285e", + "sha256:710376bf67d8ff4500a31d0c207b8941ff4fba5de6890a701d71680474fe2a60", + "sha256:756ae7efddd68d4ea7d89c636b703e14a0c686688d42f588b90778a3c2fc0564", + "sha256:77149002d9386fae303a4a162e6bce75cc2161347ad2ba06c2f0182561875d45", + "sha256:78e2f18a82b88cbc37d22365cf8d2b879a492faedb3f2975adb4ed8dfe994d3a", + "sha256:7d9b42127a6c0bdcc25c3dcf252bb3ddc70454fac593b1b6933ae091396deb13", + "sha256:8389d6044ee4e2037dca83e3f6994738550f6ee8cfb746762283fad9b932868f", + "sha256:9c1a81af067e72261c9cbe33ea792893e83bc6aa987bfbd6fdc1e5e7b22777c4", + "sha256:c1e0920909d916d3375c7a1fdb0b1c78e46170e8bb42792312b6eb6676b2f87f", + "sha256:c68fdf21c6f3573ae19c7ee65f9ff185649a060c9a06535e9c3a0ee0bbac9235", + "sha256:c733ef3bdcfe52a1a75564389bad4064352274036e7e234730526d155f04d914", + "sha256:c9c58b0b84055d8bc27b7df5a9d141df4ee6ff59821f922dd73155861282f6a3", + "sha256:d03abec50df423b026a5aa09656bd9d37f1e6a49271f123f31f9b8aed5dc3ea3", + "sha256:d2cfac21e31e841d60dc28c0ec7d4ec47a35c608cb8906435d47ef83ffb22150", + "sha256:dcc119db14757b0c7bce64042158307b9b1c76471e655751a61b57f5a0e4d78e", + "sha256:df3a7b258cc230a65245167a202dd07320a5af05f3d41da1488ba0fa05bc9347", + "sha256:df48a623c58180874d7407b4d9ec06a19b84ed47f60a3884345b1a5099c1818b", + "sha256:e1b95972a0ae3f248a899cdbac92ba2e01d731225f566569311043ce2226f5e7", + "sha256:f326b3c1bbfda5b9308252ee0dcb30b612ee92b0e105d4abec70335fab5b1245", + "sha256:f411cb22115cb15452d099fec0ee636b06cf81bfb40ed9c02d30c8dc2bc2e3d1" ], "index": "pypi", - "version": "==3.6.3" + "version": "==3.7.3" }, "aioping": { "hashes": [ @@ -129,51 +153,51 @@ }, "certifi": { "hashes": [ - "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd", - "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4" + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" ], - "version": "==2020.11.8" + "version": "==2020.12.5" }, "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" - ], - "version": "==1.14.3" + "sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e", + "sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d", + "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a", + "sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec", + "sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362", + "sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668", + "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c", + "sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b", + "sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06", + "sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698", + "sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2", + "sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c", + "sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7", + "sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009", + "sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03", + "sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b", + "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909", + "sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53", + "sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35", + "sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26", + "sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b", + "sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01", + "sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb", + "sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293", + "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd", + "sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d", + "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3", + "sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d", + "sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e", + "sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca", + "sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d", + "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775", + "sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375", + "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b", + "sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b", + "sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f" + ], + "version": "==1.14.4" }, "chardet": { "hashes": [ @@ -192,11 +216,11 @@ }, "coloredlogs": { "hashes": [ - "sha256:346f58aad6afd48444c2468618623638dadab76e4e70d5e10822676f2d32226a", - "sha256:a1fab193d2053aa6c0a97608c4342d031f1f93a3d1218432c59322441d31a505" + "sha256:7ef1a7219870c7f02c218a2f2877ce68f2f8e087bb3a55bd6fbaa2a4362b4d52", + "sha256:e244a892f9d97ffd2c60f15bf1d2582ef7f9ac0f848d132249004184785702b3" ], "index": "pypi", - "version": "==14.0" + "version": "==14.3" }, "deepdiff": { "hashes": [ @@ -206,13 +230,9 @@ "index": "pypi", "version": "==4.3.2" }, - "discord.py": { - "hashes": [ - "sha256:2367359e31f6527f8a936751fc20b09d7495dd6a76b28c8fb13d4ca6c55b7563", - "sha256:def00dc50cf36d21346d71bc89f0cad8f18f9a3522978dc18c7796287d47de8b" - ], - "index": "pypi", - "version": "==1.5.1" + "discord-py": { + "git": "https://github.com/Rapptz/discord.py.git", + "ref": "93f102ca907af6722ee03638766afd53dfe93a7f" }, "docutils": { "hashes": [ @@ -231,10 +251,10 @@ }, "fakeredis": { "hashes": [ - "sha256:8070b7fce16f828beaef2c757a4354af91698685d5232404f1aeeb233529c7a5", - "sha256:f8c8ea764d7b6fd801e7f5486e3edd32ca991d506186f1923a01fc072e33c271" + "sha256:01cb47d2286825a171fb49c0e445b1fa9307087e07cbb3d027ea10dbff108b6a", + "sha256:2c6041cf0225889bc403f3949838b2c53470a95a9e2d4272422937786f5f8f73" ], - "version": "==1.4.4" + "version": "==1.4.5" }, "feedparser": { "hashes": [ @@ -307,11 +327,11 @@ }, "humanfriendly": { "hashes": [ - "sha256:bf52ec91244819c780341a3438d5d7b09f431d3f113a475147ac9b7b167a3d12", - "sha256:e78960b31198511f45fd455534ae7645a6207d33e512d2e842c766d15d9c8080" + "sha256:066562956639ab21ff2676d1fda0b5987e985c534fc76700a19bd54bcb81121d", + "sha256:d5c731705114b9ad673754f3317d9fa4c23212f36b29bdc4272a892eafc9bc72" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==8.2" + "version": "==9.1" }, "idna": { "hashes": [ @@ -339,54 +359,54 @@ }, "lxml": { "hashes": [ - "sha256:098fb713b31050463751dcc694878e1d39f316b86366fb9fe3fbbe5396ac9fab", - "sha256:0e89f5d422988c65e6936e4ec0fe54d6f73f3128c80eb7ecc3b87f595523607b", - "sha256:189ad47203e846a7a4951c17694d845b6ade7917c47c64b29b86526eefc3adf5", - "sha256:1d87936cb5801c557f3e981c9c193861264c01209cb3ad0964a16310ca1b3301", - "sha256:211b3bcf5da70c2d4b84d09232534ad1d78320762e2c59dedc73bf01cb1fc45b", - "sha256:2358809cc64394617f2719147a58ae26dac9e21bae772b45cfb80baa26bfca5d", - "sha256:23c83112b4dada0b75789d73f949dbb4e8f29a0a3511647024a398ebd023347b", - "sha256:24e811118aab6abe3ce23ff0d7d38932329c513f9cef849d3ee88b0f848f2aa9", - "sha256:2d5896ddf5389560257bbe89317ca7bcb4e54a02b53a3e572e1ce4226512b51b", - "sha256:2d6571c48328be4304aee031d2d5046cbc8aed5740c654575613c5a4f5a11311", - "sha256:2e311a10f3e85250910a615fe194839a04a0f6bc4e8e5bb5cac221344e3a7891", - "sha256:302160eb6e9764168e01d8c9ec6becddeb87776e81d3fcb0d97954dd51d48e0a", - "sha256:3a7a380bfecc551cfd67d6e8ad9faa91289173bdf12e9cfafbd2bdec0d7b1ec1", - "sha256:3d9b2b72eb0dbbdb0e276403873ecfae870599c83ba22cadff2db58541e72856", - "sha256:475325e037fdf068e0c2140b818518cf6bc4aa72435c407a798b2db9f8e90810", - "sha256:4b7572145054330c8e324a72d808c8c8fbe12be33368db28c39a255ad5f7fb51", - "sha256:4fff34721b628cce9eb4538cf9a73d02e0f3da4f35a515773cce6f5fe413b360", - "sha256:56eff8c6fb7bc4bcca395fdff494c52712b7a57486e4fbde34c31bb9da4c6cc4", - "sha256:573b2f5496c7e9f4985de70b9bbb4719ffd293d5565513e04ac20e42e6e5583f", - "sha256:7ecaef52fd9b9535ae5f01a1dd2651f6608e4ec9dc136fc4dfe7ebe3c3ddb230", - "sha256:803a80d72d1f693aa448566be46ffd70882d1ad8fc689a2e22afe63035eb998a", - "sha256:8862d1c2c020cb7a03b421a9a7b4fe046a208db30994fc8ff68c627a7915987f", - "sha256:9b06690224258db5cd39a84e993882a6874676f5de582da57f3df3a82ead9174", - "sha256:a71400b90b3599eb7bf241f947932e18a066907bf84617d80817998cee81e4bf", - "sha256:bb252f802f91f59767dcc559744e91efa9df532240a502befd874b54571417bd", - "sha256:be1ebf9cc25ab5399501c9046a7dcdaa9e911802ed0e12b7d620cd4bbf0518b3", - "sha256:be7c65e34d1b50ab7093b90427cbc488260e4b3a38ef2435d65b62e9fa3d798a", - "sha256:c0dac835c1a22621ffa5e5f999d57359c790c52bbd1c687fe514ae6924f65ef5", - "sha256:c152b2e93b639d1f36ec5a8ca24cde4a8eefb2b6b83668fcd8e83a67badcb367", - "sha256:d182eada8ea0de61a45a526aa0ae4bcd222f9673424e65315c35820291ff299c", - "sha256:d18331ea905a41ae71596502bd4c9a2998902328bbabd29e3d0f5f8569fabad1", - "sha256:d20d32cbb31d731def4b1502294ca2ee99f9249b63bc80e03e67e8f8e126dea8", - "sha256:d4ad7fd3269281cb471ad6c7bafca372e69789540d16e3755dd717e9e5c9d82f", - "sha256:d6f8c23f65a4bfe4300b85f1f40f6c32569822d08901db3b6454ab785d9117cc", - "sha256:d84d741c6e35c9f3e7406cb7c4c2e08474c2a6441d59322a00dcae65aac6315d", - "sha256:e65c221b2115a91035b55a593b6eb94aa1206fa3ab374f47c6dc10d364583ff9", - "sha256:f98b6f256be6cec8dd308a8563976ddaff0bdc18b730720f6f4bee927ffe926f" + "sha256:0448576c148c129594d890265b1a83b9cd76fd1f0a6a04620753d9a6bcfd0a4d", + "sha256:127f76864468d6630e1b453d3ffbbd04b024c674f55cf0a30dc2595137892d37", + "sha256:1471cee35eba321827d7d53d104e7b8c593ea3ad376aa2df89533ce8e1b24a01", + "sha256:2363c35637d2d9d6f26f60a208819e7eafc4305ce39dc1d5005eccc4593331c2", + "sha256:2e5cc908fe43fe1aa299e58046ad66981131a66aea3129aac7770c37f590a644", + "sha256:2e6fd1b8acd005bd71e6c94f30c055594bbd0aa02ef51a22bbfa961ab63b2d75", + "sha256:366cb750140f221523fa062d641393092813b81e15d0e25d9f7c6025f910ee80", + "sha256:42ebca24ba2a21065fb546f3e6bd0c58c3fe9ac298f3a320147029a4850f51a2", + "sha256:4e751e77006da34643ab782e4a5cc21ea7b755551db202bc4d3a423b307db780", + "sha256:4fb85c447e288df535b17ebdebf0ec1cf3a3f1a8eba7e79169f4f37af43c6b98", + "sha256:50c348995b47b5a4e330362cf39fc503b4a43b14a91c34c83b955e1805c8e308", + "sha256:535332fe9d00c3cd455bd3dd7d4bacab86e2d564bdf7606079160fa6251caacf", + "sha256:535f067002b0fd1a4e5296a8f1bf88193080ff992a195e66964ef2a6cfec5388", + "sha256:5be4a2e212bb6aa045e37f7d48e3e1e4b6fd259882ed5a00786f82e8c37ce77d", + "sha256:60a20bfc3bd234d54d49c388950195d23a5583d4108e1a1d47c9eef8d8c042b3", + "sha256:648914abafe67f11be7d93c1a546068f8eff3c5fa938e1f94509e4a5d682b2d8", + "sha256:681d75e1a38a69f1e64ab82fe4b1ed3fd758717bed735fb9aeaa124143f051af", + "sha256:68a5d77e440df94011214b7db907ec8f19e439507a70c958f750c18d88f995d2", + "sha256:69a63f83e88138ab7642d8f61418cf3180a4d8cd13995df87725cb8b893e950e", + "sha256:6e4183800f16f3679076dfa8abf2db3083919d7e30764a069fb66b2b9eff9939", + "sha256:6fd8d5903c2e53f49e99359b063df27fdf7acb89a52b6a12494208bf61345a03", + "sha256:791394449e98243839fa822a637177dd42a95f4883ad3dec2a0ce6ac99fb0a9d", + "sha256:7a7669ff50f41225ca5d6ee0a1ec8413f3a0d8aa2b109f86d540887b7ec0d72a", + "sha256:7e9eac1e526386df7c70ef253b792a0a12dd86d833b1d329e038c7a235dfceb5", + "sha256:7ee8af0b9f7de635c61cdd5b8534b76c52cd03536f29f51151b377f76e214a1a", + "sha256:8246f30ca34dc712ab07e51dc34fea883c00b7ccb0e614651e49da2c49a30711", + "sha256:8c88b599e226994ad4db29d93bc149aa1aff3dc3a4355dd5757569ba78632bdf", + "sha256:923963e989ffbceaa210ac37afc9b906acebe945d2723e9679b643513837b089", + "sha256:94d55bd03d8671686e3f012577d9caa5421a07286dd351dfef64791cf7c6c505", + "sha256:97db258793d193c7b62d4e2586c6ed98d51086e93f9a3af2b2034af01450a74b", + "sha256:a9d6bc8642e2c67db33f1247a77c53476f3a166e09067c0474facb045756087f", + "sha256:cd11c7e8d21af997ee8079037fff88f16fda188a9776eb4b81c7e4c9c0a7d7fc", + "sha256:d8d3d4713f0c28bdc6c806a278d998546e8efc3498949e3ace6e117462ac0a5e", + "sha256:e0bfe9bb028974a481410432dbe1b182e8191d5d40382e5b8ff39cdd2e5c5931", + "sha256:f4822c0660c3754f1a41a655e37cb4dbbc9be3d35b125a37fab6f82d47674ebc", + "sha256:f83d281bb2a6217cd806f4cf0ddded436790e66f393e124dfe9731f6b3fb9afe", + "sha256:fc37870d6716b137e80d19241d0e2cff7a7643b925dfa49b4c8ebd1295eb506e" ], "index": "pypi", - "version": "==4.6.1" + "version": "==4.6.2" }, "markdownify": { "hashes": [ - "sha256:30be8340724e706c9e811c27fe8c1542cf74a15b46827924fff5c54b40dd9b0d", - "sha256:a69588194fd76634f0139d6801b820fd652dc5eeba9530e90d323dfdc0155252" + "sha256:901c6106533f4a0b79cfe7c700c4df6b15cf782aa6236fd13161bf2608e2c591", + "sha256:f40874e3113a170697f0e74ea7aeee2d66eb9973201a5fbcc68ef8ce6bfbcf8a" ], "index": "pypi", - "version": "==0.5.3" + "version": "==0.6.0" }, "markupsafe": { "hashes": [ @@ -437,26 +457,46 @@ }, "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" }, "ordered-set": { "hashes": [ @@ -467,11 +507,11 @@ }, "packaging": { "hashes": [ - "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", - "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" + "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858", + "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.4" + "version": "==20.8" }, "pamqp": { "hashes": [ @@ -524,11 +564,11 @@ }, "pygments": { "hashes": [ - "sha256:381985fcc551eb9d37c52088a32914e00517e57f4a21609f48141ba08e193fa0", - "sha256:88a0bbcd659fcb9573703957c6b9cff9fab7295e6e76db54c9d00ae42df32773" + "sha256:ccf3acacf3782cbed4a989426012f1c535c9a90d3a7fc3f16d231b9372d2b716", + "sha256:f275b6c0909e5dafd2d6269a656aa90fa58ebf4a74f8fcf9053195d226b24a08" ], "markers": "python_version >= '3.5'", - "version": "==2.7.2" + "version": "==2.7.3" }, "pyparsing": { "hashes": [ @@ -555,18 +595,18 @@ }, "pyyaml": { "hashes": [ - "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", - "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", - "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e", "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", - "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", - "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", - "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", - "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" ], "index": "pypi", @@ -582,19 +622,19 @@ }, "requests": { "hashes": [ - "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8", - "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998" + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "index": "pypi", - "version": "==2.25.0" + "version": "==2.25.1" }, "sentry-sdk": { "hashes": [ - "sha256:1052f0ed084e532f66cb3e4ba617960d820152aee8b93fc6c05bd53861768c1c", - "sha256:4c42910a55a6b1fe694d5e4790d5188d105d77b5a6346c1c64cbea8c06c0e8b7" + "sha256:0a711ec952441c2ec89b8f5d226c33bc697914f46e876b44a4edd3e7864cf4d0", + "sha256:737a094e49a529dd0fdcaafa9e97cf7c3d5eb964bd229821d640bc77f3502b3f" ], "index": "pypi", - "version": "==0.19.4" + "version": "==0.19.5" }, "six": { "hashes": [ @@ -620,11 +660,11 @@ }, "soupsieve": { "hashes": [ - "sha256:1634eea42ab371d3d346309b93df7870a88610f0725d47528be902a0d95ecc55", - "sha256:a59dc181727e95d25f781f0eb4fd1825ff45590ec8ff49eadfd7f1a537cc0232" + "sha256:4bb21a6ee4707bf43b61230e80740e71bfe56e55d1f1f50924b087bb2975c851", + "sha256:6dc52924dc0bc710a5d16794e6b3480b2c7c08b07729505feab2b2c16661ff6e" ], "markers": "python_version >= '3.0'", - "version": "==2.0.1" + "version": "==2.1" }, "sphinx": { "hashes": [ @@ -690,6 +730,14 @@ "index": "pypi", "version": "==3.3.0" }, + "typing-extensions": { + "hashes": [ + "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", + "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", + "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" + ], + "version": "==3.7.4.3" + }, "urllib3": { "hashes": [ "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08", @@ -700,26 +748,46 @@ }, "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": { @@ -740,10 +808,10 @@ }, "certifi": { "hashes": [ - "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd", - "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4" + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" ], - "version": "==2020.11.8" + "version": "==2020.12.5" }, "cfgv": { "hashes": [ @@ -846,11 +914,11 @@ }, "flake8-bugbear": { "hashes": [ - "sha256:a3ddc03ec28ba2296fc6f89444d1c946a6b76460f859795b35b77d4920a51b63", - "sha256:bd02e4b009fb153fe6072c31c52aeab5b133d508095befb2ffcf3b41c4823162" + "sha256:528020129fea2dea33a466b9d64ab650aa3e5f9ffc788b70ea4bc6cf18283538", + "sha256:f35b8135ece7a014bc0aee5b5d485334ac30a6da48494998cc1fabf7ec70d703" ], "index": "pypi", - "version": "==20.1.4" + "version": "==20.11.1" }, "flake8-docstrings": { "hashes": [ @@ -885,11 +953,11 @@ }, "flake8-tidy-imports": { "hashes": [ - "sha256:62059ca07d8a4926b561d392cbab7f09ee042350214a25cf12823384a45d27dd", - "sha256:c30b40337a2e6802ba3bb611c26611154a27e94c53fc45639e3e282169574fd3" + "sha256:2821c79e83c656652d5ac6d3650ca370ed3c9752edb5383b1d50dee5bd8a383f", + "sha256:6cdd51e0d2f221e43ff4d5ac6331b1d95bbf4a5408906e36da913acaaed890e0" ], "index": "pypi", - "version": "==4.1.0" + "version": "==4.2.0" }, "flake8-todo": { "hashes": [ @@ -900,11 +968,11 @@ }, "identify": { "hashes": [ - "sha256:5dd84ac64a9a115b8e0b27d1756b244b882ad264c3c423f42af8235a6e71ca12", - "sha256:c9504ba6a043ee2db0a9d69e43246bc138034895f6338d5aed1b41e4a73b1513" + "sha256:943cd299ac7f5715fcb3f684e2fc1594c1e0f22a90d15398e5888143bd4144b5", + "sha256:cc86e6a9a390879dcc2976cef169dd9cc48843ed70b7380f321d1b118163c60e" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.9" + "version": "==1.5.10" }, "idna": { "hashes": [ @@ -938,11 +1006,11 @@ }, "pre-commit": { "hashes": [ - "sha256:22e6aa3bd571debb01eb7d34483f11c01b65237be4eebbf30c3d4fb65762d315", - "sha256:905ebc9b534b991baec87e934431f2d0606ba27f2b90f7f652985f5a5b8b6ae6" + "sha256:6c86d977d00ddc8a60d68eec19f51ef212d9462937acf3ea37c7adec32284ac0", + "sha256:ee784c11953e6d8badb97d19bc46b997a3a9eded849881ec587accd8608d74a4" ], "index": "pypi", - "version": "==2.8.2" + "version": "==2.9.3" }, "pycodestyle": { "hashes": [ @@ -970,18 +1038,18 @@ }, "pyyaml": { "hashes": [ - "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", - "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", - "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e", "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", - "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", - "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", - "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", - "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" ], "index": "pypi", @@ -989,11 +1057,11 @@ }, "requests": { "hashes": [ - "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8", - "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998" + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "index": "pypi", - "version": "==2.25.0" + "version": "==2.25.1" }, "six": { "hashes": [ @@ -1028,11 +1096,11 @@ }, "virtualenv": { "hashes": [ - "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2", - "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380" + "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c", + "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.1.0" + "version": "==20.2.2" } } } -- cgit v1.2.3 From 17e1ca32651ca9c16d94afc9987fecb80a2ea176 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 02:49:56 +0000 Subject: Fix linting errors --- bot/exts/moderation/verification.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index ad05888df..2b298950c 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -583,7 +583,6 @@ class Verification(Cog): @Cog.listener() async def on_member_update(self, before: discord.Member, after: discord.Member) -> None: """Check if we need to send a verification DM to a gated user.""" - if before.pending is True and after.pending is False: try: # If the member has not received a DM from our !accept command -- cgit v1.2.3 From d6e842f76e4f65cbd5d131cc341c8059a728393c Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 02:54:44 +0000 Subject: Remove member_gating_cache RedisDict --- bot/exts/moderation/verification.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 2b298950c..6239cf522 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -174,9 +174,6 @@ class Verification(Cog): # ] task_cache = RedisCache() - # Create a cache for storing recipients of the alternate welcome DM. - member_gating_cache = RedisCache() - def __init__(self, bot: Bot) -> None: """Start internal tasks.""" self.bot = bot -- cgit v1.2.3 From 539aaa28eae1204e90380167560a2ce57c4aea6e Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 03:05:06 +0000 Subject: Update discord.py name in Pipfile --- Pipfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 02b60b681..1f866e0ee 100644 --- a/Pipfile +++ b/Pipfile @@ -14,7 +14,7 @@ beautifulsoup4 = "~=4.9" colorama = {version = "~=0.4.3",sys_platform = "== 'win32'"} coloredlogs = "~=14.0" deepdiff = "~=4.0" -discord-py = {git = "https://github.com/Rapptz/discord.py.git", ref = "93f102ca907af6722ee03638766afd53dfe93a7f"} +"discord.py" = {git = "https://github.com/Rapptz/discord.py.git", ref = "93f102ca907af6722ee03638766afd53dfe93a7f"} feedparser = "~=5.2" fuzzywuzzy = "~=0.17" lxml = "~=4.4" -- cgit v1.2.3 From ee8c6d1f40a38a8f24c89e3103048bfe10bd1709 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 03:20:41 +0000 Subject: relock lockfile --- Pipfile.lock | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Pipfile.lock b/Pipfile.lock index c99a1d07d..aad0069db 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "1a759ddc72f37c3861b988fc99013690188e7c3e053eadc346d08054e912ec10" + "sha256": "3621b325f6395169e53a68d2f740232e10430fbca0150d936efd01a62d844b2c" }, "pipfile-spec": 6, "requires": { @@ -234,6 +234,10 @@ "git": "https://github.com/Rapptz/discord.py.git", "ref": "93f102ca907af6722ee03638766afd53dfe93a7f" }, + "discord.py": { + "git": "https://github.com/Rapptz/discord.py.git", + "ref": "93f102ca907af6722ee03638766afd53dfe93a7f" + }, "docutils": { "hashes": [ "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af", -- cgit v1.2.3 From fa60dc9b7bbbc8bdf06afc46c672015598c5df66 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 03:55:14 +0000 Subject: Remove usage of joined_at metricity API item --- bot/constants.py | 2 +- bot/exts/info/information.py | 19 +++++-------------- bot/exts/moderation/voice_gate.py | 10 ++-------- config-default.yml | 2 +- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/bot/constants.py b/bot/constants.py index 08ae0d52f..c4bb6b2d6 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -606,7 +606,7 @@ class Verification(metaclass=YAMLGetter): class VoiceGate(metaclass=YAMLGetter): section = "voice_gate" - minimum_days_verified: int + minimum_days_member: int minimum_messages: int bot_message_delete_delay: int minimum_activity_blocks: int diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 187950689..5450ff377 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -225,12 +225,12 @@ class Information(Cog): if is_set and (emoji := getattr(constants.Emojis, f"badge_{badge}", None)): badges.append(emoji) - verified_at, activity = await self.user_verification_and_messages(user) + activity = await self.user_messages(user) if on_server: joined = time_since(user.joined_at, max_units=3) roles = ", ".join(role.mention for role in user.roles[1:]) - membership = {"Joined": joined, "Verified": verified_at or "False", "Roles": roles or None} + membership = {"Joined": joined, "Verified": user.pending, "Roles": roles or None} if not is_mod_channel(ctx.channel): membership.pop("Verified") @@ -360,30 +360,21 @@ class Information(Cog): return "Nominations", "\n".join(output) - async def user_verification_and_messages(self, user: FetchedMember) -> Tuple[Union[bool, str], Tuple[str, str]]: + async def user_messages(self, user: FetchedMember) -> Tuple[Union[bool, str], Tuple[str, str]]: """ - Gets the time of verification and amount of messages for `member`. + Gets the amount of messages for `member`. Fetches information from the metricity database that's hosted by the site. If the database returns a code besides a 404, then many parts of the bot are broken including this one. """ activity_output = [] - verified_at = False try: user_activity = await self.bot.api_client.get(f"bot/users/{user.id}/metricity_data") except ResponseCodeError as e: if e.status == 404: activity_output = "No activity" - else: - try: - if (verified_at := user_activity["verified_at"]) is not None: - verified_at = time_since(parser.isoparse(verified_at), max_units=3) - except ValueError: - log.warning(f"Could not parse ISO string correctly for user {user.id} verification date.") - verified_at = None - activity_output.append(user_activity["total_messages"] or "No messages") activity_output.append(user_activity["activity_blocks"] or "No activity") @@ -391,7 +382,7 @@ class Information(Cog): f"{name}: {metric}" for name, metric in zip(["Messages", "Activity blocks"], activity_output) ) - return verified_at, ("Activity", activity_output) + return ("Activity", activity_output) def format_fields(self, mapping: Mapping[str, Any], field_width: Optional[int] = None) -> str: """Format a mapping to be readable to a human.""" diff --git a/bot/exts/moderation/voice_gate.py b/bot/exts/moderation/voice_gate.py index 4d48d2c1b..b8f37adf2 100644 --- a/bot/exts/moderation/voice_gate.py +++ b/bot/exts/moderation/voice_gate.py @@ -29,7 +29,7 @@ FAILED_MESSAGE = ( ) MESSAGE_FIELD_MAP = { - "verified_at": f"have been verified for less than {GateConf.minimum_days_verified} days", + "joined_at": f"have been on the server for less than {GateConf.minimum_days_member} days", "voice_banned": "have an active voice ban infraction", "total_messages": f"have sent less than {GateConf.minimum_messages} messages", "activity_blocks": f"have been active for fewer than {GateConf.minimum_activity_blocks} ten-minute blocks", @@ -149,14 +149,8 @@ class VoiceGate(Cog): await ctx.author.send(embed=embed) return - # Pre-parse this for better code style - if data["verified_at"] is not None: - data["verified_at"] = parser.isoparse(data["verified_at"]) - else: - data["verified_at"] = datetime.utcnow() - timedelta(days=3) - checks = { - "verified_at": data["verified_at"] > datetime.utcnow() - timedelta(days=GateConf.minimum_days_verified), + "joined_at": ctx.author.joined_at > datetime.utcnow() - timedelta(days=GateConf.minimum_days_verified), "total_messages": data["total_messages"] < GateConf.minimum_messages, "voice_banned": data["voice_banned"], "activity_blocks": data["activity_blocks"] < GateConf.minimum_activity_blocks diff --git a/config-default.yml b/config-default.yml index 006743342..3f3f66962 100644 --- a/config-default.yml +++ b/config-default.yml @@ -526,7 +526,7 @@ verification: voice_gate: - minimum_days_verified: 3 # How many days the user must have been verified for + minimum_days_member: 3 # How many days the user must have been a member for minimum_messages: 50 # How many messages a user must have to be eligible for voice bot_message_delete_delay: 10 # Seconds before deleting bot's response in Voice Gate minimum_activity_blocks: 3 # Number of 10 minute blocks during which a user must have been active -- cgit v1.2.3 From 3be657effd8ad6d5f54a536c12f5b82ea91fd571 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 03:56:49 +0000 Subject: Remove unused dateutil imports --- bot/exts/info/information.py | 1 - bot/exts/moderation/voice_gate.py | 1 - 2 files changed, 2 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 5450ff377..15f96db3a 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -6,7 +6,6 @@ from collections import Counter, defaultdict from string import Template from typing import Any, Mapping, Optional, Tuple, Union -from dateutil import parser from discord import ChannelType, Colour, Embed, Guild, Message, Role, Status, utils from discord.abc import GuildChannel from discord.ext.commands import BucketType, Cog, Context, Paginator, command, group, has_any_role diff --git a/bot/exts/moderation/voice_gate.py b/bot/exts/moderation/voice_gate.py index b8f37adf2..cc0ac0118 100644 --- a/bot/exts/moderation/voice_gate.py +++ b/bot/exts/moderation/voice_gate.py @@ -5,7 +5,6 @@ from datetime import datetime, timedelta import discord from async_rediscache import RedisCache -from dateutil import parser from discord import Colour, Member, VoiceState from discord.ext.commands import Cog, Context, command -- cgit v1.2.3 From 688908d1d996708525b9125a20e7c72b4413b252 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 04:00:59 +0000 Subject: Fix pending tests --- bot/exts/info/information.py | 4 ++-- tests/bot/exts/info/test_information.py | 2 +- tests/helpers.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 15f96db3a..2057876e4 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -229,9 +229,9 @@ class Information(Cog): if on_server: joined = time_since(user.joined_at, max_units=3) roles = ", ".join(role.mention for role in user.roles[1:]) - membership = {"Joined": joined, "Verified": user.pending, "Roles": roles or None} + membership = {"Joined": joined, "Pending": user.pending, "Roles": roles or None} if not is_mod_channel(ctx.channel): - membership.pop("Verified") + membership.pop("Pending") membership = textwrap.dedent("\n".join([f"{key}: {value}" for key, value in membership.items()])) else: diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index 254b0a867..043cce8de 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -355,7 +355,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): self.assertEqual( textwrap.dedent(f""" Joined: {"1 year ago"} - Verified: {"False"} + Pending: {"False"} Roles: &Moderators """).strip(), embed.fields[1].value diff --git a/tests/helpers.py b/tests/helpers.py index 870f66197..496363ae3 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -230,7 +230,7 @@ class MockMember(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin spec_set = member_instance def __init__(self, roles: Optional[Iterable[MockRole]] = None, **kwargs) -> None: - default_kwargs = {'name': 'member', 'id': next(self.discord_id), 'bot': False} + default_kwargs = {'name': 'member', 'id': next(self.discord_id), 'bot': False, "pending": False} super().__init__(**collections.ChainMap(kwargs, default_kwargs)) self.roles = [MockRole(name="@everyone", position=1, id=0)] -- cgit v1.2.3 From 620fa3fb82d1de8424a699a1b6676eeddd04eba2 Mon Sep 17 00:00:00 2001 From: Den4200 Date: Fri, 18 Dec 2020 23:06:44 -0500 Subject: Downgrade `markdownify` from 0.6.0 to 0.5.3. 0.6.0 brought breaking changes to markdownify, so we'll downgrade. --- Pipfile | 2 +- Pipfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Pipfile b/Pipfile index 1f866e0ee..23422869d 100644 --- a/Pipfile +++ b/Pipfile @@ -18,7 +18,7 @@ deepdiff = "~=4.0" feedparser = "~=5.2" fuzzywuzzy = "~=0.17" lxml = "~=4.4" -markdownify = "~=0.4" +markdownify = "==0.5.3" more_itertools = "~=8.2" python-dateutil = "~=2.8" pyyaml = "~=5.1" diff --git a/Pipfile.lock b/Pipfile.lock index aad0069db..ca72fb0f3 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3621b325f6395169e53a68d2f740232e10430fbca0150d936efd01a62d844b2c" + "sha256": "bfaf61339c0cebb10d76f2e14ff967030008b8512b5f0b4c23c9e8997aab4552" }, "pipfile-spec": 6, "requires": { @@ -406,11 +406,11 @@ }, "markdownify": { "hashes": [ - "sha256:901c6106533f4a0b79cfe7c700c4df6b15cf782aa6236fd13161bf2608e2c591", - "sha256:f40874e3113a170697f0e74ea7aeee2d66eb9973201a5fbcc68ef8ce6bfbcf8a" + "sha256:30be8340724e706c9e811c27fe8c1542cf74a15b46827924fff5c54b40dd9b0d", + "sha256:a69588194fd76634f0139d6801b820fd652dc5eeba9530e90d323dfdc0155252" ], "index": "pypi", - "version": "==0.6.0" + "version": "==0.5.3" }, "markupsafe": { "hashes": [ -- cgit v1.2.3 From 975562236d356ca43f8ed037d7048eb410abfe26 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 04:10:26 +0000 Subject: Fix invalid config name in voice gate --- bot/exts/moderation/voice_gate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/moderation/voice_gate.py b/bot/exts/moderation/voice_gate.py index cc0ac0118..0cbce6a51 100644 --- a/bot/exts/moderation/voice_gate.py +++ b/bot/exts/moderation/voice_gate.py @@ -149,7 +149,7 @@ class VoiceGate(Cog): return checks = { - "joined_at": ctx.author.joined_at > datetime.utcnow() - timedelta(days=GateConf.minimum_days_verified), + "joined_at": ctx.author.joined_at > datetime.utcnow() - timedelta(days=GateConf.minimum_days_member), "total_messages": data["total_messages"] < GateConf.minimum_messages, "voice_banned": data["voice_banned"], "activity_blocks": data["activity_blocks"] < GateConf.minimum_activity_blocks -- cgit v1.2.3 From c4545d8f5206e296bcecfd87236be57fbc91b778 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 04:21:52 +0000 Subject: Fix silence command to use guild default role --- bot/exts/moderation/silence.py | 14 +++++++------- tests/bot/exts/moderation/test_silence.py | 9 --------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/bot/exts/moderation/silence.py b/bot/exts/moderation/silence.py index e6712b3b6..a942d5294 100644 --- a/bot/exts/moderation/silence.py +++ b/bot/exts/moderation/silence.py @@ -93,7 +93,7 @@ class Silence(commands.Cog): await self.bot.wait_until_guild_available() guild = self.bot.get_guild(Guild.id) - self._verified_role = guild.get_role(Roles.verified) + self._everyone_role = guild.default_role self._mod_alerts_channel = self.bot.get_channel(Channels.mod_alerts) self.notifier = SilenceNotifier(self.bot.get_channel(Channels.mod_log)) await self._reschedule() @@ -142,7 +142,7 @@ class Silence(commands.Cog): async def _unsilence_wrapper(self, channel: TextChannel) -> None: """Unsilence `channel` and send a success/failure message.""" if not await self._unsilence(channel): - overwrite = channel.overwrites_for(self._verified_role) + overwrite = channel.overwrites_for(self._everyone_role) if overwrite.send_messages is False or overwrite.add_reactions is False: await channel.send(MSG_UNSILENCE_MANUAL) else: @@ -152,14 +152,14 @@ class Silence(commands.Cog): async def _set_silence_overwrites(self, channel: TextChannel) -> bool: """Set silence permission overwrites for `channel` and return True if successful.""" - overwrite = channel.overwrites_for(self._verified_role) + overwrite = channel.overwrites_for(self._everyone_role) prev_overwrites = dict(send_messages=overwrite.send_messages, add_reactions=overwrite.add_reactions) if channel.id in self.scheduler or all(val is False for val in prev_overwrites.values()): return False overwrite.update(send_messages=False, add_reactions=False) - await channel.set_permissions(self._verified_role, overwrite=overwrite) + await channel.set_permissions(self._everyone_role, overwrite=overwrite) await self.previous_overwrites.set(channel.id, json.dumps(prev_overwrites)) return True @@ -188,14 +188,14 @@ class Silence(commands.Cog): log.info(f"Tried to unsilence channel #{channel} ({channel.id}) but the channel was not silenced.") return False - overwrite = channel.overwrites_for(self._verified_role) + overwrite = channel.overwrites_for(self._everyone_role) if prev_overwrites is None: log.info(f"Missing previous overwrites for #{channel} ({channel.id}); defaulting to None.") overwrite.update(send_messages=None, add_reactions=None) else: overwrite.update(**json.loads(prev_overwrites)) - await channel.set_permissions(self._verified_role, overwrite=overwrite) + await channel.set_permissions(self._everyone_role, overwrite=overwrite) log.info(f"Unsilenced channel #{channel} ({channel.id}).") self.scheduler.cancel(channel.id) @@ -207,7 +207,7 @@ class Silence(commands.Cog): await self._mod_alerts_channel.send( f"<@&{Roles.admins}> Restored overwrites with default values after unsilencing " f"{channel.mention}. Please check that the `Send Messages` and `Add Reactions` " - f"overwrites for {self._verified_role.mention} are at their desired values." + f"overwrites for {self._everyone_role.mention} are at their desired values." ) return True diff --git a/tests/bot/exts/moderation/test_silence.py b/tests/bot/exts/moderation/test_silence.py index 104293d8e..5c89a2f2a 100644 --- a/tests/bot/exts/moderation/test_silence.py +++ b/tests/bot/exts/moderation/test_silence.py @@ -116,15 +116,6 @@ class SilenceCogTests(unittest.IsolatedAsyncioTestCase): self.bot.wait_until_guild_available.assert_awaited_once() self.bot.get_guild.assert_called_once_with(Guild.id) - @autospec(silence, "SilenceNotifier", pass_mocks=False) - async def test_async_init_got_role(self): - """Got `Roles.verified` role from guild.""" - guild = self.bot.get_guild() - guild.get_role.side_effect = lambda id_: Mock(id=id_) - - await self.cog._async_init() - self.assertEqual(self.cog._verified_role.id, Roles.verified) - @autospec(silence, "SilenceNotifier", pass_mocks=False) async def test_async_init_got_channels(self): """Got channels from bot.""" -- cgit v1.2.3 From d76a1a676fbdb1f79814ae50b4a28ebc746bccf6 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 04:22:07 +0000 Subject: kaizen: remove role check from bot account commands --- bot/exts/utils/bot.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bot/exts/utils/bot.py b/bot/exts/utils/bot.py index 69d623581..03c98677f 100644 --- a/bot/exts/utils/bot.py +++ b/bot/exts/utils/bot.py @@ -17,13 +17,11 @@ class BotCog(Cog, name="Bot"): self.bot = bot @group(invoke_without_command=True, name="bot", hidden=True) - @has_any_role(Roles.verified) async def botinfo_group(self, ctx: Context) -> None: """Bot informational commands.""" await ctx.send_help(ctx.command) @botinfo_group.command(name='about', aliases=('info',), hidden=True) - @has_any_role(Roles.verified) async def about_command(self, ctx: Context) -> None: """Get information about the bot.""" embed = Embed( -- cgit v1.2.3 From bc98110449933086fdfee7d949074caf9c4f0553 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 04:23:21 +0000 Subject: Remove unused import --- bot/exts/utils/bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/utils/bot.py b/bot/exts/utils/bot.py index 03c98677f..a4c828f95 100644 --- a/bot/exts/utils/bot.py +++ b/bot/exts/utils/bot.py @@ -5,7 +5,7 @@ from discord import Embed, TextChannel from discord.ext.commands import Cog, Context, command, group, has_any_role from bot.bot import Bot -from bot.constants import Guild, MODERATION_ROLES, Roles, URLs +from bot.constants import Guild, MODERATION_ROLES, URLs log = logging.getLogger(__name__) -- cgit v1.2.3 From 9799020de67c9350ee57f9ee3edff348a718cf6b Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 04:27:01 +0000 Subject: Fix silence tests --- tests/bot/exts/moderation/test_silence.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/bot/exts/moderation/test_silence.py b/tests/bot/exts/moderation/test_silence.py index 5c89a2f2a..fa5fc9e81 100644 --- a/tests/bot/exts/moderation/test_silence.py +++ b/tests/bot/exts/moderation/test_silence.py @@ -293,7 +293,7 @@ class SilenceTests(unittest.IsolatedAsyncioTestCase): self.assertFalse(self.overwrite.send_messages) self.assertFalse(self.overwrite.add_reactions) self.channel.set_permissions.assert_awaited_once_with( - self.cog._verified_role, + self.cog._everyone_role, overwrite=self.overwrite ) @@ -426,7 +426,7 @@ class UnsilenceTests(unittest.IsolatedAsyncioTestCase): """Channel's `send_message` and `add_reactions` overwrites were restored.""" await self.cog._unsilence(self.channel) self.channel.set_permissions.assert_awaited_once_with( - self.cog._verified_role, + self.cog._everyone_role, overwrite=self.overwrite, ) @@ -440,7 +440,7 @@ class UnsilenceTests(unittest.IsolatedAsyncioTestCase): await self.cog._unsilence(self.channel) self.channel.set_permissions.assert_awaited_once_with( - self.cog._verified_role, + self.cog._everyone_role, overwrite=self.overwrite, ) -- cgit v1.2.3 From d744dc779cd7c3b128cf28830f54a0dc2aecc574 Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sat, 19 Dec 2020 10:45:33 -0800 Subject: APIClient: simplify session creation Making the class-reusable is not worth the added complexity. --- bot/api.py | 42 ++++++------------------------------------ bot/bot.py | 7 ++++--- 2 files changed, 10 insertions(+), 39 deletions(-) diff --git a/bot/api.py b/bot/api.py index 4b8520582..6436c2b8b 100644 --- a/bot/api.py +++ b/bot/api.py @@ -50,52 +50,22 @@ class APIClient: self.session = None self.loop = loop - self._ready = asyncio.Event(loop=loop) - self._creation_task = None - self._default_session_kwargs = kwargs - - self.recreate() + # It has to be instantiated in a task/coroutine to avoid warnings from aiohttp. + self._creation_task = self.loop.create_task(self._create_session(**kwargs)) @staticmethod def _url_for(endpoint: str) -> str: return f"{URLs.site_schema}{URLs.site_api}/{quote_url(endpoint)}" async def _create_session(self, **session_kwargs) -> None: - """ - Create the aiohttp session with `session_kwargs` and set the ready event. - - `session_kwargs` is merged with `_default_session_kwargs` and overwrites its values. - If an open session already exists, it will first be closed. - """ - await self.close() - self.session = aiohttp.ClientSession(**{**self._default_session_kwargs, **session_kwargs}) - self._ready.set() + """Create the aiohttp session with `session_kwargs`.""" + self.session = aiohttp.ClientSession(**session_kwargs) async def close(self) -> None: """Close the aiohttp session and unset the ready event.""" if self.session: await self.session.close() - self._ready.clear() - - def recreate(self, force: bool = False, **session_kwargs) -> None: - """ - Schedule the aiohttp session to be created with `session_kwargs` if it's been closed. - - If `force` is True, the session will be recreated even if an open one exists. If a task to - create the session is pending, it will be cancelled. - - `session_kwargs` is merged with the kwargs given when the `APIClient` was created and - overwrites those default kwargs. - """ - if force or self.session is None or self.session.closed: - if force and self._creation_task: - self._creation_task.cancel() - - # Don't schedule a task if one is already in progress. - if force or self._creation_task is None or self._creation_task.done(): - self._creation_task = self.loop.create_task(self._create_session(**session_kwargs)) - async def maybe_raise_for_status(self, response: aiohttp.ClientResponse, should_raise: bool) -> None: """Raise ResponseCodeError for non-OK response if an exception should be raised.""" if should_raise and response.status >= 400: @@ -108,7 +78,7 @@ class APIClient: async def request(self, method: str, endpoint: str, *, raise_for_status: bool = True, **kwargs) -> dict: """Send an HTTP request to the site API and return the JSON response.""" - await self._ready.wait() + await self._creation_task async with self.session.request(method.upper(), self._url_for(endpoint), **kwargs) as resp: await self.maybe_raise_for_status(resp, raise_for_status) @@ -132,7 +102,7 @@ class APIClient: async def delete(self, endpoint: str, *, raise_for_status: bool = True, **kwargs) -> Optional[dict]: """Site API DELETE.""" - await self._ready.wait() + await self._creation_task async with self.session.delete(self._url_for(endpoint), **kwargs) as resp: if resp.status == 204: diff --git a/bot/bot.py b/bot/bot.py index f71f5d1fb..1715f3ca3 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -32,7 +32,7 @@ class Bot(commands.Bot): self.http_session: Optional[aiohttp.ClientSession] = None self.redis_session = redis_session - self.api_client = api.APIClient(loop=self.loop) + self.api_client = None self.filter_list_cache = defaultdict(dict) self._connector = None @@ -112,7 +112,7 @@ class Bot(commands.Bot): ) self.http_session = aiohttp.ClientSession(connector=self._connector) - self.api_client.recreate(force=True, connector=self._connector) + self.api_client = api.APIClient(loop=self.loop, connector=self._connector) # Build the FilterList cache self.loop.create_task(self.cache_filter_list_data()) @@ -194,7 +194,8 @@ class Bot(commands.Bot): """Close the Discord connection and the aiohttp session, connector, statsd client, and resolver.""" await super().close() - await self.api_client.close() + if self.api_client: + await self.api_client.close() if self.http_session: await self.http_session.close() -- cgit v1.2.3 From 2021c78635de4ae5a9f9835944c87cba699b41c0 Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sat, 19 Dec 2020 10:46:26 -0800 Subject: APIClient: remove obsolete function --- bot/api.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/bot/api.py b/bot/api.py index 6436c2b8b..ce3f2ada3 100644 --- a/bot/api.py +++ b/bot/api.py @@ -110,17 +110,3 @@ class APIClient: await self.maybe_raise_for_status(resp, raise_for_status) return await resp.json() - - -def loop_is_running() -> bool: - """ - Determine if there is a running asyncio event loop. - - This helps enable "call this when event loop is running" logic (see: Twisted's `callWhenRunning`), - which is currently not provided by asyncio. - """ - try: - asyncio.get_running_loop() - except RuntimeError: - return False - return True -- cgit v1.2.3 From 598c4a50c0c4f2e0c2139d6c349ee183010dbf78 Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sat, 19 Dec 2020 10:59:09 -0800 Subject: Bot: cease support of Bot.clear() Supporting the function means supporting re-use of a closed Bot. However, this functionality is not relied upon by anything nor will it ever be in the foreseeable future. Support of it required scheduling any needed startup coroutines as tasks. This made augmenting the Bot clunky and didn't make it easy to wait for startup coroutines to complete before logging in. --- bot/bot.py | 79 ++++++++++++++++++++++---------------------------------------- 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/bot/bot.py b/bot/bot.py index 1715f3ca3..b01cbea43 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -32,7 +32,7 @@ class Bot(commands.Bot): self.http_session: Optional[aiohttp.ClientSession] = None self.redis_session = redis_session - self.api_client = None + self.api_client: Optional[api.APIClient] = None self.filter_list_cache = defaultdict(dict) self._connector = None @@ -77,46 +77,6 @@ class Bot(commands.Bot): for item in full_cache: self.insert_item_into_filter_list_cache(item) - def _recreate(self) -> None: - """Re-create the connector, aiohttp session, the APIClient and the Redis session.""" - # Use asyncio for DNS resolution instead of threads so threads aren't spammed. - # Doesn't seem to have any state with regards to being closed, so no need to worry? - self._resolver = aiohttp.AsyncResolver() - - # Its __del__ does send a warning but it doesn't always show up for some reason. - if self._connector and not self._connector._closed: - log.warning( - "The previous connector was not closed; it will remain open and be overwritten" - ) - - if self.redis_session.closed: - # If the RedisSession was somehow closed, we try to reconnect it - # here. Normally, this shouldn't happen. - self.loop.create_task(self.redis_session.connect()) - - # Use AF_INET as its socket family to prevent HTTPS related problems both locally - # and in production. - self._connector = aiohttp.TCPConnector( - resolver=self._resolver, - family=socket.AF_INET, - ) - - # Client.login() will call HTTPClient.static_login() which will create a session using - # this connector attribute. - self.http.connector = self._connector - - # Its __del__ does send a warning but it doesn't always show up for some reason. - if self.http_session and not self.http_session.closed: - log.warning( - "The previous session was not closed; it will remain open and be overwritten" - ) - - self.http_session = aiohttp.ClientSession(connector=self._connector) - self.api_client = api.APIClient(loop=self.loop, connector=self._connector) - - # Build the FilterList cache - self.loop.create_task(self.cache_filter_list_data()) - @classmethod def create(cls) -> "Bot": """Create and return an instance of a Bot.""" @@ -180,15 +140,8 @@ class Bot(commands.Bot): return command def clear(self) -> None: - """ - Clears the internal state of the bot and recreates the connector and sessions. - - Will cause a DeprecationWarning if called outside a coroutine. - """ - # Because discord.py recreates the HTTPClient session, may as well follow suit and recreate - # our own stuff here too. - self._recreate() - super().clear() + """Not implemented! Re-instantiate the bot instead of attempting to re-use a closed one.""" + raise NotImplementedError("Re-using a Bot object after closing it is not supported.") async def close(self) -> None: """Close the Discord connection and the aiohttp session, connector, statsd client, and resolver.""" @@ -230,7 +183,31 @@ class Bot(commands.Bot): async def login(self, *args, **kwargs) -> None: """Re-create the connector and set up sessions before logging into Discord.""" - self._recreate() + # Use asyncio for DNS resolution instead of threads so threads aren't spammed. + self._resolver = aiohttp.AsyncResolver() + + # Use AF_INET as its socket family to prevent HTTPS related problems both locally + # and in production. + self._connector = aiohttp.TCPConnector( + resolver=self._resolver, + family=socket.AF_INET, + ) + + # Client.login() will call HTTPClient.static_login() which will create a session using + # this connector attribute. + self.http.connector = self._connector + + self.http_session = aiohttp.ClientSession(connector=self._connector) + self.api_client = api.APIClient(loop=self.loop, connector=self._connector) + + if self.redis_session.closed: + # If the RedisSession was somehow closed, we try to reconnect it + # here. Normally, this shouldn't happen. + await self.redis_session.connect() + + # Build the FilterList cache + await self.cache_filter_list_data() + await self.stats.create_socket() await super().login(*args, **kwargs) -- cgit v1.2.3 From c58fbe828781444fc282151c06c2f4fb9057fe59 Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sat, 19 Dec 2020 11:29:05 -0800 Subject: APIClient: create the session directly in __init__ The client is already instantiated in a coroutine and aiohttp won't complain. Therefore, scheduling a task to create the session is redundant. --- bot/api.py | 29 +++++++++-------------------- bot/bot.py | 2 +- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/bot/api.py b/bot/api.py index ce3f2ada3..d93f9f2ba 100644 --- a/bot/api.py +++ b/bot/api.py @@ -37,34 +37,27 @@ class APIClient: session: Optional[aiohttp.ClientSession] = None loop: asyncio.AbstractEventLoop = None - def __init__(self, loop: asyncio.AbstractEventLoop, **kwargs): + def __init__(self, **session_kwargs): auth_headers = { 'Authorization': f"Token {Keys.site_api}" } - if 'headers' in kwargs: - kwargs['headers'].update(auth_headers) + if 'headers' in session_kwargs: + session_kwargs['headers'].update(auth_headers) else: - kwargs['headers'] = auth_headers + session_kwargs['headers'] = auth_headers - self.session = None - self.loop = loop - - # It has to be instantiated in a task/coroutine to avoid warnings from aiohttp. - self._creation_task = self.loop.create_task(self._create_session(**kwargs)) + # aiohttp will complain if APIClient gets instantiated outside a coroutine. Thankfully, we + # don't and shouldn't need to do that, so we can avoid scheduling a task to create it. + self.session = aiohttp.ClientSession(**session_kwargs) @staticmethod def _url_for(endpoint: str) -> str: return f"{URLs.site_schema}{URLs.site_api}/{quote_url(endpoint)}" - async def _create_session(self, **session_kwargs) -> None: - """Create the aiohttp session with `session_kwargs`.""" - self.session = aiohttp.ClientSession(**session_kwargs) - async def close(self) -> None: - """Close the aiohttp session and unset the ready event.""" - if self.session: - await self.session.close() + """Close the aiohttp session.""" + await self.session.close() async def maybe_raise_for_status(self, response: aiohttp.ClientResponse, should_raise: bool) -> None: """Raise ResponseCodeError for non-OK response if an exception should be raised.""" @@ -78,8 +71,6 @@ class APIClient: async def request(self, method: str, endpoint: str, *, raise_for_status: bool = True, **kwargs) -> dict: """Send an HTTP request to the site API and return the JSON response.""" - await self._creation_task - async with self.session.request(method.upper(), self._url_for(endpoint), **kwargs) as resp: await self.maybe_raise_for_status(resp, raise_for_status) return await resp.json() @@ -102,8 +93,6 @@ class APIClient: async def delete(self, endpoint: str, *, raise_for_status: bool = True, **kwargs) -> Optional[dict]: """Site API DELETE.""" - await self._creation_task - async with self.session.delete(self._url_for(endpoint), **kwargs) as resp: if resp.status == 204: return None diff --git a/bot/bot.py b/bot/bot.py index b01cbea43..4ebe0a5c3 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -198,7 +198,7 @@ class Bot(commands.Bot): self.http.connector = self._connector self.http_session = aiohttp.ClientSession(connector=self._connector) - self.api_client = api.APIClient(loop=self.loop, connector=self._connector) + self.api_client = api.APIClient(connector=self._connector) if self.redis_session.closed: # If the RedisSession was somehow closed, we try to reconnect it -- cgit v1.2.3 From 52ee0dab1e59089a7acc9f08078dee0df3fa40e6 Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sat, 19 Dec 2020 11:33:37 -0800 Subject: Remove obsolete test cases Forgot to remove these when removing `loop_is_running` in a previous commit. --- tests/bot/test_api.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/bot/test_api.py b/tests/bot/test_api.py index 99e942813..76bcb481d 100644 --- a/tests/bot/test_api.py +++ b/tests/bot/test_api.py @@ -13,14 +13,6 @@ class APIClientTests(unittest.IsolatedAsyncioTestCase): cls.error_api_response = MagicMock() cls.error_api_response.status = 999 - def test_loop_is_not_running_by_default(self): - """The event loop should not be running by default.""" - self.assertFalse(api.loop_is_running()) - - async def test_loop_is_running_in_async_context(self): - """The event loop should be running in an async context.""" - self.assertTrue(api.loop_is_running()) - def test_response_code_error_default_initialization(self): """Test the default initialization of `ResponseCodeError` without `text` or `json`""" error = api.ResponseCodeError(response=self.error_api_response) -- cgit v1.2.3 From 6115f5a9f9c4c72e3ec7cac02372f10135b836bc Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Sun, 20 Dec 2020 16:56:27 +0100 Subject: Add the clear alias to the clean command --- bot/exts/utils/clean.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/utils/clean.py b/bot/exts/utils/clean.py index bf25cb4c2..8acaf9131 100644 --- a/bot/exts/utils/clean.py +++ b/bot/exts/utils/clean.py @@ -191,7 +191,7 @@ class Clean(Cog): channel_id=Channels.mod_log, ) - @group(invoke_without_command=True, name="clean", aliases=["purge"]) + @group(invoke_without_command=True, name="clean", aliases=["clear", "purge"]) @has_any_role(*MODERATION_ROLES) async def clean_group(self, ctx: Context) -> None: """Commands for cleaning messages in channels.""" -- cgit v1.2.3