From 695e903640d6c394dd4f23aa12fef4c7336dc74e Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sat, 16 Apr 2022 16:46:05 +0100 Subject: Output max 10 bumped threads on list --- bot/exts/utils/thread_bumper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/utils/thread_bumper.py b/bot/exts/utils/thread_bumper.py index ee0636b37..6d1c64956 100644 --- a/bot/exts/utils/thread_bumper.py +++ b/bot/exts/utils/thread_bumper.py @@ -111,7 +111,7 @@ class ThreadBumper(commands.Cog): title="Threads in the bump list", colour=constants.Colours.blue ) - await LinePaginator.paginate(lines, ctx, embed) + await LinePaginator.paginate(lines, ctx, embed, max_lines=10) @commands.Cog.listener() async def on_thread_update(self, _: discord.Thread, after: discord.Thread) -> None: -- cgit v1.2.3 From 90d4f908400a09cee127406805d0a7556c26315c Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sat, 16 Apr 2022 17:11:51 +0100 Subject: Use site api over redis for thread bumps --- bot/exts/utils/thread_bumper.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/bot/exts/utils/thread_bumper.py b/bot/exts/utils/thread_bumper.py index 6d1c64956..6bd9efc08 100644 --- a/bot/exts/utils/thread_bumper.py +++ b/bot/exts/utils/thread_bumper.py @@ -2,6 +2,7 @@ import typing as t import discord from async_rediscache import RedisCache +from botcore.site_api import ResponseCodeError from discord.ext import commands from bot import constants @@ -11,6 +12,7 @@ from bot.pagination import LinePaginator from bot.utils import channel log = get_logger(__name__) +THREAD_BUMP_ENDPOINT = "bot/bumped-threads" class ThreadBumper(commands.Cog): @@ -45,7 +47,7 @@ class ThreadBumper(commands.Cog): thread.name, thread.id ) - await self.threads_to_bump.delete(thread.id) + await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread.id}") else: await thread.edit(archived=False) @@ -54,12 +56,16 @@ class ThreadBumper(commands.Cog): await self.bot.wait_until_guild_available() threads_to_maybe_bump = [] - for thread_id, _ in await self.threads_to_bump.items(): + for thread_id in await self.bot.api_client.get(THREAD_BUMP_ENDPOINT): try: thread = await channel.get_or_fetch_channel(thread_id) except discord.NotFound: log.info("Thread %d has been deleted, removing from bumped threads.", thread_id) - await self.threads_to_bump.delete(thread_id) + await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread_id}") + continue + + if not isinstance(thread, discord.Thread): + await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread_id}") continue if thread.archived: @@ -82,10 +88,14 @@ class ThreadBumper(commands.Cog): else: raise commands.BadArgument("You must provide a thread, or run this command within a thread.") - if await self.threads_to_bump.contains(thread.id): + try: + await self.bot.api_client.get(f"{THREAD_BUMP_ENDPOINT}/{thread.id}") + except ResponseCodeError: + pass + else: raise commands.BadArgument("This thread is already in the bump list.") - await self.threads_to_bump.set(thread.id, "sentinel") + await self.bot.api_client.post(THREAD_BUMP_ENDPOINT, data={"thread_id": thread.id}) await ctx.send(f":ok_hand:{thread.mention} has been added to the bump list.") @thread_bump_group.command(name="remove", aliases=("r", "rem", "d", "del", "delete")) @@ -97,16 +107,18 @@ class ThreadBumper(commands.Cog): else: raise commands.BadArgument("You must provide a thread, or run this command within a thread.") - if not await self.threads_to_bump.contains(thread.id): + try: + await self.bot.api_client.get(f"{THREAD_BUMP_ENDPOINT}/{thread.id}") + except ResponseCodeError: raise commands.BadArgument("This thread is not in the bump list.") - await self.threads_to_bump.delete(thread.id) + await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread.id}") await ctx.send(f":ok_hand: {thread.mention} has been removed from the bump list.") @thread_bump_group.command(name="list", aliases=("get",)) async def list_all_threads_in_bump_list(self, ctx: commands.Context) -> None: """List all the threads in the bump list.""" - lines = [f"<#{k}>" for k, _ in await self.threads_to_bump.items()] + lines = [f"<#{thread_id}>" for thread_id in await self.bot.api_client.get(THREAD_BUMP_ENDPOINT)] embed = discord.Embed( title="Threads in the bump list", colour=constants.Colours.blue @@ -123,7 +135,11 @@ class ThreadBumper(commands.Cog): if not after.archived: return - if await self.threads_to_bump.contains(after.id): + try: + await self.bot.api_client.get(f"{THREAD_BUMP_ENDPOINT}/{after.id}") + except ResponseCodeError: + pass + else: await self.unarchive_threads_not_manually_archived([after]) async def cog_check(self, ctx: commands.Context) -> bool: -- cgit v1.2.3 From a196ec9d49c8da3bcca0f6a84b06b383797e6af7 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sat, 16 Apr 2022 17:14:31 +0100 Subject: Only call unarchive threads if there are threads to send --- bot/exts/utils/thread_bumper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/exts/utils/thread_bumper.py b/bot/exts/utils/thread_bumper.py index 6bd9efc08..8d0ebdf1c 100644 --- a/bot/exts/utils/thread_bumper.py +++ b/bot/exts/utils/thread_bumper.py @@ -71,7 +71,8 @@ class ThreadBumper(commands.Cog): if thread.archived: threads_to_maybe_bump.append(thread) - await self.unarchive_threads_not_manually_archived(threads_to_maybe_bump) + if threads_to_maybe_bump: + await self.unarchive_threads_not_manually_archived(threads_to_maybe_bump) @commands.group(name="bump") async def thread_bump_group(self, ctx: commands.Context) -> None: -- cgit v1.2.3 From 930bf0f9203cf38b8b88a59d44e277ccc6201811 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sat, 16 Apr 2022 17:25:13 +0100 Subject: Only suppress 404s from site when checking for bumped threads --- bot/exts/utils/thread_bumper.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bot/exts/utils/thread_bumper.py b/bot/exts/utils/thread_bumper.py index 8d0ebdf1c..743919d4e 100644 --- a/bot/exts/utils/thread_bumper.py +++ b/bot/exts/utils/thread_bumper.py @@ -91,8 +91,9 @@ class ThreadBumper(commands.Cog): try: await self.bot.api_client.get(f"{THREAD_BUMP_ENDPOINT}/{thread.id}") - except ResponseCodeError: - pass + except ResponseCodeError as e: + if e.status != 404: + raise else: raise commands.BadArgument("This thread is already in the bump list.") @@ -138,8 +139,9 @@ class ThreadBumper(commands.Cog): try: await self.bot.api_client.get(f"{THREAD_BUMP_ENDPOINT}/{after.id}") - except ResponseCodeError: - pass + except ResponseCodeError as e: + if e.status != 404: + raise else: await self.unarchive_threads_not_manually_archived([after]) -- cgit v1.2.3 From 872026266b72b916fd67ab3190c781237d2dffff Mon Sep 17 00:00:00 2001 From: mbaruh Date: Fri, 22 Apr 2022 02:20:45 +0300 Subject: Make extension management async This is necessary after cog loading was made async in a new discord.py version --- bot/exts/utils/extensions.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bot/exts/utils/extensions.py b/bot/exts/utils/extensions.py index 9862988cb..0f5fc0de4 100644 --- a/bot/exts/utils/extensions.py +++ b/bot/exts/utils/extensions.py @@ -54,7 +54,7 @@ class Extensions(commands.Cog): if "*" in extensions or "**" in extensions: extensions = set(self.bot.all_extensions) - set(self.bot.extensions.keys()) - msg = self.batch_manage(Action.LOAD, *extensions) + msg = await self.batch_manage(Action.LOAD, *extensions) await ctx.send(msg) @extensions_group.command(name="unload", aliases=("ul",)) @@ -76,7 +76,7 @@ class Extensions(commands.Cog): if "*" in extensions or "**" in extensions: extensions = set(self.bot.extensions.keys()) - UNLOAD_BLACKLIST - msg = self.batch_manage(Action.UNLOAD, *extensions) + msg = await self.batch_manage(Action.UNLOAD, *extensions) await ctx.send(msg) @@ -100,7 +100,7 @@ class Extensions(commands.Cog): extensions = set(self.bot.extensions.keys()) | set(extensions) extensions.remove("*") - msg = self.batch_manage(Action.RELOAD, *extensions) + msg = await self.batch_manage(Action.RELOAD, *extensions) await ctx.send(msg) @@ -151,21 +151,21 @@ class Extensions(commands.Cog): return categories - def batch_manage(self, action: Action, *extensions: str) -> str: + async def batch_manage(self, action: Action, *extensions: str) -> str: """ Apply an action to multiple extensions and return a message with the results. If only one extension is given, it is deferred to `manage()`. """ if len(extensions) == 1: - msg, _ = self.manage(action, extensions[0]) + msg, _ = await self.manage(action, extensions[0]) return msg verb = action.name.lower() failures = {} for extension in extensions: - _, error = self.manage(action, extension) + _, error = await self.manage(action, extension) if error: failures[extension] = error @@ -180,17 +180,17 @@ class Extensions(commands.Cog): return msg - def manage(self, action: Action, ext: str) -> t.Tuple[str, t.Optional[str]]: + async def manage(self, action: Action, ext: str) -> t.Tuple[str, t.Optional[str]]: """Apply an action to an extension and return the status message and any error message.""" verb = action.name.lower() error_msg = None try: - action.value(self.bot, ext) + await action.value(self.bot, ext) except (commands.ExtensionAlreadyLoaded, commands.ExtensionNotLoaded): if action is Action.RELOAD: # When reloading, just load the extension if it was not loaded. - return self.manage(Action.LOAD, ext) + return await self.manage(Action.LOAD, ext) msg = f":x: Extension `{ext}` is already {verb}ed." log.debug(msg[4:]) -- cgit v1.2.3 From c2d1538c4357eaf8849aad506a2fc67c658d51a6 Mon Sep 17 00:00:00 2001 From: mina <75038675+minalike@users.noreply.github.com> Date: Thu, 21 Apr 2022 22:54:14 -0400 Subject: Add support for BIG SOLIDUS unicode characters in off topic names (#2146) Make `ALLOWED_CHARACTERS` a raw string to account for slashes --- bot/converters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/converters.py b/bot/converters.py index 7393a1ddc..910ed9e39 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -382,8 +382,8 @@ class Age(DurationDelta): class OffTopicName(Converter): """A converter that ensures an added off-topic name is valid.""" - ALLOWED_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!?'`-<>" - TRANSLATED_CHARACTERS = "๐– ๐–ก๐–ข๐–ฃ๐–ค๐–ฅ๐–ฆ๐–ง๐–จ๐–ฉ๐–ช๐–ซ๐–ฌ๐–ญ๐–ฎ๐–ฏ๐–ฐ๐–ฑ๐–ฒ๐–ณ๐–ด๐–ต๐–ถ๐–ท๐–ธ๐–นวƒ๏ผŸโ€™โ€™-๏ผœ๏ผž" + ALLOWED_CHARACTERS = r"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?'`-<>\/" + TRANSLATED_CHARACTERS = "๐– ๐–ก๐–ข๐–ฃ๐–ค๐–ฅ๐–ฆ๐–ง๐–จ๐–ฉ๐–ช๐–ซ๐–ฌ๐–ญ๐–ฎ๐–ฏ๐–ฐ๐–ฑ๐–ฒ๐–ณ๐–ด๐–ต๐–ถ๐–ท๐–ธ๐–นวƒ๏ผŸโ€™โ€™-๏ผœ๏ผžโงนโงธ" @classmethod def translate_name(cls, name: str, *, from_unicode: bool = True) -> str: -- cgit v1.2.3 From 8f9f25a796f6cc07f01f8f7f56e825cb5ebf56c8 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sat, 23 Apr 2022 14:24:20 +0400 Subject: Speed Up Sync Cog Loading The user syncer was blocking the startup of the sync cog due to having to perform thousands of pointless member fetch requests. This speeds up that process by increasing the probability that the cache is up-to-date using `Guild.chunked`, and limiting the fetches to members who were in the guild during the previous sync only. Co-authored-by: ChrisJL Co-authored-by: wookie184 Signed-off-by: Hassan Abouelela --- bot/exts/backend/sync/_cog.py | 6 ++++++ bot/exts/backend/sync/_syncers.py | 13 +++++++++++-- tests/helpers.py | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/bot/exts/backend/sync/_cog.py b/bot/exts/backend/sync/_cog.py index a5bf82397..4ec822d3f 100644 --- a/bot/exts/backend/sync/_cog.py +++ b/bot/exts/backend/sync/_cog.py @@ -1,3 +1,4 @@ +import asyncio from typing import Any, Dict from botcore.site_api import ResponseCodeError @@ -27,6 +28,11 @@ class Sync(Cog): if guild is None: return + log.info("Waiting for guild to be chunked to start syncers.") + while not guild.chunked: + await asyncio.sleep(10) + log.info("Starting syncers.") + for syncer in (_syncers.RoleSyncer, _syncers.UserSyncer): await syncer.sync(guild) diff --git a/bot/exts/backend/sync/_syncers.py b/bot/exts/backend/sync/_syncers.py index e1c4541ef..799137cb9 100644 --- a/bot/exts/backend/sync/_syncers.py +++ b/bot/exts/backend/sync/_syncers.py @@ -2,6 +2,7 @@ import abc import typing as t from collections import namedtuple +import discord.errors from botcore.site_api import ResponseCodeError from discord import Guild from discord.ext.commands import Context @@ -9,7 +10,6 @@ from more_itertools import chunked import bot from bot.log import get_logger -from bot.utils.members import get_or_fetch_member log = get_logger(__name__) @@ -157,7 +157,16 @@ class UserSyncer(Syncer): if db_user[db_field] != guild_value: updated_fields[db_field] = guild_value - if guild_user := await get_or_fetch_member(guild, db_user["id"]): + guild_user = guild.get_member(db_user["id"]) + if not guild_user and db_user["in_guild"]: + # The member was in the guild during the last sync. + # We try to fetch them to verify cache integrity. + try: + guild_user = await guild.fetch_member(db_user["id"]) + except discord.errors.NotFound: + guild_user = None + + if guild_user: seen_guild_users.add(guild_user.id) maybe_update("name", guild_user.name) diff --git a/tests/helpers.py b/tests/helpers.py index a6e4bdd66..5f3111616 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -171,7 +171,7 @@ class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin): spec_set = guild_instance def __init__(self, roles: Optional[Iterable[MockRole]] = None, **kwargs) -> None: - default_kwargs = {'id': next(self.discord_id), 'members': []} + default_kwargs = {'id': next(self.discord_id), 'members': [], "chunked": True} super().__init__(**collections.ChainMap(kwargs, default_kwargs)) self.roles = [MockRole(name="@everyone", position=1, id=0)] -- cgit v1.2.3 From acc1654572196cf861a37cd9f17bbe9db2111566 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Mon, 25 Apr 2022 20:15:38 +0400 Subject: Add Timeout To The Sync Cog Adds a 30-minute timeout while waiting for the guild to be chunked in the sync cog, after which the cog is not loaded. Signed-off-by: Hassan Abouelela --- bot/exts/backend/sync/_cog.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bot/exts/backend/sync/_cog.py b/bot/exts/backend/sync/_cog.py index 4ec822d3f..85266340b 100644 --- a/bot/exts/backend/sync/_cog.py +++ b/bot/exts/backend/sync/_cog.py @@ -1,10 +1,11 @@ import asyncio +import datetime from typing import Any, Dict from botcore.site_api import ResponseCodeError from discord import Member, Role, User from discord.ext import commands -from discord.ext.commands import Cog, Context +from discord.ext.commands import Cog, Context, errors from bot import constants from bot.bot import Bot @@ -29,10 +30,17 @@ class Sync(Cog): return log.info("Waiting for guild to be chunked to start syncers.") + end = datetime.datetime.now() + datetime.timedelta(minutes=30) while not guild.chunked: await asyncio.sleep(10) - log.info("Starting syncers.") + if datetime.datetime.now() > end: + # More than 30 minutes have passed while trying, abort + raise errors.ExtensionFailed( + self.__class__.__name__, + RuntimeError("The guild was not chunked in time, not loading sync cog.") + ) + log.info("Starting syncers.") for syncer in (_syncers.RoleSyncer, _syncers.UserSyncer): await syncer.sync(guild) -- cgit v1.2.3 From 24b0515851795a510a60aa548d4219eaf925c53c Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 25 Apr 2022 17:01:20 +0100 Subject: Bump bot base so a real statsd client is actually created --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3cfcb8089..a72f6ab16 100644 --- a/poetry.lock +++ b/poetry.lock @@ -125,7 +125,7 @@ lxml = ["lxml"] [[package]] name = "bot-core" -version = "6.1.0" +version = "6.3.2" description = "Bot-Core provides the core functionality and utilities for the bots of the Python Discord community." category = "main" optional = false @@ -141,7 +141,7 @@ async-rediscache = ["async-rediscache[fakeredis] (==0.2.0)"] [package.source] type = "url" -url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.3.0.zip" +url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.3.2.zip" [[package]] name = "certifi" version = "2021.10.8" @@ -1150,7 +1150,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "3.9.*" -content-hash = "edd7c686b0f6f6dee5b48853b94c58038349ee17e87c1e3baaf4872dfc7ec721" +content-hash = "6c545296e308253b3f24ad7463a177031e3152ec6a2768fea25689588a032be8" [metadata.files] aiodns = [ diff --git a/pyproject.toml b/pyproject.toml index 6977b4b09..4d9a27486 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ python = "3.9.*" "discord.py" = {url = "https://github.com/Rapptz/discord.py/archive/987235d5649e7c2b1a927637bab6547244ecb2cf.zip"} # See https://bot-core.pythondiscord.com/ for docs. -bot-core = {url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.3.0.zip", extras = ["async-rediscache"]} +bot-core = {url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.3.2.zip", extras = ["async-rediscache"]} aiodns = "3.0.0" aiohttp = "3.8.1" -- cgit v1.2.3 From 253bc469fc40ee2b18967a4f4c1672f9b0b78b1f Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Tue, 26 Apr 2022 10:21:44 +0100 Subject: Bump d.py and bot-core one of the commits in this bump dynamically extends the timeout of Guild.chunk() based on the number or members, so it should actually work on our guild now. --- poetry.lock | 10 +++++----- pyproject.toml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index a72f6ab16..8281394e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -125,7 +125,7 @@ lxml = ["lxml"] [[package]] name = "bot-core" -version = "6.3.2" +version = "6.4.0" description = "Bot-Core provides the core functionality and utilities for the bots of the Python Discord community." category = "main" optional = false @@ -133,7 +133,7 @@ python-versions = "3.9.*" [package.dependencies] async-rediscache = {version = "0.2.0", extras = ["fakeredis"], optional = true, markers = "extra == \"async-rediscache\""} -"discord.py" = {url = "https://github.com/Rapptz/discord.py/archive/987235d5649e7c2b1a927637bab6547244ecb2cf.zip"} +"discord.py" = {url = "https://github.com/Rapptz/discord.py/archive/5a06fa5f3e28d2b7191722e1a84c541560008aea.zip"} statsd = "3.3.0" [package.extras] @@ -141,7 +141,7 @@ async-rediscache = ["async-rediscache[fakeredis] (==0.2.0)"] [package.source] type = "url" -url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.3.2.zip" +url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.4.0.zip" [[package]] name = "certifi" version = "2021.10.8" @@ -263,7 +263,7 @@ voice = ["PyNaCl (>=1.3.0,<1.6)"] [package.source] type = "url" -url = "https://github.com/Rapptz/discord.py/archive/987235d5649e7c2b1a927637bab6547244ecb2cf.zip" +url = "https://github.com/Rapptz/discord.py/archive/5a06fa5f3e28d2b7191722e1a84c541560008aea.zip" [[package]] name = "distlib" @@ -1150,7 +1150,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "3.9.*" -content-hash = "6c545296e308253b3f24ad7463a177031e3152ec6a2768fea25689588a032be8" +content-hash = "a07f619c75f8133982984eb506ad350144829f10c704421f09b3dbe72cd037d8" [metadata.files] aiodns = [ diff --git a/pyproject.toml b/pyproject.toml index 4d9a27486..402d05f70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,9 +8,9 @@ license = "MIT" [tool.poetry.dependencies] python = "3.9.*" -"discord.py" = {url = "https://github.com/Rapptz/discord.py/archive/987235d5649e7c2b1a927637bab6547244ecb2cf.zip"} +"discord.py" = {url = "https://github.com/Rapptz/discord.py/archive/5a06fa5f3e28d2b7191722e1a84c541560008aea.zip"} # See https://bot-core.pythondiscord.com/ for docs. -bot-core = {url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.3.2.zip", extras = ["async-rediscache"]} +bot-core = {url = "https://github.com/python-discord/bot-core/archive/refs/tags/v6.4.0.zip", extras = ["async-rediscache"]} aiodns = "3.0.0" aiohttp = "3.8.1" -- cgit v1.2.3 From 8d05a50ee55f3374162ba468710cf6586f4363c8 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Tue, 26 Apr 2022 19:16:56 +0100 Subject: Manually chunk guild if not chunked 30s after startup --- bot/exts/backend/sync/_cog.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/bot/exts/backend/sync/_cog.py b/bot/exts/backend/sync/_cog.py index 85266340b..433ff5024 100644 --- a/bot/exts/backend/sync/_cog.py +++ b/bot/exts/backend/sync/_cog.py @@ -1,11 +1,10 @@ import asyncio -import datetime from typing import Any, Dict from botcore.site_api import ResponseCodeError from discord import Member, Role, User from discord.ext import commands -from discord.ext.commands import Cog, Context, errors +from discord.ext.commands import Cog, Context from bot import constants from bot.bot import Bot @@ -13,6 +12,7 @@ from bot.exts.backend.sync import _syncers from bot.log import get_logger log = get_logger(__name__) +MAX_ATTEMPTS = 3 class Sync(Cog): @@ -29,16 +29,20 @@ class Sync(Cog): if guild is None: return - log.info("Waiting for guild to be chunked to start syncers.") - end = datetime.datetime.now() + datetime.timedelta(minutes=30) - while not guild.chunked: + attempts = 0 + while True: + attempts += 1 + if guild.chunked: + log.info("Guild was found to be chunked after %d attempt(s).", attempts) + break + + if attempts == MAX_ATTEMPTS: + log.info("Guild not chunked after %d attempts, calling chunk manually.", MAX_ATTEMPTS) + await guild.chunk() + break + + log.info("Attempt %d/%d: Guild not yet chunked, checking again in 10s.", attempts, MAX_ATTEMPTS) await asyncio.sleep(10) - if datetime.datetime.now() > end: - # More than 30 minutes have passed while trying, abort - raise errors.ExtensionFailed( - self.__class__.__name__, - RuntimeError("The guild was not chunked in time, not loading sync cog.") - ) log.info("Starting syncers.") for syncer in (_syncers.RoleSyncer, _syncers.UserSyncer): -- cgit v1.2.3 From 12b1f82c1a2757466469ffe236209d18feb4bc5e Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Thu, 28 Apr 2022 08:11:49 +0100 Subject: Use async with Messageable.typing() everywhere Closes BOT-33Z Closes #2154 With the latest version of discord.py support for the with Messageable.typingn() was droped, in favour of only using async with. --- bot/exts/info/doc/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/doc/_cog.py b/bot/exts/info/doc/_cog.py index 079bfc942..dece44063 100644 --- a/bot/exts/info/doc/_cog.py +++ b/bot/exts/info/doc/_cog.py @@ -431,7 +431,7 @@ class DocCog(commands.Cog): async def refresh_command(self, ctx: commands.Context) -> None: """Refresh inventories and show the difference.""" old_inventories = set(self.base_urls) - with ctx.typing(): + async with ctx.typing(): await self.refresh_inventories() new_inventories = set(self.base_urls) -- cgit v1.2.3 From f57b48d4ac1418fa2e885255c6b302687e0a51b2 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Fri, 29 Apr 2022 19:27:27 -0400 Subject: Update wording for or-gotcha tag --- bot/resources/tags/or-gotcha.md | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/resources/tags/or-gotcha.md b/bot/resources/tags/or-gotcha.md index d75a73d78..25ade8620 100644 --- a/bot/resources/tags/or-gotcha.md +++ b/bot/resources/tags/or-gotcha.md @@ -1,5 +1,6 @@ When checking if something is equal to one thing or another, you might think that this is possible: ```py +# Incorrect... if favorite_fruit == 'grapefruit' or 'lemon': print("That's a weird favorite fruit to have.") ``` -- cgit v1.2.3