mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[Core] add [p]set api list and [p]set api remove (#4370)
* add get_shared_api_keys
* add set listapi command
* fix typo
* refactor `[p]set listapi` into `[p]set api list`
* remove unnecessary check
* fix decorators
* corrected wording
* add remove_shared_api_services
* add `set api remove`
* further typo sniping
* bugsniping
* minor typo
* aaaaaaaaa
* Apply suggestions from code review
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
* update api docstring to reflect new subcommands
* Apply suggestions from code review
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
* update framework_apikeys.rst with new methods
* Update redbot/core/bot.py
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
* rewrite get_shared_api_services into a special case of
get_shared_api_tokens
* rewrite api_list to include keys and tokens in response
* don't show secrets
* better api_remove response
* black
* remove nonexistent method
* remove unnecessary import
* fix wording
* Improve docstrings and type hints
- added overloads to help out developers a bit more
* this wasn't necessary, but development tools work better
with this information
- fixed type hint to use Union as now
its return type depends on whether `service_name` is passed
- updated docstrings to contain information about the added behavior
* Use `humanize_list()` rather than `str.join()`
This is done for consistency within Red
and it makes the list have the last element joined
with `and` (or its equivalent in chosen locale)
* Use `.format()` after translation is applied
If `.format()` is used before `_()`, the search for translation is done
with the string that already has the dynamic text added,
which results in no matches.
* Add plural support
* Improve error message
Updated message to be more specific
(used phrases: "None of the services" and "had any keys set")
and a bit more nice to the user (judging word "anyway" removed)
* Improve readability of `[p]set api list`
It's a lot clearer when the sublists are indented,
especially on mobile where code blocks aren't colored at all.
New look:
https://user-images.githubusercontent.com/6032823/94614944-3bbd7c80-02a7-11eb-89e4-64bdf06c650b.png
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
This commit is contained in:
parent
8b477db0a6
commit
b45e62f354
@ -73,3 +73,5 @@ Additional References
|
|||||||
.. automethod:: Red.set_shared_api_tokens
|
.. automethod:: Red.set_shared_api_tokens
|
||||||
|
|
||||||
.. automethod:: Red.remove_shared_api_tokens
|
.. automethod:: Red.remove_shared_api_tokens
|
||||||
|
|
||||||
|
.. automethod:: Red.remove_shared_api_services
|
||||||
|
|||||||
@ -26,6 +26,7 @@ from typing import (
|
|||||||
Any,
|
Any,
|
||||||
Literal,
|
Literal,
|
||||||
MutableMapping,
|
MutableMapping,
|
||||||
|
overload,
|
||||||
)
|
)
|
||||||
from types import MappingProxyType
|
from types import MappingProxyType
|
||||||
|
|
||||||
@ -986,21 +987,36 @@ class RedBase(
|
|||||||
"""
|
"""
|
||||||
return await self._config.guild(discord.Object(id=guild_id)).mod_role()
|
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]:
|
@overload
|
||||||
|
async def get_shared_api_tokens(self, service_name: str = ...) -> Dict[str, str]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
async def get_shared_api_tokens(self, service_name: None = ...) -> Dict[str, Dict[str, str]]:
|
||||||
|
...
|
||||||
|
|
||||||
|
async def get_shared_api_tokens(
|
||||||
|
self, service_name: Optional[str] = None
|
||||||
|
) -> Union[Dict[str, Dict[str, str]], Dict[str, str]]:
|
||||||
"""
|
"""
|
||||||
Gets the shared API tokens for a service
|
Gets the shared API tokens for a service, or all of them if no argument specified.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
service_name: str
|
service_name: str, optional
|
||||||
The service to get tokens for.
|
The service to get tokens for. Leave empty to get tokens for all services.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
Dict[str, str]
|
Dict[str, Dict[str, str]] or Dict[str, str]
|
||||||
A Mapping of token names to tokens.
|
A Mapping of token names to tokens.
|
||||||
This mapping exists because some services have multiple tokens.
|
This mapping exists because some services have multiple tokens.
|
||||||
|
If ``service_name`` is `None`, this method will return
|
||||||
|
a mapping with mappings for all services.
|
||||||
"""
|
"""
|
||||||
|
if service_name is None:
|
||||||
|
return await self._config.custom(SHARED_API_TOKENS).all()
|
||||||
|
else:
|
||||||
return await self._config.custom(SHARED_API_TOKENS, service_name).all()
|
return await self._config.custom(SHARED_API_TOKENS, service_name).all()
|
||||||
|
|
||||||
async def set_shared_api_tokens(self, service_name: str, **tokens: str):
|
async def set_shared_api_tokens(self, service_name: str, **tokens: str):
|
||||||
@ -1051,6 +1067,25 @@ class RedBase(
|
|||||||
for name in token_names:
|
for name in token_names:
|
||||||
group.pop(name, None)
|
group.pop(name, None)
|
||||||
|
|
||||||
|
async def remove_shared_api_services(self, *service_names: str):
|
||||||
|
"""
|
||||||
|
Removes shared API services, as well as keys and tokens associated with them.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
*service_names: str
|
||||||
|
The services to remove.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
----------
|
||||||
|
Removing the youtube service
|
||||||
|
|
||||||
|
>>> await ctx.bot.remove_shared_api_services("youtube")
|
||||||
|
"""
|
||||||
|
async with self._config.custom(SHARED_API_TOKENS).all() as group:
|
||||||
|
for service in service_names:
|
||||||
|
group.pop(service, None)
|
||||||
|
|
||||||
async def get_context(self, message, *, cls=commands.Context):
|
async def get_context(self, message, *, cls=commands.Context):
|
||||||
return await super().get_context(message, cls=cls)
|
return await super().get_context(message, cls=cls)
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import aiohttp
|
|||||||
import discord
|
import discord
|
||||||
from babel import Locale as BabelLocale, UnknownLocaleError
|
from babel import Locale as BabelLocale, UnknownLocaleError
|
||||||
from redbot.core.data_manager import storage_type
|
from redbot.core.data_manager import storage_type
|
||||||
|
from redbot.core.utils.chat_formatting import box, pagify
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
__version__,
|
__version__,
|
||||||
@ -2071,10 +2072,10 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
|
|||||||
else:
|
else:
|
||||||
await ctx.send(_("Text must be fewer than 1024 characters long."))
|
await ctx.send(_("Text must be fewer than 1024 characters long."))
|
||||||
|
|
||||||
@_set.command()
|
@_set.group(invoke_without_command=True)
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def api(self, ctx: commands.Context, service: str, *, tokens: TokenConverter):
|
async def api(self, ctx: commands.Context, service: str, *, tokens: TokenConverter):
|
||||||
"""Set various external API tokens.
|
"""Set, list or remove 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.
|
||||||
|
|
||||||
@ -2089,6 +2090,47 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
|
|||||||
await ctx.bot.set_shared_api_tokens(service, **tokens)
|
await ctx.bot.set_shared_api_tokens(service, **tokens)
|
||||||
await ctx.send(_("`{service}` API tokens have been set.").format(service=service))
|
await ctx.send(_("`{service}` API tokens have been set.").format(service=service))
|
||||||
|
|
||||||
|
@api.command(name="list")
|
||||||
|
async def api_list(self, ctx: commands.Context):
|
||||||
|
"""Show all external API services along with their keys that have been set.
|
||||||
|
|
||||||
|
Secrets are not shown."""
|
||||||
|
|
||||||
|
services: dict = await ctx.bot.get_shared_api_tokens()
|
||||||
|
if not services:
|
||||||
|
await ctx.send(_("No API services have been set yet."))
|
||||||
|
return
|
||||||
|
|
||||||
|
sorted_services = sorted(services.keys(), key=str.lower)
|
||||||
|
|
||||||
|
joined = _("Set API services:\n") if len(services) > 1 else _("Set API service:\n")
|
||||||
|
for service_name in sorted_services:
|
||||||
|
joined += "+ {}\n".format(service_name)
|
||||||
|
for key_name in services[service_name].keys():
|
||||||
|
joined += " - {}\n".format(key_name)
|
||||||
|
for page in pagify(joined, ["\n"], shorten_by=16):
|
||||||
|
await ctx.send(box(page.lstrip(" "), lang="diff"))
|
||||||
|
|
||||||
|
@api.command(name="remove")
|
||||||
|
async def api_remove(self, ctx: commands.Context, *services: str):
|
||||||
|
"""Remove the given services with all their keys and tokens."""
|
||||||
|
bot_services = (await ctx.bot.get_shared_api_tokens()).keys()
|
||||||
|
services = [s for s in services if s in bot_services]
|
||||||
|
|
||||||
|
if services:
|
||||||
|
await self.bot.remove_shared_api_services(*services)
|
||||||
|
if len(services) > 1:
|
||||||
|
msg = _("Services deleted successfully:\n{services_list}").format(
|
||||||
|
services_list=humanize_list(services)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
msg = _("Service deleted successfully: {service_name}").format(
|
||||||
|
service_name=services[0]
|
||||||
|
)
|
||||||
|
await ctx.send(msg)
|
||||||
|
else:
|
||||||
|
await ctx.send(_("None of the services you provided had any keys set."))
|
||||||
|
|
||||||
@commands.group()
|
@commands.group()
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def helpset(self, ctx: commands.Context):
|
async def helpset(self, ctx: commands.Context):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user