mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
Cache prefixes (#3150)
* Cache prefixes - This works towards #3148 - Ends up centralizing some logic - Including that prefixes should be a reverse sorted list * handle global prefix attempts at none * fix prefix set for server * cache using guild id
This commit is contained in:
parent
d1b7f836db
commit
cd7f4681a4
1
changelog.d/3148.misc.1.rst
Normal file
1
changelog.d/3148.misc.1.rst
Normal file
@ -0,0 +1 @@
|
||||
Cache prefixes rather than lookup from config each time
|
||||
@ -36,6 +36,8 @@ from .dev_commands import Dev
|
||||
from .events import init_events
|
||||
from .global_checks import init_global_checks
|
||||
|
||||
from .settings_caches import PrefixManager
|
||||
|
||||
from .rpc import RPCMixin
|
||||
from .utils import common_filters
|
||||
|
||||
@ -124,23 +126,13 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d
|
||||
|
||||
self._config.init_custom(SHARED_API_TOKENS, 2)
|
||||
self._config.register_custom(SHARED_API_TOKENS)
|
||||
self._prefix_cache = PrefixManager(self._config, cli_flags)
|
||||
|
||||
async def prefix_manager(bot, message):
|
||||
if not cli_flags.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._config.guild(message.guild).prefix()
|
||||
async def prefix_manager(bot, message) -> List[str]:
|
||||
prefixes = await self._prefix_cache.get_prefixes(message.guild)
|
||||
if cli_flags.mentionable:
|
||||
return (
|
||||
when_mentioned_or(*server_prefix)(bot, message)
|
||||
if server_prefix
|
||||
else when_mentioned_or(*global_prefix)(bot, message)
|
||||
)
|
||||
else:
|
||||
return server_prefix if server_prefix else global_prefix
|
||||
return when_mentioned_or(*prefixes)(bot, message)
|
||||
return prefixes
|
||||
|
||||
if "command_prefix" not in kwargs:
|
||||
kwargs["command_prefix"] = prefix_manager
|
||||
|
||||
@ -135,7 +135,9 @@ def parse_cli_flags(args):
|
||||
"security implications if misused. Can be "
|
||||
"multiple.",
|
||||
)
|
||||
parser.add_argument("--prefix", "-p", action="append", help="Global prefix. Can be multiple")
|
||||
parser.add_argument(
|
||||
"--prefix", "-p", action="append", help="Global prefix. Can be multiple", default=[]
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-prompt",
|
||||
action="store_true",
|
||||
|
||||
@ -257,10 +257,9 @@ class CoreLogic:
|
||||
The current (or new) list of prefixes.
|
||||
"""
|
||||
if prefixes:
|
||||
prefixes = sorted(prefixes, reverse=True)
|
||||
await self.bot._config.prefix.set(prefixes)
|
||||
await self.bot._prefix_cache.set_prefixes(guild=None, prefixes=prefixes)
|
||||
return prefixes
|
||||
return await self.bot._config.prefix()
|
||||
return await self.bot._prefix_cache.get_prefixes(guild=None)
|
||||
|
||||
@classmethod
|
||||
async def _version_info(cls) -> Dict[str, str]:
|
||||
@ -847,15 +846,13 @@ class Core(commands.Cog, CoreLogic):
|
||||
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._config.guild(ctx.guild).prefix()
|
||||
guild_settings = _("Admin roles: {admin}\nMod roles: {mod}\n").format(
|
||||
admin=admin_roles_str, mod=mod_roles_str
|
||||
)
|
||||
else:
|
||||
guild_settings = ""
|
||||
prefixes = None # This is correct. The below can happen in a guild.
|
||||
if not prefixes:
|
||||
prefixes = await ctx.bot._config.prefix()
|
||||
|
||||
prefixes = await ctx.bot._prefix_cache.get_prefixes(ctx.guild)
|
||||
locale = await ctx.bot._config.locale()
|
||||
|
||||
prefix_string = " ".join(prefixes)
|
||||
@ -1182,11 +1179,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._config.guild(ctx.guild).prefix.set([])
|
||||
await ctx.bot._prefix_cache.set_prefixes(guild=ctx.guild, prefixes=[])
|
||||
await ctx.send(_("Guild prefixes have been reset."))
|
||||
return
|
||||
prefixes = sorted(prefixes, reverse=True)
|
||||
await ctx.bot._config.guild(ctx.guild).prefix.set(prefixes)
|
||||
await ctx.bot._prefix_cache.set_prefixes(guild=ctx.guild, prefixes=prefixes)
|
||||
await ctx.send(_("Prefix set."))
|
||||
|
||||
@_set.command()
|
||||
|
||||
53
redbot/core/settings_caches.py
Normal file
53
redbot/core/settings_caches.py
Normal file
@ -0,0 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, List, Optional
|
||||
from argparse import Namespace
|
||||
|
||||
import discord
|
||||
|
||||
from .config import Config
|
||||
|
||||
|
||||
class PrefixManager:
|
||||
def __init__(self, config: Config, cli_flags: Namespace):
|
||||
self._config: Config = config
|
||||
self._global_prefix_overide: Optional[List[str]] = sorted(
|
||||
cli_flags.prefix, reverse=True
|
||||
) or None
|
||||
self._cached: Dict[Optional[int], List[str]] = {}
|
||||
|
||||
async def get_prefixes(self, guild: Optional[discord.Guild] = None) -> List[str]:
|
||||
ret: List[str]
|
||||
|
||||
gid: Optional[int] = guild.id if guild else None
|
||||
|
||||
if gid in self._cached:
|
||||
ret = self._cached[gid].copy()
|
||||
else:
|
||||
if gid is not None:
|
||||
ret = await self._config.guild_from_id(gid).prefix()
|
||||
if not ret:
|
||||
ret = await self.get_prefixes(None)
|
||||
else:
|
||||
ret = self._global_prefix_overide or (await self._config.prefix())
|
||||
|
||||
self._cached[gid] = ret.copy()
|
||||
|
||||
return ret
|
||||
|
||||
async def set_prefixes(
|
||||
self, guild: Optional[discord.Guild] = None, prefixes: Optional[List[str]] = None
|
||||
):
|
||||
gid: Optional[int] = guild.id if guild else None
|
||||
prefixes = prefixes or []
|
||||
if not isinstance(prefixes, list) and not all(isinstance(pfx, str) for pfx in prefixes):
|
||||
raise TypeError("Prefixes must be a list of strings")
|
||||
prefixes = sorted(prefixes, reverse=True)
|
||||
if gid is None:
|
||||
if not prefixes:
|
||||
raise ValueError("You must have at least one prefix.")
|
||||
self._cached.clear()
|
||||
await self._config.prefix.set(prefixes)
|
||||
else:
|
||||
del self._cached[gid]
|
||||
await self._config.guild_from_id(gid).prefix.set(prefixes)
|
||||
Loading…
x
Reference in New Issue
Block a user