mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-11 05:38:54 -05:00
[Core] Improve API token converter (#2692)
* improve api converter * make usage more clear
This commit is contained in:
parent
2e271d695b
commit
68590dfdb8
@ -1,7 +1,9 @@
|
|||||||
import re
|
import re
|
||||||
from typing import TYPE_CHECKING
|
import functools
|
||||||
|
from typing import TYPE_CHECKING, Optional, List, Dict
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
from discord.ext import commands as dpy_commands
|
||||||
|
|
||||||
from . import BadArgument
|
from . import BadArgument
|
||||||
from ..i18n import Translator
|
from ..i18n import Translator
|
||||||
@ -9,7 +11,7 @@ from ..i18n import Translator
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .context import Context
|
from .context import Context
|
||||||
|
|
||||||
__all__ = ["GuildConverter"]
|
__all__ = ["GuildConverter", "APIToken", "DictConverter", "get_dict_converter"]
|
||||||
|
|
||||||
_ = Translator("commands.converter", __file__)
|
_ = Translator("commands.converter", __file__)
|
||||||
|
|
||||||
@ -47,16 +49,20 @@ class APIToken(discord.ext.commands.Converter):
|
|||||||
This will parse the input argument separating the key value pairs into a
|
This will parse the input argument separating the key value pairs into a
|
||||||
format to be used for the core bots API token storage.
|
format to be used for the core bots API token storage.
|
||||||
|
|
||||||
This will split the argument by either `;` or `,` and return a dict
|
This will split the argument by either `;` ` `, or `,` and return a dict
|
||||||
to be stored. Since all API's are different and have different naming convention,
|
to be stored. Since all API's are different and have different naming convention,
|
||||||
this leaves the onus on the cog creator to clearly define how to setup the correct
|
this leaves the onus on the cog creator to clearly define how to setup the correct
|
||||||
credential names for their cogs.
|
credential names for their cogs.
|
||||||
|
|
||||||
|
Note: Core usage of this has been replaced with DictConverter use instead.
|
||||||
|
|
||||||
|
This may be removed at a later date (with warning)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def convert(self, ctx, argument) -> dict:
|
async def convert(self, ctx, argument) -> dict:
|
||||||
bot = ctx.bot
|
bot = ctx.bot
|
||||||
result = {}
|
result = {}
|
||||||
match = re.split(r";|,", argument)
|
match = re.split(r";|,| ", argument)
|
||||||
# provide two options to split incase for whatever reason one is part of the api key we're using
|
# provide two options to split incase for whatever reason one is part of the api key we're using
|
||||||
if len(match) > 1:
|
if len(match) > 1:
|
||||||
result[match[0]] = "".join(r for r in match[1:])
|
result[match[0]] = "".join(r for r in match[1:])
|
||||||
@ -65,3 +71,48 @@ class APIToken(discord.ext.commands.Converter):
|
|||||||
if not result:
|
if not result:
|
||||||
raise BadArgument(_("The provided tokens are not in a valid format."))
|
raise BadArgument(_("The provided tokens are not in a valid format."))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class DictConverter(dpy_commands.Converter):
|
||||||
|
"""
|
||||||
|
Converts pairs of space seperated values to a dict
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *expected_keys: str, delims: Optional[List[str]] = None):
|
||||||
|
self.expected_keys = expected_keys
|
||||||
|
self.delims = delims or [" "]
|
||||||
|
self.pattern = re.compile(r"|".join(re.escape(d) for d in self.delims))
|
||||||
|
|
||||||
|
async def convert(self, ctx: "Context", argument: str) -> Dict[str, str]:
|
||||||
|
|
||||||
|
ret: Dict[str, str] = {}
|
||||||
|
args = self.pattern.split(argument)
|
||||||
|
|
||||||
|
if len(args) % 2 != 0:
|
||||||
|
raise BadArgument()
|
||||||
|
|
||||||
|
iterator = iter(args)
|
||||||
|
|
||||||
|
for key in iterator:
|
||||||
|
if self.expected_keys and key not in self.expected_keys:
|
||||||
|
raise BadArgument(_("Unexpected key {key}").format(key))
|
||||||
|
|
||||||
|
ret[key] = next(iterator)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def get_dict_converter(*expected_keys: str, delims: Optional[List[str]] = None) -> type:
|
||||||
|
"""
|
||||||
|
Returns a typechecking safe `DictConverter` suitable for use with discord.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
class PartialMeta(type(DictConverter)):
|
||||||
|
__call__ = functools.partialmethod(
|
||||||
|
type(DictConverter).__call__, *expected_keys, delims=delims
|
||||||
|
)
|
||||||
|
|
||||||
|
class ValidatedConverter(DictConverter, metaclass=PartialMeta):
|
||||||
|
pass
|
||||||
|
|
||||||
|
return ValidatedConverter
|
||||||
|
|||||||
@ -45,6 +45,8 @@ log = logging.getLogger("red")
|
|||||||
|
|
||||||
_ = i18n.Translator("Core", __file__)
|
_ = i18n.Translator("Core", __file__)
|
||||||
|
|
||||||
|
TokenConverter = commands.get_dict_converter(delims=[" ", ",", ";"])
|
||||||
|
|
||||||
|
|
||||||
class CoreLogic:
|
class CoreLogic:
|
||||||
def __init__(self, bot: "Red"):
|
def __init__(self, bot: "Red"):
|
||||||
@ -1063,7 +1065,7 @@ class Core(commands.Cog, CoreLogic):
|
|||||||
|
|
||||||
@_set.command()
|
@_set.command()
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def api(self, ctx: commands.Context, service: str, *tokens: commands.converter.APIToken):
|
async def api(self, ctx: commands.Context, service: str, *, tokens: TokenConverter):
|
||||||
"""Set various external API tokens.
|
"""Set various external API tokens.
|
||||||
|
|
||||||
This setting will be asked for by some 3rd party cogs and some core cogs.
|
This setting will be asked for by some 3rd party cogs and some core cogs.
|
||||||
@ -1076,8 +1078,7 @@ class Core(commands.Cog, CoreLogic):
|
|||||||
"""
|
"""
|
||||||
if ctx.channel.permissions_for(ctx.me).manage_messages:
|
if ctx.channel.permissions_for(ctx.me).manage_messages:
|
||||||
await ctx.message.delete()
|
await ctx.message.delete()
|
||||||
entry = {k: v for t in tokens for k, v in t.items()}
|
await ctx.bot.db.api_tokens.set_raw(service, value=tokens)
|
||||||
await ctx.bot.db.api_tokens.set_raw(service, value=entry)
|
|
||||||
await ctx.send(_("`{service}` API tokens have been set.").format(service=service))
|
await ctx.send(_("`{service}` API tokens have been set.").format(service=service))
|
||||||
|
|
||||||
@commands.group()
|
@commands.group()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user