diff --git a/changelog.d/2967.breaking.rst b/changelog.d/2967.breaking.rst new file mode 100644 index 000000000..cc66095a7 --- /dev/null +++ b/changelog.d/2967.breaking.rst @@ -0,0 +1,11 @@ +The main bot config is no longer directly accessible to cogs. New methods have been added for use where this is concerned. +New methods for this include + + - ``bot.get_shared_api_tokens`` + - ``bot.set_shared_api_tokens`` + - ``bot.get_embed_color`` + - ``bot.get_embed_colour`` + - ``bot.get_admin_roles`` + - ``bot.get_admin_role_ids`` + - ``bot.get_mod_roles`` + - ``bot.get_mod_role_ids`` diff --git a/docs/framework_apikeys.rst b/docs/framework_apikeys.rst index 86a0a2e2d..bfaadac40 100644 --- a/docs/framework_apikeys.rst +++ b/docs/framework_apikeys.rst @@ -18,7 +18,7 @@ and when accessed in the code it should be done by .. code-block:: python - await self.bot.db.api_tokens.get_raw("twitch", default={"client_id": None, "client_secret": None}) + await self.bot.get_shared_api_keys("twitch") Each service has its own dict of key, value pairs for each required key type. If there's only one key required then a name for the key is still required for storing and accessing. @@ -30,7 +30,7 @@ and when accessed in the code it should be done by .. code-block:: python - await self.bot.db.api_tokens.get_raw("youtube", default={"api_key": None}) + await self.bot.get_shared_api_keys("youtube") *********** @@ -42,7 +42,7 @@ Basic Usage class MyCog: @commands.command() async def youtube(self, ctx, user: str): - apikey = await self.bot.db.api_tokens.get_raw("youtube", default={"api_key": None}) - if apikey["api_key"] is None: + youtube_keys = await self.bot.get_shared_api_keys("youtube") + if youtube_keys.get("api_key") is None: return await ctx.send("The YouTube API key has not been set.") # Use the API key to access content as you normally would diff --git a/redbot/__main__.py b/redbot/__main__.py index 2cac3e178..5ec928e86 100644 --- a/redbot/__main__.py +++ b/redbot/__main__.py @@ -52,8 +52,8 @@ async def _get_prefix_and_token(red, indict): :param indict: :return: """ - indict["token"] = await red.db.token() - indict["prefix"] = await red.db.prefix() + indict["token"] = await red._config.token() + indict["prefix"] = await red._config.prefix() def list_instances(): @@ -115,7 +115,7 @@ def main(): red = Red( cli_flags=cli_flags, description=description, dm_help=None, fetch_offline_members=True ) - loop.run_until_complete(red.maybe_update_config()) + loop.run_until_complete(red._maybe_update_config()) init_global_checks(red) init_events(red, cli_flags) @@ -153,11 +153,11 @@ def main(): loop.run_until_complete(red.start(token, bot=True)) except discord.LoginFailure: log.critical("This token doesn't seem to be valid.") - db_token = loop.run_until_complete(red.db.token()) + db_token = loop.run_until_complete(red._config.token()) if db_token and not cli_flags.no_prompt: print("\nDo you want to reset the token? (y/n)") if confirm("> "): - loop.run_until_complete(red.db.token.set("")) + loop.run_until_complete(red._config.token.set("")) print("Token has been reset.") except KeyboardInterrupt: log.info("Keyboard interrupt detected. Quitting...") diff --git a/redbot/cogs/audio/audio.py b/redbot/cogs/audio/audio.py index 4dde73984..637bced48 100644 --- a/redbot/cogs/audio/audio.py +++ b/redbot/cogs/audio/audio.py @@ -296,7 +296,7 @@ class Audio(commands.Cog): else: dur = lavalink.utils.format_time(player.current.length) embed = discord.Embed( - colour=(await self._get_embed_colour(notify_channel)), + colour=(await self.bot.get_embed_color(notify_channel)), title=_("Now Playing"), description=description, ) @@ -328,7 +328,8 @@ class Audio(commands.Cog): if notify_channel: notify_channel = self.bot.get_channel(notify_channel) embed = discord.Embed( - colour=(await self._get_embed_colour(notify_channel)), title=_("Queue ended.") + colour=(await self.bot.get_embed_colour(notify_channel)), + title=_("Queue ended."), ) await notify_channel.send(embed=embed) @@ -346,7 +347,7 @@ class Audio(commands.Cog): if message_channel: message_channel = self.bot.get_channel(message_channel) embed = discord.Embed( - colour=(await self._get_embed_colour(message_channel)), + colour=(await self.bot.get_embed_color(message_channel)), title=_("Track Error"), description="{}\n**[{}]({})**".format( extra, player.current.title, player.current.uri @@ -3834,14 +3835,12 @@ class Audio(commands.Cog): return False async def _check_api_tokens(self): - spotify = await self.bot.db.api_tokens.get_raw( - "spotify", default={"client_id": "", "client_secret": ""} - ) - youtube = await self.bot.db.api_tokens.get_raw("youtube", default={"api_key": ""}) + spotify = await self.bot.get_shared_api_tokens("spotify") + youtube = await self.bot.get_shared_api_tokens("youtube") return { - "spotify_client_id": spotify["client_id"], - "spotify_client_secret": spotify["client_secret"], - "youtube_api": youtube["api_key"], + "spotify_client_id": spotify.get("client_id", ""), + "spotify_client_secret": spotify.get("client_secret", ""), + "youtube_api": youtube.get("api_key", ""), } async def _check_external(self): @@ -4081,13 +4080,6 @@ class Audio(commands.Cog): except discord.errors.NotFound: pass - async def _get_embed_colour(self, channel: discord.abc.GuildChannel): - # Unfortunately we need this for when context is unavailable. - if await self.bot.db.guild(channel.guild).use_bot_color(): - return channel.guild.me.color - else: - return self.bot.color - async def _get_eq_reaction(self, ctx, message, emoji): try: reaction, user = await self.bot.wait_for( @@ -4323,10 +4315,9 @@ class Audio(commands.Cog): return {"Authorization": "Basic %s" % auth_header.decode("ascii")} async def _request_token(self): - self.client_id = await self.bot.db.api_tokens.get_raw("spotify", default={"client_id": ""}) - self.client_secret = await self.bot.db.api_tokens.get_raw( - "spotify", default={"client_secret": ""} - ) + tokens = await self.bot.get_shared_api_tokens("spotify") + self.client_id = tokens.get("client_id", "") + self.client_secret = tokens.get("client_secret", "") payload = {"grant_type": "client_credentials"} headers = self._make_token_auth( self.client_id["client_id"], self.client_secret["client_secret"] diff --git a/redbot/cogs/bank/bank.py b/redbot/cogs/bank/bank.py index 3f8f8a444..abee96905 100644 --- a/redbot/cogs/bank/bank.py +++ b/redbot/cogs/bank/bank.py @@ -47,9 +47,9 @@ def check_global_setting_admin(): return True if ctx.channel.permissions_for(author).manage_guild: return True - admin_roles = set(await ctx.bot.db.guild(ctx.guild).admin_role()) + admin_role_ids = await ctx.bot.get_admin_role_ids(ctx.guild.id) for role in author.roles: - if role.id in admin_roles: + if role.id in admin_role_ids: return True else: return await ctx.bot.is_owner(author) diff --git a/redbot/cogs/image/image.py b/redbot/cogs/image/image.py index aa51c01d7..e7d3d3556 100644 --- a/redbot/cogs/image/image.py +++ b/redbot/cogs/image/image.py @@ -28,8 +28,9 @@ class Image(commands.Cog): async def initialize(self) -> None: """Move the API keys from cog stored config to core bot config if they exist.""" imgur_token = await self.settings.imgur_client_id() - if imgur_token is not None and "imgur" not in await self.bot.db.api_tokens(): - await self.bot.db.api_tokens.set_raw("imgur", value={"client_id": imgur_token}) + if imgur_token is not None: + if not await self.bot.get_shared_api_tokens("imgur"): + await self.bot.set_shared_api_tokens(client_id=imgur_token) await self.settings.imgur_client_id.clear() @commands.group(name="imgur") @@ -48,7 +49,7 @@ class Image(commands.Cog): """ url = self.imgur_base_url + "gallery/search/time/all/0" params = {"q": term} - imgur_client_id = await ctx.bot.db.api_tokens.get_raw("imgur", default=None) + imgur_client_id = (await ctx.bot.get_shared_api_tokens("imgur")).get("client_id") if not imgur_client_id: await ctx.send( _( @@ -56,7 +57,7 @@ class Image(commands.Cog): ).format(prefix=ctx.prefix) ) return - headers = {"Authorization": "Client-ID {}".format(imgur_client_id["client_id"])} + headers = {"Authorization": "Client-ID {}".format(imgur_client_id)} async with self.session.get(url, headers=headers, params=params) as search_get: data = await search_get.json() @@ -101,7 +102,7 @@ class Image(commands.Cog): await ctx.send_help() return - imgur_client_id = await ctx.bot.db.api_tokens.get_raw("imgur", default=None) + imgur_client_id = (await ctx.bot.get_shared_api_tokens("imgur")).get("client_id") if not imgur_client_id: await ctx.send( _( @@ -111,7 +112,7 @@ class Image(commands.Cog): return links = [] - headers = {"Authorization": "Client-ID {}".format(imgur_client_id["client_id"])} + headers = {"Authorization": "Client-ID {}".format(imgur_client_id)} url = self.imgur_base_url + "gallery/r/{}/{}/{}/0".format(subreddit, sort, window) async with self.session.get(url, headers=headers) as sub_get: @@ -164,7 +165,7 @@ class Image(commands.Cog): await ctx.send_help() return - giphy_api_key = await ctx.bot.db.api_tokens.get_raw("GIPHY", default=None) + giphy_api_key = (await ctx.bot.get_shared_api_tokens("GIPHY")).get("api_key") if not giphy_api_key: await ctx.send( _("An API key has not been set! Please set one with `{prefix}giphycreds`.").format( @@ -174,7 +175,7 @@ class Image(commands.Cog): return url = "http://api.giphy.com/v1/gifs/search?&api_key={}&q={}".format( - giphy_api_key["api_key"], keywords + giphy_api_key, keywords ) async with self.session.get(url) as r: @@ -197,7 +198,7 @@ class Image(commands.Cog): await ctx.send_help() return - giphy_api_key = await ctx.bot.db.api_tokens.get_raw("GIPHY", default=None) + giphy_api_key = (await ctx.bot.get_shared_api_tokens("GIPHY")).get("api_key") if not giphy_api_key: await ctx.send( _("An API key has not been set! Please set one with `{prefix}giphycreds`.").format( @@ -207,7 +208,7 @@ class Image(commands.Cog): return url = "http://api.giphy.com/v1/gifs/random?&api_key={}&tag={}".format( - giphy_api_key["api_key"], keywords + giphy_api_key, keywords ) async with self.session.get(url) as r: diff --git a/redbot/cogs/streams/streams.py b/redbot/cogs/streams/streams.py index 56d20ebd3..60b2c1b76 100644 --- a/redbot/cogs/streams/streams.py +++ b/redbot/cogs/streams/streams.py @@ -82,27 +82,27 @@ class Streams(commands.Cog): async def move_api_keys(self): """Move the API keys from cog stored config to core bot config if they exist.""" tokens = await self.db.tokens() - youtube = await self.bot.db.api_tokens.get_raw("youtube", default={}) - twitch = await self.bot.db.api_tokens.get_raw("twitch", default={}) + youtube = await self.bot.get_shared_api_tokens("youtube") + twitch = await self.bot.get_shared_api_tokens("twitch") for token_type, token in tokens.items(): if token_type == "YoutubeStream" and "api_key" not in youtube: - await self.bot.db.api_tokens.set_raw("youtube", value={"api_key": token}) + await self.bot.set_shared_api_tokens("youtube", api_key=token) if token_type == "TwitchStream" and "client_id" not in twitch: # Don't need to check Community since they're set the same - await self.bot.db.api_tokens.set_raw("twitch", value={"client_id": token}) + await self.bot.set_shared_api_tokens("twitch", client_id=token) await self.db.tokens.clear() @commands.command() async def twitchstream(self, ctx: commands.Context, channel_name: str): """Check if a Twitch channel is live.""" - token = await self.bot.db.api_tokens.get_raw("twitch", default={"client_id": None}) + token = (await self.bot.get_shared_api_tokens("twitch")).get("client_id") stream = TwitchStream(name=channel_name, token=token) await self.check_online(ctx, stream) @commands.command() async def youtubestream(self, ctx: commands.Context, channel_id_or_name: str): """Check if a YouTube channel is live.""" - apikey = await self.bot.db.api_tokens.get_raw("youtube", default={"api_key": None}) + apikey = await self.bot.get_shared_api_tokens("youtube") is_name = self.check_name_or_id(channel_id_or_name) if is_name: stream = YoutubeStream(name=channel_id_or_name, token=apikey) @@ -273,7 +273,7 @@ class Streams(commands.Cog): async def stream_alert(self, ctx: commands.Context, _class, channel_name): stream = self.get_stream(_class, channel_name) if not stream: - token = await self.bot.db.api_tokens.get_raw(_class.token_name, default=None) + token = await self.bot.get_shared_api_tokens(_class.token_name) is_yt = _class.__name__ == "YoutubeStream" if is_yt and not self.check_name_or_id(channel_name): stream = _class(id=channel_name, token=token) @@ -651,8 +651,8 @@ class Streams(commands.Cog): pass else: raw_stream["_messages_cache"].append(msg) - token = await self.bot.db.api_tokens.get_raw(_class.token_name, default=None) - if token is not None: + token = await self.bot.get_shared_api_tokens(_class.token_name) + if token: raw_stream["token"] = token streams.append(_class(**raw_stream)) diff --git a/redbot/core/bot.py b/redbot/core/bot.py index 6a2150a25..87b24072b 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -6,7 +6,7 @@ from collections import Counter from enum import Enum from importlib.machinery import ModuleSpec from pathlib import Path -from typing import Optional, Union, List +from typing import Optional, Union, List, Dict import discord from discord.ext.commands import when_mentioned_or @@ -36,11 +36,11 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d def __init__(self, *args, cli_flags=None, bot_dir: Path = Path.cwd(), **kwargs): self._shutdown_mode = ExitCodes.CRITICAL - self.db = Config.get_core_conf(force_registration=True) + self._config = Config.get_core_conf(force_registration=False) self._co_owners = cli_flags.co_owner self.rpc_enabled = cli_flags.rpc self._last_exception = None - self.db.register_global( + self._config.register_global( token=None, prefix=[], packages=[], @@ -69,7 +69,7 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d schema_version=0, ) - self.db.register_guild( + self._config.register_guild( prefix=[], whitelist=[], blacklist=[], @@ -82,19 +82,19 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d autoimmune_ids=[], ) - self.db.register_user(embeds=None) + self._config.register_user(embeds=None) - self.db.init_custom(CUSTOM_GROUPS, 2) - self.db.register_custom(CUSTOM_GROUPS) + self._config.init_custom(CUSTOM_GROUPS, 2) + self._config.register_custom(CUSTOM_GROUPS) async def prefix_manager(bot, message): if not cli_flags.prefix: - global_prefix = await bot.db.prefix() + global_prefix = await bot._config.prefix() else: global_prefix = cli_flags.prefix if message.guild is None: return global_prefix - server_prefix = await bot.db.guild(message.guild).prefix() + server_prefix = await bot._config.guild(message.guild).prefix() if cli_flags.mentionable: return ( when_mentioned_or(*server_prefix)(bot, message) @@ -117,10 +117,10 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d if "command_not_found" not in kwargs: kwargs["command_not_found"] = "Command {} not found.\n{}" - self.counter = Counter() - self.uptime = None - self.checked_time_accuracy = None - self.color = discord.Embed.Empty # This is needed or color ends up 0x000000 + self._counter = Counter() + self._uptime = None + self._checked_time_accuracy = None + self._color = discord.Embed.Empty # This is needed or color ends up 0x000000 self.main_dir = bot_dir @@ -134,16 +134,42 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d self._permissions_hooks: List[commands.CheckPredicate] = [] - async def maybe_update_config(self): + async def get_embed_color(self, location: discord.abc.Messageable) -> discord.Color: + """ + Get the embed color for a location. + + Parameters + ---------- + location : `discord.abc.Messageable` + + Returns + ------- + discord.Color + """ + + guild = getattr(location, "guild", None) + + if ( + guild + and await self._config.guild(guild).use_bot_color() + and not isinstance(location, discord.Member) + ): + return guild.me.color + + return self._color + + get_embed_colour = get_embed_color + + async def _maybe_update_config(self): """ This should be run prior to loading cogs or connecting to discord. """ - schema_version = await self.db.schema_version() + schema_version = await self._config.schema_version() if schema_version == 0: await self._schema_0_to_1() schema_version += 1 - await self.db.schema_version.set(schema_version) + await self._config.schema_version.set(schema_version) async def _schema_0_to_1(self): """ @@ -151,7 +177,7 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d """ log.info("Begin updating guild configs to support multiple mod/admin roles") - all_guild_data = await self.db.all_guilds() + all_guild_data = await self._config.all_guilds() for guild_id, guild_data in all_guild_data.items(): guild_obj = discord.Object(id=guild_id) mod_roles, admin_roles = [], [] @@ -160,10 +186,10 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d if maybe_mod_role_id: mod_roles.append(maybe_mod_role_id) - await self.db.guild(guild_obj).mod_role.set(mod_roles) + await self._config.guild(guild_obj).mod_role.set(mod_roles) if maybe_admin_role_id: admin_roles.append(maybe_admin_role_id) - await self.db.guild(guild_obj).admin_role.set(admin_roles) + await self._config.guild(guild_obj).admin_role.set(admin_roles) log.info("Done updating guild configs to support multiple mod/admin roles") async def send_help_for( @@ -182,8 +208,8 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d :return: """ - indict["owner_id"] = await self.db.owner() - i18n.set_locale(await self.db.locale()) + indict["owner_id"] = await self._config.owner() + i18n.set_locale(await self._config.locale()) async def embed_requested(self, channel, user, command=None) -> bool: """ @@ -203,47 +229,112 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d bool :code:`True` if an embed is requested """ - if isinstance(channel, discord.abc.PrivateChannel): - user_setting = await self.db.user(user).embeds() + if isinstance(channel, discord.abc.PrivateChannel) or ( + command and command == self.get_command("help") + ): + user_setting = await self._config.user(user).embeds() if user_setting is not None: return user_setting else: - guild_setting = await self.db.guild(channel.guild).embeds() + guild_setting = await self._config.guild(channel.guild).embeds() if guild_setting is not None: return guild_setting - global_setting = await self.db.embeds() + global_setting = await self._config.embeds() return global_setting - async def is_owner(self, user): + async def is_owner(self, user) -> bool: if user.id in self._co_owners: return True return await super().is_owner(user) - async def is_admin(self, member: discord.Member): + async def is_admin(self, member: discord.Member) -> bool: """Checks if a member is an admin of their guild.""" try: member_snowflakes = member._roles # DEP-WARN - for snowflake in await self.db.guild(member.guild).admin_role(): + for snowflake in await self._config.guild(member.guild).admin_role(): if member_snowflakes.has(snowflake): # Dep-WARN return True except AttributeError: # someone passed a webhook to this pass return False - async def is_mod(self, member: discord.Member): + async def is_mod(self, member: discord.Member) -> bool: """Checks if a member is a mod or admin of their guild.""" try: member_snowflakes = member._roles # DEP-WARN - for snowflake in await self.db.guild(member.guild).admin_role(): + for snowflake in await self._config.guild(member.guild).admin_role(): if member_snowflakes.has(snowflake): # DEP-WARN return True - for snowflake in await self.db.guild(member.guild).mod_role(): + for snowflake in await self._config.guild(member.guild).mod_role(): if member_snowflakes.has(snowflake): # DEP-WARN return True except AttributeError: # someone passed a webhook to this pass return False + async def get_admin_roles(self, guild: discord.Guild) -> List[discord.Role]: + """ + Gets the admin roles for a guild. + """ + ret: List[discord.Role] = [] + for snowflake in await self._config.guild(guild).admin_role(): + r = guild.get_role(snowflake) + if r: + ret.append(r) + return ret + + async def get_mod_roles(self, guild: discord.Guild) -> List[discord.Role]: + """ + Gets the mod roles for a guild. + """ + ret: List[discord.Role] = [] + for snowflake in await self._config.guild(guild).mod_role(): + r = guild.get_role(snowflake) + if r: + ret.append(r) + return ret + + async def get_admin_role_ids(self, guild_id: int) -> List[int]: + """ + Gets the admin role ids for a guild id. + """ + return await self._config.guild(discord.Object(id=guild_id)).admin_role() + + async def get_mod_role_ids(self, guild_id: int) -> List[int]: + """ + Gets the mod role ids for a guild id. + """ + return await self._config.guild(discord.Object(id=guild_id)).mod_role() + + async def get_shared_api_tokens(self, service_name: str) -> Dict[str, str]: + """ + Gets the shared API tokens for a service + + Parameters + ---------- + service_name: str + + Returns + ------- + Dict[str, str] + A Mapping of token names to tokens. + This mapping exists because some services have multiple tokens. + """ + return await self._config.api_tokens.get_raw(service_name, default={}) + + async def set_shared_api_tokens(self, service_name: str, **tokens: str): + """ + Sets shared API tokens for a service + + In most cases, this should not be used. Users should instead be using the + ``set api`` command + + This will not clear existing values not specified. + """ + + async with self._config.api_tokens.get_attr(service_name)() as method_abuse: + method_abuse.update(**tokens) + async def get_context(self, message, *, cls=commands.Context): return await super().get_context(message, cls=cls) @@ -269,15 +360,15 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d return os.listdir("cogs") async def save_packages_status(self, packages): - await self.db.packages.set(packages) + await self._config.packages.set(packages) async def add_loaded_package(self, pkg_name: str): - async with self.db.packages() as curr_pkgs: + async with self._config.packages() as curr_pkgs: if pkg_name not in curr_pkgs: curr_pkgs.append(pkg_name) async def remove_loaded_package(self, pkg_name: str): - async with self.db.packages() as curr_pkgs: + async with self._config.packages() as curr_pkgs: while pkg_name in curr_pkgs: curr_pkgs.remove(pkg_name) @@ -361,7 +452,7 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d else: ids_to_check.append(author.id) - immune_ids = await self.db.guild(guild).autoimmune_ids() + immune_ids = await self._config.guild(guild).autoimmune_ids() return any(i in immune_ids for i in ids_to_check) @@ -545,14 +636,14 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d Gets the users and channels to send to """ destinations = [] - opt_outs = await self.db.owner_opt_out_list() + opt_outs = await self._config.owner_opt_out_list() for user_id in (self.owner_id, *self._co_owners): if user_id not in opt_outs: user = self.get_user(user_id) if user: destinations.append(user) - channel_ids = await self.db.extra_owner_destinations() + channel_ids = await self._config.extra_owner_destinations() for channel_id in channel_ids: channel = self.get_channel(channel_id) if channel: diff --git a/redbot/core/commands/context.py b/redbot/core/commands/context.py index 63bfe8707..12e51928c 100644 --- a/redbot/core/commands/context.py +++ b/redbot/core/commands/context.py @@ -175,10 +175,7 @@ class Context(commands.Context): discord.Colour: The colour to be used """ - if self.guild and await self.bot.db.guild(self.guild).use_bot_color(): - return self.guild.me.color - else: - return self.bot.color + return await self.bot.get_embed_color(self) @property def embed_color(self): diff --git a/redbot/core/commands/help.py b/redbot/core/commands/help.py index 0d457b3c4..515ad9866 100644 --- a/redbot/core/commands/help.py +++ b/redbot/core/commands/help.py @@ -94,7 +94,7 @@ class RedHelpFormatter: await self.command_not_found(ctx, help_for) return except NoSubCommand as exc: - if await ctx.bot.db.help.verify_exists(): + if await ctx.bot._config.help.verify_exists(): await self.subcommand_not_found(ctx, exc.last, exc.not_found) return help_for = exc.last @@ -130,7 +130,7 @@ class RedHelpFormatter: async def format_command_help(self, ctx: Context, obj: commands.Command): - send = await ctx.bot.db.help.verify_exists() + send = await ctx.bot._config.help.verify_exists() if not send: async for _ in self.help_filter_func(ctx, (obj,), bypass_hidden=True): # This is a really lazy option for not @@ -147,7 +147,7 @@ class RedHelpFormatter: command = obj description = command.description or "" - tagline = (await ctx.bot.db.help.tagline()) or self.get_default_tagline(ctx) + tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx) signature = f"`Syntax: {ctx.clean_prefix}{command.qualified_name} {command.signature}`" subcommands = None @@ -250,7 +250,7 @@ class RedHelpFormatter: pages = [] - page_char_limit = await ctx.bot.db.help.page_char_limit() + page_char_limit = await ctx.bot._config.help.page_char_limit() field_groups = self.group_embed_fields(embed_dict["fields"], page_char_limit) color = await ctx.embed_color() @@ -285,11 +285,11 @@ class RedHelpFormatter: async def format_cog_help(self, ctx: Context, obj: commands.Cog): coms = await self.get_cog_help_mapping(ctx, obj) - if not (coms or await ctx.bot.db.help.verify_exists()): + if not (coms or await ctx.bot._config.help.verify_exists()): return description = obj.help - tagline = (await ctx.bot.db.help.tagline()) or self.get_default_tagline(ctx) + tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx) if await ctx.embed_requested(): emb = {"embed": {"title": "", "description": ""}, "footer": {"text": ""}, "fields": []} @@ -356,7 +356,7 @@ class RedHelpFormatter: return description = ctx.bot.description or "" - tagline = (await ctx.bot.db.help.tagline()) or self.get_default_tagline(ctx) + tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx) if await ctx.embed_requested(): @@ -433,8 +433,8 @@ class RedHelpFormatter: This does most of actual filtering. """ - show_hidden = bypass_hidden or await ctx.bot.db.help.show_hidden() - verify_checks = await ctx.bot.db.help.verify_checks() + show_hidden = bypass_hidden or await ctx.bot._config.help.show_hidden() + verify_checks = await ctx.bot._config.help.verify_checks() # TODO: Settings for this in core bot db for obj in objects: @@ -466,17 +466,17 @@ class RedHelpFormatter: ret = await format_fuzzy_results(ctx, fuzzy_commands, embed=use_embeds) if use_embeds: ret.set_author(name=f"{ctx.me.display_name} Help Menu", icon_url=ctx.me.avatar_url) - tagline = (await ctx.bot.db.help.tagline()) or self.get_default_tagline(ctx) + tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx) ret.set_footer(text=tagline) await ctx.send(embed=ret) else: await ctx.send(ret) - elif await ctx.bot.db.help.verify_exists(): + elif await ctx.bot._config.help.verify_exists(): ret = T_("Help topic for *{command_name}* not found.").format(command_name=help_for) if use_embeds: ret = discord.Embed(color=(await ctx.embed_color()), description=ret) ret.set_author(name=f"{ctx.me.display_name} Help Menu", icon_url=ctx.me.avatar_url) - tagline = (await ctx.bot.db.help.tagline()) or self.get_default_tagline(ctx) + tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx) ret.set_footer(text=tagline) await ctx.send(embed=ret) else: @@ -492,7 +492,7 @@ class RedHelpFormatter: if await ctx.embed_requested(): ret = discord.Embed(color=(await ctx.embed_color()), description=ret) ret.set_author(name=f"{ctx.me.display_name} Help Menu", icon_url=ctx.me.avatar_url) - tagline = (await ctx.bot.db.help.tagline()) or self.get_default_tagline(ctx) + tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx) ret.set_footer(text=tagline) await ctx.send(embed=ret) else: @@ -536,10 +536,11 @@ class RedHelpFormatter: """ if not ( - ctx.channel.permissions_for(ctx.me).add_reactions and await ctx.bot.db.help.use_menus() + ctx.channel.permissions_for(ctx.me).add_reactions + and await ctx.bot._config.help.use_menus() ): - max_pages_in_guild = await ctx.bot.db.help.max_pages_in_guild() + max_pages_in_guild = await ctx.bot._config.help.max_pages_in_guild() destination = ctx.author if len(pages) > max_pages_in_guild else ctx if embed: diff --git a/redbot/core/commands/requires.py b/redbot/core/commands/requires.py index 35eddd145..c5b4187a4 100644 --- a/redbot/core/commands/requires.py +++ b/redbot/core/commands/requires.py @@ -125,7 +125,7 @@ class PrivilegeLevel(enum.IntEnum): # The following is simply an optimised way to check if the user has the # admin or mod role. - guild_settings = ctx.bot.db.guild(ctx.guild) + guild_settings = ctx.bot._config.guild(ctx.guild) member_snowflakes = ctx.author._roles # DEP-WARN for snowflake in await guild_settings.admin_role(): diff --git a/redbot/core/core_commands.py b/redbot/core/core_commands.py index 6eb2b7c9a..7c81bff11 100644 --- a/redbot/core/core_commands.py +++ b/redbot/core/core_commands.py @@ -223,8 +223,9 @@ class CoreLogic: """ if prefixes: prefixes = sorted(prefixes, reverse=True) - await self.bot.db.prefix.set(prefixes) - return await self.bot.db.prefix() + await self.bot._config.prefix.set(prefixes) + return prefixes + return await self.bot._config.prefix() @classmethod async def _version_info(cls) -> Dict[str, str]: @@ -248,14 +249,14 @@ class CoreLogic: Invite URL. """ app_info = await self.bot.application_info() - perms_int = await self.bot.db.invite_perm() + perms_int = await self.bot._config.invite_perm() permissions = discord.Permissions(perms_int) return discord.utils.oauth_url(app_info.id, permissions) @staticmethod async def _can_get_invite_url(ctx): is_owner = await ctx.bot.is_owner(ctx.author) - is_invite_public = await ctx.bot.db.invite_public() + is_invite_public = await ctx.bot._config.invite_public() return is_owner or is_invite_public @@ -285,7 +286,7 @@ class Core(commands.Cog, CoreLogic): red_version = "[{}]({})".format(__version__, red_pypi) app_info = await self.bot.application_info() owner = app_info.owner - custom_info = await self.bot.db.custom_info() + custom_info = await self.bot._config.custom_info() async with aiohttp.ClientSession() as session: async with session.get("{}/json".format(red_pypi)) as r: @@ -343,12 +344,12 @@ class Core(commands.Cog, CoreLogic): """ if ctx.invoked_subcommand is None: text = _("Embed settings:\n\n") - global_default = await self.bot.db.embeds() + global_default = await self.bot._config.embeds() text += _("Global default: {}\n").format(global_default) if ctx.guild: - guild_setting = await self.bot.db.guild(ctx.guild).embeds() + guild_setting = await self.bot._config.guild(ctx.guild).embeds() text += _("Guild setting: {}\n").format(guild_setting) - user_setting = await self.bot.db.user(ctx.author).embeds() + user_setting = await self.bot._config.user(ctx.author).embeds() text += _("User setting: {}").format(user_setting) await ctx.send(box(text)) @@ -362,8 +363,8 @@ class Core(commands.Cog, CoreLogic): or guild hasn't set a preference. The default is to use embeds. """ - current = await self.bot.db.embeds() - await self.bot.db.embeds.set(not current) + current = await self.bot._config.embeds() + await self.bot._config.embeds.set(not current) await ctx.send( _("Embeds are now {} by default.").format(_("disabled") if current else _("enabled")) ) @@ -383,7 +384,7 @@ class Core(commands.Cog, CoreLogic): used for all commands done in a guild channel except for help commands. """ - await self.bot.db.guild(ctx.guild).embeds.set(enabled) + await self.bot._config.guild(ctx.guild).embeds.set(enabled) if enabled is None: await ctx.send(_("Embeds will now fall back to the global setting.")) else: @@ -406,7 +407,7 @@ class Core(commands.Cog, CoreLogic): used for all commands done in a DM with the bot, as well as all help commands everywhere. """ - await self.bot.db.user(ctx.author).embeds.set(enabled) + await self.bot._config.user(ctx.author).embeds.set(enabled) if enabled is None: await ctx.send(_("Embeds will now fall back to the global setting.")) else: @@ -454,8 +455,8 @@ class Core(commands.Cog, CoreLogic): """ Define if the command should be accessible for the average user. """ - if await self.bot.db.invite_public(): - await self.bot.db.invite_public.set(False) + if await self.bot._config.invite_public(): + await self.bot._config.invite_public.set(False) await ctx.send("The invite is now private.") return app_info = await self.bot.application_info() @@ -475,7 +476,7 @@ class Core(commands.Cog, CoreLogic): "If you agree, you can type `{0}inviteset public yes`.".format(ctx.prefix) ) else: - await self.bot.db.invite_public.set(True) + await self.bot._config.invite_public.set(True) await ctx.send("The invite command is now public.") @inviteset.command() @@ -493,7 +494,7 @@ class Core(commands.Cog, CoreLogic): Please note that you might need two factor authentification for\ some permissions. """ - await self.bot.db.invite_perm.set(level) + await self.bot._config.invite_perm.set(level) await ctx.send("The new permissions level has been set.") @commands.command() @@ -759,15 +760,15 @@ class Core(commands.Cog, CoreLogic): if ctx.invoked_subcommand is None: if ctx.guild: guild = ctx.guild - admin_role_ids = await ctx.bot.db.guild(ctx.guild).admin_role() + admin_role_ids = await ctx.bot._config.guild(ctx.guild).admin_role() admin_role_names = [r.name for r in guild.roles if r.id in admin_role_ids] admin_roles_str = ( humanize_list(admin_role_names) if admin_role_names else "Not Set." ) - mod_role_ids = await ctx.bot.db.guild(ctx.guild).mod_role() + mod_role_ids = await ctx.bot._config.guild(ctx.guild).mod_role() mod_role_names = [r.name for r in guild.roles if r.id in mod_role_ids] mod_roles_str = humanize_list(mod_role_names) if mod_role_names else "Not Set." - prefixes = await ctx.bot.db.guild(ctx.guild).prefix() + prefixes = await ctx.bot._config.guild(ctx.guild).prefix() guild_settings = _("Admin roles: {admin}\nMod roles: {mod}\n").format( admin=admin_roles_str, mod=mod_roles_str ) @@ -775,8 +776,8 @@ class Core(commands.Cog, CoreLogic): guild_settings = "" prefixes = None # This is correct. The below can happen in a guild. if not prefixes: - prefixes = await ctx.bot.db.prefix() - locale = await ctx.bot.db.locale() + prefixes = await ctx.bot._config.prefix() + locale = await ctx.bot._config.locale() prefix_string = " ".join(prefixes) settings = _( @@ -800,7 +801,7 @@ class Core(commands.Cog, CoreLogic): """ Adds an admin role for this guild. """ - async with ctx.bot.db.guild(ctx.guild).admin_role() as roles: + async with ctx.bot._config.guild(ctx.guild).admin_role() as roles: if role.id in roles: return await ctx.send(_("This role is already an admin role.")) roles.append(role.id) @@ -813,7 +814,7 @@ class Core(commands.Cog, CoreLogic): """ Adds a mod role for this guild. """ - async with ctx.bot.db.guild(ctx.guild).mod_role() as roles: + async with ctx.bot._config.guild(ctx.guild).mod_role() as roles: if role.id in roles: return await ctx.send(_("This role is already a mod role.")) roles.append(role.id) @@ -826,7 +827,7 @@ class Core(commands.Cog, CoreLogic): """ Removes an admin role for this guild. """ - async with ctx.bot.db.guild(ctx.guild).admin_role() as roles: + async with ctx.bot._config.guild(ctx.guild).admin_role() as roles: if role.id not in roles: return await ctx.send(_("That role was not an admin role to begin with.")) roles.remove(role.id) @@ -839,7 +840,7 @@ class Core(commands.Cog, CoreLogic): """ Removes a mod role for this guild. """ - async with ctx.bot.db.guild(ctx.guild).mod_role() as roles: + async with ctx.bot._config.guild(ctx.guild).mod_role() as roles: if role.id not in roles: return await ctx.send(_("That role was not a mod role to begin with.")) roles.remove(role.id) @@ -855,8 +856,8 @@ class Core(commands.Cog, CoreLogic): Default is to not use the bot's configured colour, in which case the colour used will be the colour of the bot's top role. """ - current_setting = await ctx.bot.db.guild(ctx.guild).use_bot_color() - await ctx.bot.db.guild(ctx.guild).use_bot_color.set(not current_setting) + current_setting = await ctx.bot._config.guild(ctx.guild).use_bot_color() + await ctx.bot._config.guild(ctx.guild).use_bot_color.set(not current_setting) await ctx.send( _("The bot {} use its configured color for embeds.").format( _("will not") if current_setting else _("will") @@ -872,8 +873,8 @@ class Core(commands.Cog, CoreLogic): Default is for fuzzy command search to be disabled. """ - current_setting = await ctx.bot.db.guild(ctx.guild).fuzzy() - await ctx.bot.db.guild(ctx.guild).fuzzy.set(not current_setting) + current_setting = await ctx.bot._config.guild(ctx.guild).fuzzy() + await ctx.bot._config.guild(ctx.guild).fuzzy.set(not current_setting) await ctx.send( _("Fuzzy command search has been {} for this server.").format( _("disabled") if current_setting else _("enabled") @@ -888,8 +889,8 @@ class Core(commands.Cog, CoreLogic): Default is for fuzzy command search to be disabled. """ - current_setting = await ctx.bot.db.fuzzy() - await ctx.bot.db.fuzzy.set(not current_setting) + current_setting = await ctx.bot._config.fuzzy() + await ctx.bot._config.fuzzy.set(not current_setting) await ctx.send( _("Fuzzy command search has been {} in DMs.").format( _("disabled") if current_setting else _("enabled") @@ -907,11 +908,11 @@ class Core(commands.Cog, CoreLogic): https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.ColourConverter """ if colour is None: - ctx.bot.color = discord.Color.red() - await ctx.bot.db.color.set(discord.Color.red().value) + ctx.bot._color = discord.Color.red() + await ctx.bot._config.color.set(discord.Color.red().value) return await ctx.send(_("The color has been reset.")) - ctx.bot.color = colour - await ctx.bot.db.color.set(colour.value) + ctx.bot._color = colour + await ctx.bot._config.color.set(colour.value) await ctx.send(_("The color has been set.")) @_set.command() @@ -1076,11 +1077,11 @@ class Core(commands.Cog, CoreLogic): async def serverprefix(self, ctx: commands.Context, *prefixes: str): """Sets Red's server prefix(es)""" if not prefixes: - await ctx.bot.db.guild(ctx.guild).prefix.set([]) + await ctx.bot._config.guild(ctx.guild).prefix.set([]) await ctx.send(_("Guild prefixes have been reset.")) return prefixes = sorted(prefixes, reverse=True) - await ctx.bot.db.guild(ctx.guild).prefix.set(prefixes) + await ctx.bot._config.guild(ctx.guild).prefix.set(prefixes) await ctx.send(_("Prefix set.")) @_set.command() @@ -1098,7 +1099,7 @@ class Core(commands.Cog, CoreLogic): locale_list = [loc.stem.lower() for loc in list(red_path.glob("**/*.po"))] if locale_name.lower() in locale_list or locale_name.lower() == "en-us": i18n.set_locale(locale_name) - await ctx.bot.db.locale.set(locale_name) + await ctx.bot._config.locale.set(locale_name) await ctx.send(_("Locale has been set.")) else: await ctx.send( @@ -1119,11 +1120,11 @@ class Core(commands.Cog, CoreLogic): `[My link](https://example.com)` """ if not text: - await ctx.bot.db.custom_info.clear() + await ctx.bot._config.custom_info.clear() await ctx.send(_("The custom text has been cleared.")) return if len(text) <= 1024: - await ctx.bot.db.custom_info.set(text) + await ctx.bot._config.custom_info.set(text) await ctx.send(_("The custom text has been set.")) await ctx.invoke(self.info) else: @@ -1144,7 +1145,7 @@ class Core(commands.Cog, CoreLogic): """ if ctx.channel.permissions_for(ctx.me).manage_messages: await ctx.message.delete() - await ctx.bot.db.api_tokens.set_raw(service, value=tokens) + await ctx.bot._config.api_tokens.set_raw(service, value=tokens) await ctx.send(_("`{service}` API tokens have been set.").format(service=service)) @commands.group() @@ -1163,8 +1164,8 @@ class Core(commands.Cog, CoreLogic): Using this without a setting will toggle. """ if use_menus is None: - use_menus = not await ctx.bot.db.help.use_menus() - await ctx.bot.db.help.use_menus.set(use_menus) + use_menus = not await ctx.bot._config.help.use_menus() + await ctx.bot._config.help.use_menus.set(use_menus) if use_menus: await ctx.send(_("Help will use menus.")) else: @@ -1179,8 +1180,8 @@ class Core(commands.Cog, CoreLogic): Using this without a setting will toggle. """ if show_hidden is None: - show_hidden = not await ctx.bot.db.help.show_hidden() - await ctx.bot.db.help.show_hidden.set(show_hidden) + show_hidden = not await ctx.bot._config.help.show_hidden() + await ctx.bot._config.help.show_hidden.set(show_hidden) if show_hidden: await ctx.send(_("Help will not filter hidden commands")) else: @@ -1196,8 +1197,8 @@ class Core(commands.Cog, CoreLogic): Using this without a setting will toggle. """ if verify is None: - verify = not await ctx.bot.db.help.verify_checks() - await ctx.bot.db.help.verify_checks.set(verify) + verify = not await ctx.bot._config.help.verify_checks() + await ctx.bot._config.help.verify_checks.set(verify) if verify: await ctx.send(_("Help will only show for commands which can be run.")) else: @@ -1215,8 +1216,8 @@ class Core(commands.Cog, CoreLogic): Using this without a setting will toggle. """ if verify is None: - verify = not await ctx.bot.db.help.verify_exists() - await ctx.bot.db.help.verify_exists.set(verify) + verify = not await ctx.bot._config.help.verify_exists() + await ctx.bot._config.help.verify_exists.set(verify) if verify: await ctx.send(_("Help will verify the existence of help topics.")) else: @@ -1243,7 +1244,7 @@ class Core(commands.Cog, CoreLogic): await ctx.send(_("You must give a positive value!")) return - await ctx.bot.db.help.page_char_limit.set(limit) + await ctx.bot._config.help.page_char_limit.set(limit) await ctx.send(_("Done. The character limit per page has been set to {}.").format(limit)) @helpset.command(name="maxpages") @@ -1262,7 +1263,7 @@ class Core(commands.Cog, CoreLogic): await ctx.send(_("You must give a value of zero or greater!")) return - await ctx.bot.db.help.max_pages_in_guild.set(pages) + await ctx.bot._config.help.max_pages_in_guild.set(pages) await ctx.send(_("Done. The page limit has been set to {}.").format(pages)) @helpset.command(name="tagline") @@ -1274,7 +1275,7 @@ class Core(commands.Cog, CoreLogic): specified, the default will be used instead. """ if tagline is None: - await ctx.bot.db.help.tagline.set("") + await ctx.bot._config.help.tagline.set("") return await ctx.send(_("The tagline has been reset.")) if len(tagline) > 2048: @@ -1286,7 +1287,7 @@ class Core(commands.Cog, CoreLogic): ) return - await ctx.bot.db.help.tagline.set(tagline) + await ctx.bot._config.help.tagline.set(tagline) await ctx.send(_("The tagline has been set to {}.").format(tagline[:1900])) @commands.command() @@ -1393,7 +1394,7 @@ class Core(commands.Cog, CoreLogic): footer += _(" | Server ID: {}").format(guild.id) # We need to grab the DM command prefix (global) - # Since it can also be set through cli flags, bot.db is not a reliable + # Since it can also be set through cli flags, bot._config is not a reliable # source. So we'll just mock a DM message instead. fake_message = namedtuple("Message", "guild") prefixes = await ctx.bot.command_prefix(ctx.bot, fake_message(guild=None)) @@ -1417,24 +1418,24 @@ class Core(commands.Cog, CoreLogic): send_embed = None if is_dm: - send_embed = await ctx.bot.db.user(destination).embeds() + send_embed = await ctx.bot._config.user(destination).embeds() else: if not destination.permissions_for(destination.guild.me).send_messages: continue if destination.permissions_for(destination.guild.me).embed_links: - send_embed = await ctx.bot.db.guild(destination.guild).embeds() + send_embed = await ctx.bot._config.guild(destination.guild).embeds() else: send_embed = False if send_embed is None: - send_embed = await ctx.bot.db.embeds() + send_embed = await ctx.bot._config.embeds() if send_embed: - if not is_dm and await self.bot.db.guild(destination.guild).use_bot_color(): - color = destination.guild.me.color + if not is_dm: + color = await ctx.bot.get_embed_color(destination) else: - color = ctx.bot.color + color = ctx.bot._color e = discord.Embed(colour=color, description=message) if author.avatar_url: @@ -1608,7 +1609,7 @@ class Core(commands.Cog, CoreLogic): """ Adds a user to the whitelist. """ - async with ctx.bot.db.whitelist() as curr_list: + async with ctx.bot._config.whitelist() as curr_list: if user.id not in curr_list: curr_list.append(user.id) @@ -1619,7 +1620,7 @@ class Core(commands.Cog, CoreLogic): """ Lists whitelisted users. """ - curr_list = await ctx.bot.db.whitelist() + curr_list = await ctx.bot._config.whitelist() msg = _("Whitelisted Users:") for user in curr_list: @@ -1635,7 +1636,7 @@ class Core(commands.Cog, CoreLogic): """ removed = False - async with ctx.bot.db.whitelist() as curr_list: + async with ctx.bot._config.whitelist() as curr_list: if user.id in curr_list: removed = True curr_list.remove(user.id) @@ -1650,7 +1651,7 @@ class Core(commands.Cog, CoreLogic): """ Clears the whitelist. """ - await ctx.bot.db.whitelist.set([]) + await ctx.bot._config.whitelist.set([]) await ctx.send(_("Whitelist has been cleared.")) @commands.group() @@ -1670,7 +1671,7 @@ class Core(commands.Cog, CoreLogic): await ctx.send(_("You cannot blacklist an owner!")) return - async with ctx.bot.db.blacklist() as curr_list: + async with ctx.bot._config.blacklist() as curr_list: if user.id not in curr_list: curr_list.append(user.id) @@ -1681,7 +1682,7 @@ class Core(commands.Cog, CoreLogic): """ Lists blacklisted users. """ - curr_list = await ctx.bot.db.blacklist() + curr_list = await ctx.bot._config.blacklist() msg = _("Blacklisted Users:") for user in curr_list: @@ -1697,7 +1698,7 @@ class Core(commands.Cog, CoreLogic): """ removed = False - async with ctx.bot.db.blacklist() as curr_list: + async with ctx.bot._config.blacklist() as curr_list: if user.id in curr_list: removed = True curr_list.remove(user.id) @@ -1712,7 +1713,7 @@ class Core(commands.Cog, CoreLogic): """ Clears the blacklist. """ - await ctx.bot.db.blacklist.set([]) + await ctx.bot._config.blacklist.set([]) await ctx.send(_("Blacklist has been cleared.")) @commands.group() @@ -1732,7 +1733,7 @@ class Core(commands.Cog, CoreLogic): Adds a user or role to the whitelist. """ user = isinstance(user_or_role, discord.Member) - async with ctx.bot.db.guild(ctx.guild).whitelist() as curr_list: + async with ctx.bot._config.guild(ctx.guild).whitelist() as curr_list: if user_or_role.id not in curr_list: curr_list.append(user_or_role.id) @@ -1746,7 +1747,7 @@ class Core(commands.Cog, CoreLogic): """ Lists whitelisted users and roles. """ - curr_list = await ctx.bot.db.guild(ctx.guild).whitelist() + curr_list = await ctx.bot._config.guild(ctx.guild).whitelist() msg = _("Whitelisted Users and roles:") for obj in curr_list: @@ -1765,7 +1766,7 @@ class Core(commands.Cog, CoreLogic): user = isinstance(user_or_role, discord.Member) removed = False - async with ctx.bot.db.guild(ctx.guild).whitelist() as curr_list: + async with ctx.bot._config.guild(ctx.guild).whitelist() as curr_list: if user_or_role.id in curr_list: removed = True curr_list.remove(user_or_role.id) @@ -1786,7 +1787,7 @@ class Core(commands.Cog, CoreLogic): """ Clears the whitelist. """ - await ctx.bot.db.guild(ctx.guild).whitelist.set([]) + await ctx.bot._config.guild(ctx.guild).whitelist.set([]) await ctx.send(_("Whitelist has been cleared.")) @commands.group() @@ -1811,7 +1812,7 @@ class Core(commands.Cog, CoreLogic): await ctx.send(_("You cannot blacklist an owner!")) return - async with ctx.bot.db.guild(ctx.guild).blacklist() as curr_list: + async with ctx.bot._config.guild(ctx.guild).blacklist() as curr_list: if user_or_role.id not in curr_list: curr_list.append(user_or_role.id) @@ -1825,7 +1826,7 @@ class Core(commands.Cog, CoreLogic): """ Lists blacklisted users and roles. """ - curr_list = await ctx.bot.db.guild(ctx.guild).blacklist() + curr_list = await ctx.bot._config.guild(ctx.guild).blacklist() msg = _("Blacklisted Users and Roles:") for obj in curr_list: @@ -1844,7 +1845,7 @@ class Core(commands.Cog, CoreLogic): removed = False user = isinstance(user_or_role, discord.Member) - async with ctx.bot.db.guild(ctx.guild).blacklist() as curr_list: + async with ctx.bot._config.guild(ctx.guild).blacklist() as curr_list: if user_or_role.id in curr_list: removed = True curr_list.remove(user_or_role.id) @@ -1865,7 +1866,7 @@ class Core(commands.Cog, CoreLogic): """ Clears the blacklist. """ - await ctx.bot.db.guild(ctx.guild).blacklist.set([]) + await ctx.bot._config.guild(ctx.guild).blacklist.set([]) await ctx.send(_("Blacklist has been cleared.")) @checks.guildowner_or_permissions(administrator=True) @@ -1904,7 +1905,7 @@ class Core(commands.Cog, CoreLogic): ) return - async with ctx.bot.db.disabled_commands() as disabled_commands: + async with ctx.bot._config.disabled_commands() as disabled_commands: if command not in disabled_commands: disabled_commands.append(command_obj.qualified_name) @@ -1936,7 +1937,7 @@ class Core(commands.Cog, CoreLogic): await ctx.send(_("You are not allowed to disable that command.")) return - async with ctx.bot.db.guild(ctx.guild).disabled_commands() as disabled_commands: + async with ctx.bot._config.guild(ctx.guild).disabled_commands() as disabled_commands: if command not in disabled_commands: disabled_commands.append(command_obj.qualified_name) @@ -1970,7 +1971,7 @@ class Core(commands.Cog, CoreLogic): ) return - async with ctx.bot.db.disabled_commands() as disabled_commands: + async with ctx.bot._config.disabled_commands() as disabled_commands: with contextlib.suppress(ValueError): disabled_commands.remove(command_obj.qualified_name) @@ -1996,7 +1997,7 @@ class Core(commands.Cog, CoreLogic): await ctx.send(_("You are not allowed to enable that command.")) return - async with ctx.bot.db.guild(ctx.guild).disabled_commands() as disabled_commands: + async with ctx.bot._config.guild(ctx.guild).disabled_commands() as disabled_commands: with contextlib.suppress(ValueError): disabled_commands.remove(command_obj.qualified_name) @@ -2017,7 +2018,7 @@ class Core(commands.Cog, CoreLogic): To include the command name in the message, include the `{command}` placeholder. """ - await ctx.bot.db.disabled_command_msg.set(message) + await ctx.bot._config.disabled_command_msg.set(message) await ctx.tick() @commands.guild_only() @@ -2036,7 +2037,7 @@ class Core(commands.Cog, CoreLogic): configured for automatic moderation action immunity """ - ai_ids = await ctx.bot.db.guild(ctx.guild).autoimmune_ids() + ai_ids = await ctx.bot._config.guild(ctx.guild).autoimmune_ids() roles = {r.name for r in ctx.guild.roles if r.id in ai_ids} members = {str(m) for m in ctx.guild.members if m.id in ai_ids} @@ -2064,7 +2065,7 @@ class Core(commands.Cog, CoreLogic): """ Makes a user or roles immune from automated moderation actions """ - async with ctx.bot.db.guild(ctx.guild).autoimmune_ids() as ai_ids: + async with ctx.bot._config.guild(ctx.guild).autoimmune_ids() as ai_ids: if user_or_role.id in ai_ids: return await ctx.send(_("Already added.")) ai_ids.append(user_or_role.id) @@ -2077,7 +2078,7 @@ class Core(commands.Cog, CoreLogic): """ Makes a user or roles immune from automated moderation actions """ - async with ctx.bot.db.guild(ctx.guild).autoimmune_ids() as ai_ids: + async with ctx.bot._config.guild(ctx.guild).autoimmune_ids() as ai_ids: if user_or_role.id not in ai_ids: return await ctx.send(_("Not in list.")) ai_ids.remove(user_or_role.id) @@ -2111,7 +2112,7 @@ class Core(commands.Cog, CoreLogic): This is the default state. """ - async with ctx.bot.db.owner_opt_out_list() as opt_outs: + async with ctx.bot._config.owner_opt_out_list() as opt_outs: if ctx.author.id in opt_outs: opt_outs.remove(ctx.author.id) @@ -2122,7 +2123,7 @@ class Core(commands.Cog, CoreLogic): """ Opt-out of recieving owner notifications. """ - async with ctx.bot.db.owner_opt_out_list() as opt_outs: + async with ctx.bot._config.owner_opt_out_list() as opt_outs: if ctx.author.id not in opt_outs: opt_outs.append(ctx.author.id) @@ -2141,7 +2142,7 @@ class Core(commands.Cog, CoreLogic): except AttributeError: channel_id = channel - async with ctx.bot.db.extra_owner_destinations() as extras: + async with ctx.bot._config.extra_owner_destinations() as extras: if channel_id not in extras: extras.append(channel_id) @@ -2160,7 +2161,7 @@ class Core(commands.Cog, CoreLogic): except AttributeError: channel_id = channel - async with ctx.bot.db.extra_owner_destinations() as extras: + async with ctx.bot._config.extra_owner_destinations() as extras: if channel_id in extras: extras.remove(channel_id) @@ -2172,7 +2173,7 @@ class Core(commands.Cog, CoreLogic): Lists the configured extra destinations for owner notifications """ - channel_ids = await ctx.bot.db.extra_owner_destinations() + channel_ids = await ctx.bot._config.extra_owner_destinations() if not channel_ids: await ctx.send(_("There are no extra channels being sent to.")) diff --git a/redbot/core/dev_commands.py b/redbot/core/dev_commands.py index 488d13f03..1251ea2e8 100644 --- a/redbot/core/dev_commands.py +++ b/redbot/core/dev_commands.py @@ -126,7 +126,7 @@ class Dev(commands.Cog): self._last_result = result - api_keys = await ctx.bot.db.api_tokens() + api_keys = await ctx.bot._config.api_tokens() result = self.sanitize_output(ctx, api_keys, str(result)) await ctx.send_interactive(self.get_pages(result), box_lang="py") @@ -191,7 +191,7 @@ class Dev(commands.Cog): msg = "{}{}".format(printed, result) else: msg = printed - api_keys = await ctx.bot.db.api_tokens() + api_keys = await ctx.bot._config.api_tokens() msg = self.sanitize_output(ctx, api_keys, msg) await ctx.send_interactive(self.get_pages(msg), box_lang="py") @@ -276,7 +276,7 @@ class Dev(commands.Cog): elif value: msg = "{}".format(value) - api_keys = await ctx.bot.db.api_tokens() + api_keys = await ctx.bot._config.api_tokens() msg = self.sanitize_output(ctx, api_keys, msg) try: diff --git a/redbot/core/events.py b/redbot/core/events.py index 62f53af56..7f594e0b2 100644 --- a/redbot/core/events.py +++ b/redbot/core/events.py @@ -37,19 +37,19 @@ ______ _ ______ _ _ ______ _ def init_events(bot, cli_flags): @bot.event async def on_connect(): - if bot.uptime is None: + if bot._uptime is None: print("Connected to Discord. Getting ready...") @bot.event async def on_ready(): - if bot.uptime is not None: + if bot._uptime is not None: return - bot.uptime = datetime.datetime.utcnow() + bot._uptime = datetime.datetime.utcnow() packages = [] if cli_flags.no_cogs is False: - packages.extend(await bot.db.packages()) + packages.extend(await bot._config.packages()) if cli_flags.load_cogs: packages.extend(cli_flags.load_cogs) @@ -90,8 +90,8 @@ def init_events(bot, cli_flags): except: invite_url = "Could not fetch invite url" - prefixes = cli_flags.prefix or (await bot.db.prefix()) - lang = await bot.db.locale() + prefixes = cli_flags.prefix or (await bot._config.prefix()) + lang = await bot._config.locale() red_pkg = pkg_resources.get_distribution("Red-DiscordBot") dpy_version = discord.__version__ @@ -160,7 +160,7 @@ def init_events(bot, cli_flags): if invite_url: print("\nInvite URL: {}\n".format(invite_url)) - bot.color = discord.Colour(await bot.db.color()) + bot._color = discord.Colour(await bot._config.color()) @bot.event async def on_command_error(ctx, error, unhandled_by_cog=False): @@ -183,7 +183,7 @@ def init_events(bot, cli_flags): elif isinstance(error, commands.UserInputError): await ctx.send_help() elif isinstance(error, commands.DisabledCommand): - disabled_message = await bot.db.disabled_command_msg() + disabled_message = await bot._config.disabled_command_msg() if disabled_message: await ctx.send(disabled_message.replace("{command}", ctx.invoked_with)) elif isinstance(error, commands.CommandInvokeError): @@ -255,12 +255,12 @@ def init_events(bot, cli_flags): @bot.event async def on_message(message): - bot.counter["messages_read"] += 1 + bot._counter["messages_read"] += 1 await bot.process_commands(message) discord_now = message.created_at if ( - not bot.checked_time_accuracy - or (discord_now - timedelta(minutes=60)) > bot.checked_time_accuracy + not bot._checked_time_accuracy + or (discord_now - timedelta(minutes=60)) > bot._checked_time_accuracy ): system_now = datetime.datetime.utcnow() diff = abs((discord_now - system_now).total_seconds()) @@ -270,28 +270,28 @@ def init_events(bot, cli_flags): "clock. Any time sensitive code may fail.", diff, ) - bot.checked_time_accuracy = discord_now + bot._checked_time_accuracy = discord_now @bot.event async def on_resumed(): - bot.counter["sessions_resumed"] += 1 + bot._counter["sessions_resumed"] += 1 @bot.event async def on_command(command): - bot.counter["processed_commands"] += 1 + bot._counter["processed_commands"] += 1 @bot.event async def on_command_add(command: commands.Command): - disabled_commands = await bot.db.disabled_commands() + disabled_commands = await bot._config.disabled_commands() if command.qualified_name in disabled_commands: command.enabled = False for guild in bot.guilds: - disabled_commands = await bot.db.guild(guild).disabled_commands() + disabled_commands = await bot._config.guild(guild).disabled_commands() if command.qualified_name in disabled_commands: command.disable_in(guild) async def _guild_added(guild: discord.Guild): - disabled_commands = await bot.db.guild(guild).disabled_commands() + disabled_commands = await bot._config.guild(guild).disabled_commands() for command_name in disabled_commands: command_obj = bot.get_command(command_name) if command_obj is not None: @@ -310,7 +310,7 @@ def init_events(bot, cli_flags): @bot.event async def on_guild_leave(guild: discord.Guild): # Clean up any unneeded checks - disabled_commands = await bot.db.guild(guild).disabled_commands() + disabled_commands = await bot._config.guild(guild).disabled_commands() for command_name in disabled_commands: command_obj = bot.get_command(command_name) if command_obj is not None: @@ -322,7 +322,7 @@ def init_events(bot, cli_flags): for c in confs: uuid = c.unique_identifier group_data = c.custom_groups - await bot.db.custom("CUSTOM_GROUPS", c.cog_name, uuid).set(group_data) + await bot._config.custom("CUSTOM_GROUPS", c.cog_name, uuid).set(group_data) def _get_startup_screen_specs(): diff --git a/redbot/core/global_checks.py b/redbot/core/global_checks.py index a84f8e2e1..7bdb5d1a9 100644 --- a/redbot/core/global_checks.py +++ b/redbot/core/global_checks.py @@ -9,11 +9,11 @@ def init_global_checks(bot): if await bot.is_owner(ctx.author): return True - whitelist = await bot.db.whitelist() + whitelist = await bot._config.whitelist() if whitelist: return ctx.author.id in whitelist - return ctx.author.id not in await bot.db.blacklist() + return ctx.author.id not in await bot._config.blacklist() @bot.check_once async def local_perms(ctx: commands.Context): @@ -22,7 +22,7 @@ def init_global_checks(bot): return True elif ctx.guild is None: return True - guild_settings = bot.db.guild(ctx.guild) + guild_settings = bot._config.guild(ctx.guild) local_blacklist = await guild_settings.blacklist() local_whitelist = await guild_settings.whitelist() diff --git a/redbot/core/utils/__init__.py b/redbot/core/utils/__init__.py index c97f7ac45..9fcf37bcc 100644 --- a/redbot/core/utils/__init__.py +++ b/redbot/core/utils/__init__.py @@ -221,9 +221,9 @@ async def fuzzy_command_search( """ if ctx.guild is not None: - enabled = await ctx.bot.db.guild(ctx.guild).fuzzy() + enabled = await ctx.bot._config.guild(ctx.guild).fuzzy() else: - enabled = await ctx.bot.db.fuzzy() + enabled = await ctx.bot._config.fuzzy() if not enabled: return diff --git a/redbot/core/utils/mod.py b/redbot/core/utils/mod.py index 9191d8889..030eaa3ba 100644 --- a/redbot/core/utils/mod.py +++ b/redbot/core/utils/mod.py @@ -128,9 +128,10 @@ async def is_mod_or_superior( elif isinstance(obj, discord.Member): user = obj elif isinstance(obj, discord.Role): - if obj.id in await bot.db.guild(obj.guild).mod_role(): + gid = obj.guild.id + if obj in await bot.get_admin_role_ids(gid): return True - if obj.id in await bot.db.guild(obj.guild).admin_role(): + if obj in await bot.get_mod_role_ids(gid): return True return False else: @@ -209,7 +210,7 @@ async def is_admin_or_superior( elif isinstance(obj, discord.Member): user = obj elif isinstance(obj, discord.Role): - return obj.id in await bot.db.guild(obj.guild).admin_role() + return obj.id in await bot.get_admin_role_ids(obj.guild.id) else: raise TypeError("Only messages, members or roles may be passed")