Make command usage in help for required arguments consistent (#4589)

* Make command usage in help for required arguments consistent

* Bob 3

* Bob 1

* Docstring updates

* Address Flame's review

* Update cog guides in docs
This commit is contained in:
jack1142 2020-12-22 20:14:47 +01:00 committed by GitHub
parent 59e1e31634
commit b36a702e62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 109 additions and 214 deletions

View File

@ -83,7 +83,7 @@ cog info
.. code-block:: none .. code-block:: none
[p]cog info <repo_name> <cog_name> [p]cog info <repo> <cog>
**Description** **Description**
@ -94,8 +94,8 @@ Example:
**Arguments** **Arguments**
- ``<repo_name>`` The repo to get cog info from. - ``<repo>`` The repo to get cog info from.
- ``<cog_name>`` The cog to get info on. - ``<cog>`` The cog to get info on.
.. _downloader-command-cog-install: .. _downloader-command-cog-install:
@ -107,7 +107,7 @@ cog install
.. code-block:: none .. code-block:: none
[p]cog install <repo_name> <cogs> [p]cog install <repo> <cogs...>
**Description** **Description**
@ -119,8 +119,8 @@ Examples:
**Arguments** **Arguments**
- ``<repo_name>`` The name of the repo to install cogs from. - ``<repo>`` The name of the repo to install cogs from.
- ``<cogs>`` The cog or cogs to install. - ``<cogs...>`` The cog or cogs to install.
.. _downloader-command-cog-installversion: .. _downloader-command-cog-installversion:
@ -132,7 +132,7 @@ cog installversion
.. code-block:: none .. code-block:: none
[p]cog installversion <repo_name> <revision> <cogs> [p]cog installversion <repo> <revision> <cogs...>
**Description** **Description**
@ -148,9 +148,9 @@ Example:
**Arguments** **Arguments**
- ``<repo_name>`` The name of the repo to install cogs from. - ``<repo>`` The name of the repo to install cogs from.
- ``<revision>`` The revision to install from. - ``<revision>`` The revision to install from.
- ``<cogs>`` The cog or cogs to install. - ``<cogs...>`` The cog or cogs to install.
.. _downloader-command-cog-list: .. _downloader-command-cog-list:
@ -162,7 +162,7 @@ cog list
.. code-block:: none .. code-block:: none
[p]cog list <repo_name> [p]cog list <repo>
**Description** **Description**
@ -173,7 +173,7 @@ Example:
**Arguments** **Arguments**
- ``<repo_name>`` The repo to list cogs from. - ``<repo>`` The repo to list cogs from.
.. _downloader-command-cog-listpinned: .. _downloader-command-cog-listpinned:
@ -201,7 +201,7 @@ cog pin
.. code-block:: none .. code-block:: none
[p]cog pin <cogs> [p]cog pin <cogs...>
**Description** **Description**
@ -213,7 +213,7 @@ Examples:
**Arguments** **Arguments**
- ``<cogs>`` The cog or cogs to pin. Must already be installed. - ``<cogs...>`` The cog or cogs to pin. Must already be installed.
.. _downloader-command-cog-uninstall: .. _downloader-command-cog-uninstall:
@ -225,7 +225,7 @@ cog uninstall
.. code-block:: none .. code-block:: none
[p]cog uninstall <cogs> [p]cog uninstall <cogs...>
**Description** **Description**
@ -240,7 +240,7 @@ Examples:
**Arguments** **Arguments**
- ``<cogs>`` The cog or cogs to uninstall. - ``<cogs...>`` The cog or cogs to uninstall.
.. _downloader-command-cog-unpin: .. _downloader-command-cog-unpin:
@ -252,7 +252,7 @@ cog unpin
.. code-block:: none .. code-block:: none
[p]cog unpin <cogs> [p]cog unpin <cogs...>
**Description** **Description**
@ -264,7 +264,7 @@ Examples:
**Arguments** **Arguments**
- ``<cogs>`` The cog or cogs to unpin. Must already be installed and pinned. - ``<cogs...>`` The cog or cogs to unpin. Must already be installed and pinned.
.. _downloader-command-cog-update: .. _downloader-command-cog-update:
@ -300,7 +300,7 @@ cog updateallfromrepos
.. code-block:: none .. code-block:: none
[p]cog updateallfromrepos <repos> [p]cog updateallfromrepos <repos...>
**Description** **Description**
@ -312,7 +312,7 @@ Examples:
**Arguments** **Arguments**
- ``<repos>`` The repo or repos to update all cogs from. - ``<repos...>`` The repo or repos to update all cogs from.
.. _downloader-command-cog-updatetoversion: .. _downloader-command-cog-updatetoversion:
@ -324,7 +324,7 @@ cog updatetoversion
.. code-block:: none .. code-block:: none
[p]cog updatetoversion <repo_name> <revision> [cogs] [p]cog updatetoversion <repo> <revision> [cogs...]
**Description** **Description**
@ -341,9 +341,9 @@ Example:
**Arguments** **Arguments**
- ``<repo_name>`` The repo or repos to update all cogs from. - ``<repo>`` The repo or repos to update all cogs from.
- ``<revision>`` The revision to update to. - ``<revision>`` The revision to update to.
- ``[cogs]`` The cog or cogs to update. - ``[cogs...]`` The cog or cogs to update.
.. _downloader-command-findcog: .. _downloader-command-findcog:
@ -382,7 +382,7 @@ pipinstall
.. code-block:: none .. code-block:: none
[p]pipinstall [deps...] [p]pipinstall <deps...>
**Description** **Description**
@ -396,7 +396,7 @@ Improper usage of this command can break your bot, be careful.
**Arguments** **Arguments**
- ``[deps...]`` The package or packages you wish to install. - ``<deps...>`` The package or packages you wish to install.
.. _downloader-command-repo: .. _downloader-command-repo:
@ -455,7 +455,7 @@ repo delete
.. code-block:: none .. code-block:: none
[p]repo delete <repo_name> [p]repo delete <repo>
.. tip:: Aliases: ``repo remove``, ``repo del`` .. tip:: Aliases: ``repo remove``, ``repo del``
@ -468,7 +468,7 @@ Example:
**Arguments** **Arguments**
- ``<repo_name>`` The name of an already added repo - ``<repo>`` The name of an already added repo
.. _downloader-command-repo-info: .. _downloader-command-repo-info:
@ -480,7 +480,7 @@ repo info
.. code-block:: none .. code-block:: none
[p]repo info <repo_name> [p]repo info <repo>
**Description** **Description**
@ -491,7 +491,7 @@ Example:
**Arguments** **Arguments**
- ``<repo_name>`` The name of the repo to show info about. - ``<repo>`` The name of the repo to show info about.
.. _downloader-command-repo-list: .. _downloader-command-repo-list:

View File

@ -191,7 +191,7 @@ streamset message mention
.. code-block:: none .. code-block:: none
[p]streamset message mention [message] [p]streamset message mention <message>
**Description** **Description**
@ -205,7 +205,7 @@ For example: ``[p]streamset message mention {mention}, {stream} is live!``
**Arguments** **Arguments**
* ``[message]``: Your alert message * ``<message>``: Your alert message
.. _streams-command-streamset-message-nomention: .. _streams-command-streamset-message-nomention:
@ -217,7 +217,7 @@ streamset message nomention
.. code-block:: none .. code-block:: none
[p]streamset message nomention [message] [p]streamset message nomention <message>
**Description** **Description**
@ -229,7 +229,7 @@ For example: ``[p]streamset message nomention {stream} is live!``
**Arguments** **Arguments**
* ``[message]``: Your alert message * ``<message>``: Your alert message
.. _streams-command-streamset-message-clear: .. _streams-command-streamset-message-clear:

View File

@ -478,7 +478,7 @@ class Downloader(commands.Cog):
for page in pagify(content): for page in pagify(content):
await target.send(page) await target.send(page)
@commands.command() @commands.command(require_var_positional=True)
@checks.is_owner() @checks.is_owner()
async def pipinstall(self, ctx: commands.Context, *deps: str) -> None: async def pipinstall(self, ctx: commands.Context, *deps: str) -> None:
""" """
@ -492,11 +492,8 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `[deps...]` The package or packages you wish to install. - `<deps...>` The package or packages you wish to install.
""" """
if not deps:
await ctx.send_help()
return
repo = Repo("", "", "", "", Path.cwd()) repo = Repo("", "", "", "", Path.cwd())
async with ctx.typing(): async with ctx.typing():
success = await repo.install_raw_requirements(deps, self.LIB_PATH) success = await repo.install_raw_requirements(deps, self.LIB_PATH)
@ -582,7 +579,7 @@ class Downloader(commands.Cog):
if repo.install_msg: if repo.install_msg:
await ctx.send(repo.install_msg.replace("[p]", ctx.clean_prefix)) await ctx.send(repo.install_msg.replace("[p]", ctx.clean_prefix))
@repo.command(name="delete", aliases=["remove", "del"], usage="<repo_name>") @repo.command(name="delete", aliases=["remove", "del"])
async def _repo_del(self, ctx: commands.Context, repo: Repo) -> None: async def _repo_del(self, ctx: commands.Context, repo: Repo) -> None:
""" """
Remove a repo and its files. Remove a repo and its files.
@ -592,7 +589,7 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repo_name>` The name of an already added repo - `<repo>` The name of an already added repo
""" """
await self._repo_manager.delete_repo(repo.name) await self._repo_manager.delete_repo(repo.name)
@ -612,7 +609,7 @@ class Downloader(commands.Cog):
for page in pagify(joined, ["\n"], shorten_by=16): for page in pagify(joined, ["\n"], shorten_by=16):
await ctx.send(box(page.lstrip(" "), lang="diff")) await ctx.send(box(page.lstrip(" "), lang="diff"))
@repo.command(name="info", usage="<repo_name>") @repo.command(name="info")
async def _repo_info(self, ctx: commands.Context, repo: Repo) -> None: async def _repo_info(self, ctx: commands.Context, repo: Repo) -> None:
"""Show information about a repo. """Show information about a repo.
@ -621,7 +618,7 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repo_name>` The name of the repo to show info about. - `<repo>` The name of the repo to show info about.
""" """
made_by = ", ".join(repo.author) or _("Missing from info.json") made_by = ", ".join(repo.author) or _("Missing from info.json")
@ -737,7 +734,7 @@ class Downloader(commands.Cog):
) )
) )
@cog.command(name="install", usage="<repo_name> <cogs>") @cog.command(name="install", usage="<repo> <cogs...>", require_var_positional=True)
async def _cog_install(self, ctx: commands.Context, repo: Repo, *cog_names: str) -> None: async def _cog_install(self, ctx: commands.Context, repo: Repo, *cog_names: str) -> None:
"""Install a cog from the given repo. """Install a cog from the given repo.
@ -747,14 +744,16 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repo_name>` The name of the repo to install cogs from. - `<repo>` The name of the repo to install cogs from.
- `<cogs>` The cog or cogs to install. - `<cogs...>` The cog or cogs to install.
""" """
await self._cog_installrev(ctx, repo, None, cog_names) await self._cog_installrev(ctx, repo, None, cog_names)
@cog.command(name="installversion", usage="<repo_name> <revision> <cogs>") @cog.command(
name="installversion", usage="<repo> <revision> <cogs...>", require_var_positional=True
)
async def _cog_installversion( async def _cog_installversion(
self, ctx: commands.Context, repo: Repo, rev: str, *cog_names: str self, ctx: commands.Context, repo: Repo, revision: str, *cog_names: str
) -> None: ) -> None:
"""Install a cog from the specified revision of given repo. """Install a cog from the specified revision of given repo.
@ -768,18 +767,15 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repo_name>` The name of the repo to install cogs from. - `<repo>` The name of the repo to install cogs from.
- `<revision>` The revision to install from. - `<revision>` The revision to install from.
- `<cogs>` The cog or cogs to install. - `<cogs...>` The cog or cogs to install.
""" """
await self._cog_installrev(ctx, repo, rev, cog_names) await self._cog_installrev(ctx, repo, revision, cog_names)
async def _cog_installrev( async def _cog_installrev(
self, ctx: commands.Context, repo: Repo, rev: Optional[str], cog_names: Iterable[str] self, ctx: commands.Context, repo: Repo, rev: Optional[str], cog_names: Iterable[str]
) -> None: ) -> None:
if not cog_names:
await ctx.send_help()
return
commit = None commit = None
async with ctx.typing(): async with ctx.typing():
if rev is not None: if rev is not None:
@ -859,8 +855,8 @@ class Downloader(commands.Cog):
"\nYou can load them using {command_1}." "\nYou can load them using {command_1}."
" To see end user data statements, you can use {command_2}." " To see end user data statements, you can use {command_2}."
).format( ).format(
command_1=inline(f"{ctx.clean_prefix}load <cogs>"), command_1=inline(f"{ctx.clean_prefix}load <cogs...>"),
command_2=inline(f"{ctx.clean_prefix}cog info <repo_name> <cog_name>"), command_2=inline(f"{ctx.clean_prefix}cog info <repo> <cog>"),
) )
+ message + message
) )
@ -870,7 +866,7 @@ class Downloader(commands.Cog):
if cog.install_msg: if cog.install_msg:
await ctx.send(cog.install_msg.replace("[p]", ctx.clean_prefix)) await ctx.send(cog.install_msg.replace("[p]", ctx.clean_prefix))
@cog.command(name="uninstall", usage="<cogs>") @cog.command(name="uninstall", require_var_positional=True)
async def _cog_uninstall(self, ctx: commands.Context, *cogs: InstalledCog) -> None: async def _cog_uninstall(self, ctx: commands.Context, *cogs: InstalledCog) -> None:
"""Uninstall cogs. """Uninstall cogs.
@ -883,11 +879,8 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<cogs>` The cog or cogs to uninstall. - `<cogs...>` The cog or cogs to uninstall.
""" """
if not cogs:
await ctx.send_help()
return
async with ctx.typing(): async with ctx.typing():
uninstalled_cogs = [] uninstalled_cogs = []
failed_cogs = [] failed_cogs = []
@ -923,7 +916,7 @@ class Downloader(commands.Cog):
) )
await self.send_pagified(ctx, message) await self.send_pagified(ctx, message)
@cog.command(name="pin", usage="<cogs>") @cog.command(name="pin", require_var_positional=True)
async def _cog_pin(self, ctx: commands.Context, *cogs: InstalledCog) -> None: async def _cog_pin(self, ctx: commands.Context, *cogs: InstalledCog) -> None:
"""Pin cogs - this will lock cogs on their current version. """Pin cogs - this will lock cogs on their current version.
@ -933,11 +926,8 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<cogs>` The cog or cogs to pin. Must already be installed. - `<cogs...>` The cog or cogs to pin. Must already be installed.
""" """
if not cogs:
await ctx.send_help()
return
already_pinned = [] already_pinned = []
pinned = [] pinned = []
for cog in set(cogs): for cog in set(cogs):
@ -955,7 +945,7 @@ class Downloader(commands.Cog):
message += _("\nThese cogs were already pinned: ") + humanize_list(already_pinned) message += _("\nThese cogs were already pinned: ") + humanize_list(already_pinned)
await self.send_pagified(ctx, message) await self.send_pagified(ctx, message)
@cog.command(name="unpin", usage="<cogs>") @cog.command(name="unpin", require_var_positional=True)
async def _cog_unpin(self, ctx: commands.Context, *cogs: InstalledCog) -> None: async def _cog_unpin(self, ctx: commands.Context, *cogs: InstalledCog) -> None:
"""Unpin cogs - this will remove the update lock from those cogs. """Unpin cogs - this will remove the update lock from those cogs.
@ -965,10 +955,7 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<cogs>` The cog or cogs to unpin. Must already be installed and pinned.""" - `<cogs...>` The cog or cogs to unpin. Must already be installed and pinned."""
if not cogs:
await ctx.send_help()
return
not_pinned = [] not_pinned = []
unpinned = [] unpinned = []
for cog in set(cogs): for cog in set(cogs):
@ -1062,7 +1049,7 @@ class Downloader(commands.Cog):
""" """
await self._cog_update_logic(ctx, cogs=cogs) await self._cog_update_logic(ctx, cogs=cogs)
@cog.command(name="updateallfromrepos", usage="<repos>") @cog.command(name="updateallfromrepos", require_var_positional=True)
async def _cog_updateallfromrepos(self, ctx: commands.Context, *repos: Repo) -> None: async def _cog_updateallfromrepos(self, ctx: commands.Context, *repos: Repo) -> None:
"""Update all cogs from repos of your choosing. """Update all cogs from repos of your choosing.
@ -1072,16 +1059,13 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repos>` The repo or repos to update all cogs from. - `<repos...>` The repo or repos to update all cogs from.
""" """
if not repos:
await ctx.send_help()
return
await self._cog_update_logic(ctx, repos=repos) await self._cog_update_logic(ctx, repos=repos)
@cog.command(name="updatetoversion", usage="<repo_name> <revision> [cogs]") @cog.command(name="updatetoversion")
async def _cog_updatetoversion( async def _cog_updatetoversion(
self, ctx: commands.Context, repo: Repo, rev: str, *cogs: InstalledCog self, ctx: commands.Context, repo: Repo, revision: str, *cogs: InstalledCog
) -> None: ) -> None:
"""Update all cogs, or ones of your choosing to chosen revision of one repo. """Update all cogs, or ones of your choosing to chosen revision of one repo.
@ -1096,11 +1080,11 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repo_name>` The repo or repos to update all cogs from. - `<repo>` The repo or repos to update all cogs from.
- `<revision>` The revision to update to. - `<revision>` The revision to update to.
- `[cogs]` The cog or cogs to update. - `[cogs...]` The cog or cogs to update.
""" """
await self._cog_update_logic(ctx, repo=repo, rev=rev, cogs=cogs) await self._cog_update_logic(ctx, repo=repo, rev=revision, cogs=cogs)
async def _cog_update_logic( async def _cog_update_logic(
self, self,
@ -1219,7 +1203,7 @@ class Downloader(commands.Cog):
if updates_available and updated_cognames: if updates_available and updated_cognames:
await self._ask_for_cog_reload(ctx, updated_cognames) await self._ask_for_cog_reload(ctx, updated_cognames)
@cog.command(name="list", usage="<repo_name>") @cog.command(name="list")
async def _cog_list(self, ctx: commands.Context, repo: Repo) -> None: async def _cog_list(self, ctx: commands.Context, repo: Repo) -> None:
"""List all available cogs from a single repo. """List all available cogs from a single repo.
@ -1228,7 +1212,7 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repo_name>` The repo to list cogs from. - `<repo>` The repo to list cogs from.
""" """
installed = await self.installed_cogs() installed = await self.installed_cogs()
installed_str = "" installed_str = ""
@ -1251,7 +1235,7 @@ class Downloader(commands.Cog):
for page in pagify(cogs, ["\n"], shorten_by=16): for page in pagify(cogs, ["\n"], shorten_by=16):
await ctx.send(box(page.lstrip(" "), lang="diff")) await ctx.send(box(page.lstrip(" "), lang="diff"))
@cog.command(name="info", usage="<repo_name> <cog_name>") @cog.command(name="info", usage="<repo> <cog>")
async def _cog_info(self, ctx: commands.Context, repo: Repo, cog_name: str) -> None: async def _cog_info(self, ctx: commands.Context, repo: Repo, cog_name: str) -> None:
"""List information about a single cog. """List information about a single cog.
@ -1260,8 +1244,8 @@ class Downloader(commands.Cog):
**Arguments** **Arguments**
- `<repo_name>` The repo to get cog info from. - `<repo>` The repo to get cog info from.
- `<cog_name>` The cog to get info on. - `<cog>` The cog to get info on.
""" """
cog = discord.utils.get(repo.available_cogs, name=cog_name) cog = discord.utils.get(repo.available_cogs, name=cog_name)
if cog is None: if cog is None:
@ -1490,7 +1474,7 @@ class Downloader(commands.Cog):
_("\nEnd user data statements of these cogs have changed: ") _("\nEnd user data statements of these cogs have changed: ")
+ humanize_list(tuple(map(inline, cogs_with_changed_eud_statement))) + humanize_list(tuple(map(inline, cogs_with_changed_eud_statement)))
+ _("\nYou can use {command} to see the updated statements.\n").format( + _("\nYou can use {command} to see the updated statements.\n").format(
command=inline(f"{ctx.clean_prefix}cog info <repo_name> <cog_name>") command=inline(f"{ctx.clean_prefix}cog info <repo> <cog>")
) )
) )
if failed_cogs: if failed_cogs:

View File

@ -176,14 +176,8 @@ class Image(commands.Cog):
@commands.guild_only() @commands.guild_only()
@commands.command() @commands.command()
async def gif(self, ctx, *keywords): async def gif(self, ctx, *, keywords):
"""Retrieve the first search result from Giphy.""" """Retrieve the first search result from Giphy."""
if keywords:
keywords = "+".join(keywords)
else:
await ctx.send_help()
return
giphy_api_key = (await ctx.bot.get_shared_api_tokens("GIPHY")).get("api_key") giphy_api_key = (await ctx.bot.get_shared_api_tokens("GIPHY")).get("api_key")
if not giphy_api_key: if not giphy_api_key:
await ctx.send( await ctx.send(
@ -193,11 +187,8 @@ class Image(commands.Cog):
) )
return return
url = "http://api.giphy.com/v1/gifs/search?&api_key={}&q={}".format( url = "http://api.giphy.com/v1/gifs/search"
giphy_api_key, keywords async with self.session.get(url, params={"api_key": giphy_api_key, "q": keywords}) as r:
)
async with self.session.get(url) as r:
result = await r.json() result = await r.json()
if r.status == 200: if r.status == 200:
if result["data"]: if result["data"]:
@ -209,14 +200,8 @@ class Image(commands.Cog):
@commands.guild_only() @commands.guild_only()
@commands.command() @commands.command()
async def gifr(self, ctx, *keywords): async def gifr(self, ctx, *, keywords):
"""Retrieve a random GIF from a Giphy search.""" """Retrieve a random GIF from a Giphy search."""
if keywords:
keywords = "+".join(keywords)
else:
await ctx.send_help()
return
giphy_api_key = (await ctx.bot.get_shared_api_tokens("GIPHY")).get("api_key") giphy_api_key = (await ctx.bot.get_shared_api_tokens("GIPHY")).get("api_key")
if not giphy_api_key: if not giphy_api_key:
await ctx.send( await ctx.send(
@ -226,11 +211,8 @@ class Image(commands.Cog):
) )
return return
url = "http://api.giphy.com/v1/gifs/random?&api_key={}&tag={}".format( url = "http://api.giphy.com/v1/gifs/random"
giphy_api_key, keywords async with self.session.get(url, params={"api_key": giphy_api_key, "tag": keywords}) as r:
)
async with self.session.get(url) as r:
result = await r.json() result = await r.json()
if r.status == 200: if r.status == 200:
if result["data"]: if result["data"]:

View File

@ -362,7 +362,7 @@ class KickBanMixin(MixinMeta):
await ctx.send(message) await ctx.send(message)
@commands.command(aliases=["hackban"]) @commands.command(aliases=["hackban"], usage="<user_ids...> [days] [reason]")
@commands.guild_only() @commands.guild_only()
@commands.bot_has_permissions(ban_members=True) @commands.bot_has_permissions(ban_members=True)
@checks.admin_or_permissions(ban_members=True) @checks.admin_or_permissions(ban_members=True)

View File

@ -374,9 +374,7 @@ class Permissions(commands.Cog):
await self._permissions_acl_set(ctx, guild_id=ctx.guild.id, update=True) await self._permissions_acl_set(ctx, guild_id=ctx.guild.id, update=True)
@checks.is_owner() @checks.is_owner()
@permissions.command( @permissions.command(name="addglobalrule", require_var_positional=True)
name="addglobalrule", usage="<allow_or_deny> <cog_or_command> <who_or_what>..."
)
async def permissions_addglobalrule( async def permissions_addglobalrule(
self, self,
ctx: commands.Context, ctx: commands.Context,
@ -391,11 +389,8 @@ class Permissions(commands.Cog):
`<cog_or_command>` is the cog or command to add the rule to. `<cog_or_command>` is the cog or command to add the rule to.
This is case sensitive. This is case sensitive.
`<who_or_what>` is one or more users, channels or roles the rule is for. `<who_or_what...>` is one or more users, channels or roles the rule is for.
""" """
if not who_or_what:
await ctx.send_help()
return
for w in who_or_what: for w in who_or_what:
await self._add_rule( await self._add_rule(
rule=cast(bool, allow_or_deny), rule=cast(bool, allow_or_deny),
@ -408,9 +403,7 @@ class Permissions(commands.Cog):
@commands.guild_only() @commands.guild_only()
@checks.guildowner_or_permissions(administrator=True) @checks.guildowner_or_permissions(administrator=True)
@permissions.command( @permissions.command(
name="addserverrule", name="addserverrule", aliases=["addguildrule"], require_var_positional=True
usage="<allow_or_deny> <cog_or_command> <who_or_what>...",
aliases=["addguildrule"],
) )
async def permissions_addguildrule( async def permissions_addguildrule(
self, self,
@ -426,11 +419,8 @@ class Permissions(commands.Cog):
`<cog_or_command>` is the cog or command to add the rule to. `<cog_or_command>` is the cog or command to add the rule to.
This is case sensitive. This is case sensitive.
`<who_or_what>` is one or more users, channels or roles the rule is for. `<who_or_what...>` is one or more users, channels or roles the rule is for.
""" """
if not who_or_what:
await ctx.send_help()
return
for w in who_or_what: for w in who_or_what:
await self._add_rule( await self._add_rule(
rule=cast(bool, allow_or_deny), rule=cast(bool, allow_or_deny),
@ -441,7 +431,7 @@ class Permissions(commands.Cog):
await ctx.send(_("Rule added.")) await ctx.send(_("Rule added."))
@checks.is_owner() @checks.is_owner()
@permissions.command(name="removeglobalrule", usage="<cog_or_command> <who_or_what>...") @permissions.command(name="removeglobalrule", require_var_positional=True)
async def permissions_removeglobalrule( async def permissions_removeglobalrule(
self, self,
ctx: commands.Context, ctx: commands.Context,
@ -453,11 +443,8 @@ class Permissions(commands.Cog):
`<cog_or_command>` is the cog or command to remove the rule `<cog_or_command>` is the cog or command to remove the rule
from. This is case sensitive. from. This is case sensitive.
`<who_or_what>` is one or more users, channels or roles the rule is for. `<who_or_what...>` is one or more users, channels or roles the rule is for.
""" """
if not who_or_what:
await ctx.send_help()
return
for w in who_or_what: for w in who_or_what:
await self._remove_rule(cog_or_cmd=cog_or_command, model_id=w.id, guild_id=GLOBAL) await self._remove_rule(cog_or_cmd=cog_or_command, model_id=w.id, guild_id=GLOBAL)
await ctx.send(_("Rule removed.")) await ctx.send(_("Rule removed."))
@ -465,9 +452,7 @@ class Permissions(commands.Cog):
@commands.guild_only() @commands.guild_only()
@checks.guildowner_or_permissions(administrator=True) @checks.guildowner_or_permissions(administrator=True)
@permissions.command( @permissions.command(
name="removeserverrule", name="removeserverrule", aliases=["removeguildrule"], require_var_positional=True
usage="<cog_or_command> <who_or_what>...",
aliases=["removeguildrule"],
) )
async def permissions_removeguildrule( async def permissions_removeguildrule(
self, self,
@ -480,11 +465,8 @@ class Permissions(commands.Cog):
`<cog_or_command>` is the cog or command to remove the rule `<cog_or_command>` is the cog or command to remove the rule
from. This is case sensitive. from. This is case sensitive.
`<who_or_what>` is one or more users, channels or roles the rule is for. `<who_or_what...>` is one or more users, channels or roles the rule is for.
""" """
if not who_or_what:
await ctx.send_help()
return
for w in who_or_what: for w in who_or_what:
await self._remove_rule( await self._remove_rule(
cog_or_cmd=cog_or_command, model_id=w.id, guild_id=ctx.guild.id cog_or_cmd=cog_or_command, model_id=w.id, guild_id=ctx.guild.id

View File

@ -299,12 +299,9 @@ class Streams(commands.Cog):
pass pass
@streamalert.group(name="twitch", invoke_without_command=True) @streamalert.group(name="twitch", invoke_without_command=True)
async def _twitch(self, ctx: commands.Context, channel_name: str = None): async def _twitch(self, ctx: commands.Context, channel_name: str):
"""Manage Twitch stream notifications.""" """Manage Twitch stream notifications."""
if channel_name is not None:
await ctx.invoke(self.twitch_alert_channel, channel_name) await ctx.invoke(self.twitch_alert_channel, channel_name)
else:
await ctx.send_help()
@_twitch.command(name="channel") @_twitch.command(name="channel")
async def twitch_alert_channel(self, ctx: commands.Context, channel_name: str): async def twitch_alert_channel(self, ctx: commands.Context, channel_name: str):
@ -528,7 +525,7 @@ class Streams(commands.Cog):
@message.command(name="mention") @message.command(name="mention")
@commands.guild_only() @commands.guild_only()
async def with_mention(self, ctx: commands.Context, *, message: str = None): async def with_mention(self, ctx: commands.Context, *, message: str):
"""Set stream alert message when mentions are enabled. """Set stream alert message when mentions are enabled.
Use `{mention}` in the message to insert the selected mentions. Use `{mention}` in the message to insert the selected mentions.
@ -536,28 +533,22 @@ class Streams(commands.Cog):
For example: `[p]streamset message mention {mention}, {stream} is live!` For example: `[p]streamset message mention {mention}, {stream} is live!`
""" """
if message is not None:
guild = ctx.guild guild = ctx.guild
await self.config.guild(guild).live_message_mention.set(message) await self.config.guild(guild).live_message_mention.set(message)
await ctx.send(_("Stream alert message set!")) await ctx.send(_("Stream alert message set!"))
else:
await ctx.send_help()
@message.command(name="nomention") @message.command(name="nomention")
@commands.guild_only() @commands.guild_only()
async def without_mention(self, ctx: commands.Context, *, message: str = None): async def without_mention(self, ctx: commands.Context, *, message: str):
"""Set stream alert message when mentions are disabled. """Set stream alert message when mentions are disabled.
Use `{stream}` in the message to insert the channel or user name. Use `{stream}` in the message to insert the channel or user name.
For example: `[p]streamset message nomention {stream} is live!` For example: `[p]streamset message nomention {stream} is live!`
""" """
if message is not None:
guild = ctx.guild guild = ctx.guild
await self.config.guild(guild).live_message_nomention.set(message) await self.config.guild(guild).live_message_nomention.set(message)
await ctx.send(_("Stream alert message set!")) await ctx.send(_("Stream alert message set!"))
else:
await ctx.send_help()
@message.command(name="clear") @message.command(name="clear")
@commands.guild_only() @commands.guild_only()

View File

@ -279,7 +279,7 @@ class Trivia(commands.Cog):
else: else:
await ctx.send(_("Trivia file was not found.")) await ctx.send(_("Trivia file was not found."))
@commands.group(invoke_without_command=True) @commands.group(invoke_without_command=True, require_var_positional=True)
@commands.guild_only() @commands.guild_only()
async def trivia(self, ctx: commands.Context, *categories: str): async def trivia(self, ctx: commands.Context, *categories: str):
"""Start trivia session on the specified category. """Start trivia session on the specified category.
@ -287,9 +287,6 @@ class Trivia(commands.Cog):
You may list multiple categories, in which case the trivia will involve You may list multiple categories, in which case the trivia will involve
questions from all of them. questions from all of them.
""" """
if not categories:
await ctx.send_help()
return
categories = [c.lower() for c in categories] categories = [c.lower() for c in categories]
session = self._get_trivia_session(ctx.channel) session = self._get_trivia_session(ctx.channel)
if session is not None: if session is not None:

View File

@ -1282,12 +1282,10 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
except asyncio.TimeoutError: except asyncio.TimeoutError:
await ctx.send(_("Response timed out.")) await ctx.send(_("Response timed out."))
@commands.command() @commands.command(require_var_positional=True)
@checks.is_owner() @checks.is_owner()
async def load(self, ctx: commands.Context, *cogs: str): async def load(self, ctx: commands.Context, *cogs: str):
"""Loads packages.""" """Loads packages."""
if not cogs:
return await ctx.send_help()
cogs = tuple(map(lambda cog: cog.rstrip(","), cogs)) cogs = tuple(map(lambda cog: cog.rstrip(","), cogs))
async with ctx.typing(): async with ctx.typing():
( (
@ -1393,12 +1391,10 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
page = page[2:] page = page[2:]
await ctx.send(page) await ctx.send(page)
@commands.command() @commands.command(require_var_positional=True)
@checks.is_owner() @checks.is_owner()
async def unload(self, ctx: commands.Context, *cogs: str): async def unload(self, ctx: commands.Context, *cogs: str):
"""Unloads packages.""" """Unloads packages."""
if not cogs:
return await ctx.send_help()
cogs = tuple(map(lambda cog: cog.rstrip(","), cogs)) cogs = tuple(map(lambda cog: cog.rstrip(","), cogs))
unloaded, failed = await self._unload(cogs) unloaded, failed = await self._unload(cogs)
@ -1431,12 +1427,10 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
for page in pagify(total_message): for page in pagify(total_message):
await ctx.send(page) await ctx.send(page)
@commands.command(name="reload") @commands.command(require_var_positional=True)
@checks.is_owner() @checks.is_owner()
async def reload(self, ctx: commands.Context, *cogs: str): async def reload(self, ctx: commands.Context, *cogs: str):
"""Reloads packages.""" """Reloads packages."""
if not cogs:
return await ctx.send_help()
cogs = tuple(map(lambda cog: cog.rstrip(","), cogs)) cogs = tuple(map(lambda cog: cog.rstrip(","), cogs))
async with ctx.typing(): async with ctx.typing():
( (
@ -1944,7 +1938,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
await ctx.bot.change_presence(status=status, activity=game) await ctx.bot.change_presence(status=status, activity=game)
await ctx.send(_("Status changed to {}.").format(status)) await ctx.send(_("Status changed to {}.").format(status))
@_set.command(name="streaming", aliases=["stream"]) @_set.command(name="streaming", aliases=["stream"], usage="[(<streamer> <stream_title>)]")
@checks.bot_in_a_guild() @checks.bot_in_a_guild()
@checks.is_owner() @checks.is_owner()
async def stream(self, ctx: commands.Context, streamer=None, *, stream_title=None): async def stream(self, ctx: commands.Context, streamer=None, *, stream_title=None):
@ -2026,13 +2020,10 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
else: else:
await ctx.send(_("Done.")) await ctx.send(_("Done."))
@_set.command(aliases=["prefixes"]) @_set.command(aliases=["prefixes"], require_var_positional=True)
@checks.is_owner() @checks.is_owner()
async def prefix(self, ctx: commands.Context, *prefixes: str): async def prefix(self, ctx: commands.Context, *prefixes: str):
"""Sets [botname]'s global prefix(es).""" """Sets [botname]'s global prefix(es)."""
if not prefixes:
await ctx.send_help()
return
await ctx.bot.set_prefixes(guild=None, prefixes=prefixes) await ctx.bot.set_prefixes(guild=None, prefixes=prefixes)
await ctx.send(_("Prefix set.")) await ctx.send(_("Prefix set."))
@ -2252,7 +2243,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
for page in pagify(joined, ["\n"], shorten_by=16): for page in pagify(joined, ["\n"], shorten_by=16):
await ctx.send(box(page.lstrip(" "), lang="diff")) await ctx.send(box(page.lstrip(" "), lang="diff"))
@api.command(name="remove") @api.command(name="remove", require_var_positional=True)
async def api_remove(self, ctx: commands.Context, *services: str): async def api_remove(self, ctx: commands.Context, *services: str):
"""Remove the given services with all their keys and tokens.""" """Remove the given services with all their keys and tokens."""
bot_services = (await ctx.bot.get_shared_api_tokens()).keys() bot_services = (await ctx.bot.get_shared_api_tokens()).keys()
@ -2756,15 +2747,11 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
""" """
pass pass
@allowlist.command(name="add", usage="<user>...") @allowlist.command(name="add", require_var_positional=True)
async def allowlist_add(self, ctx: commands.Context, *users: Union[discord.Member, int]): async def allowlist_add(self, ctx: commands.Context, *users: Union[discord.Member, int]):
""" """
Adds a user to the allowlist. Adds a user to the allowlist.
""" """
if not users:
await ctx.send_help()
return
uids = {getattr(user, "id", user) for user in users} uids = {getattr(user, "id", user) for user in users}
await self.bot._whiteblacklist_cache.add_to_whitelist(None, uids) await self.bot._whiteblacklist_cache.add_to_whitelist(None, uids)
@ -2788,15 +2775,11 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
for page in pagify(msg): for page in pagify(msg):
await ctx.send(box(page)) await ctx.send(box(page))
@allowlist.command(name="remove", usage="<user>...") @allowlist.command(name="remove", require_var_positional=True)
async def allowlist_remove(self, ctx: commands.Context, *users: Union[discord.Member, int]): async def allowlist_remove(self, ctx: commands.Context, *users: Union[discord.Member, int]):
""" """
Removes user from the allowlist. Removes user from the allowlist.
""" """
if not users:
await ctx.send_help()
return
uids = {getattr(user, "id", user) for user in users} uids = {getattr(user, "id", user) for user in users}
await self.bot._whiteblacklist_cache.remove_from_whitelist(None, uids) await self.bot._whiteblacklist_cache.remove_from_whitelist(None, uids)
@ -2818,15 +2801,11 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
""" """
pass pass
@blocklist.command(name="add", usage="<user>...") @blocklist.command(name="add", require_var_positional=True)
async def blocklist_add(self, ctx: commands.Context, *users: Union[discord.Member, int]): async def blocklist_add(self, ctx: commands.Context, *users: Union[discord.Member, int]):
""" """
Adds a user to the blocklist. Adds a user to the blocklist.
""" """
if not users:
await ctx.send_help()
return
for user in users: for user in users:
if isinstance(user, int): if isinstance(user, int):
user_obj = discord.Object(id=user) user_obj = discord.Object(id=user)
@ -2859,15 +2838,11 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
for page in pagify(msg): for page in pagify(msg):
await ctx.send(box(page)) await ctx.send(box(page))
@blocklist.command(name="remove", usage="<user>...") @blocklist.command(name="remove", require_var_positional=True)
async def blocklist_remove(self, ctx: commands.Context, *users: Union[discord.Member, int]): async def blocklist_remove(self, ctx: commands.Context, *users: Union[discord.Member, int]):
""" """
Removes user from the blocklist. Removes user from the blocklist.
""" """
if not users:
await ctx.send_help()
return
uids = {getattr(user, "id", user) for user in users} uids = {getattr(user, "id", user) for user in users}
await self.bot._whiteblacklist_cache.remove_from_blacklist(None, uids) await self.bot._whiteblacklist_cache.remove_from_blacklist(None, uids)
@ -2890,17 +2865,13 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
""" """
pass pass
@localallowlist.command(name="add", usage="<user_or_role>...") @localallowlist.command(name="add", require_var_positional=True)
async def localallowlist_add( async def localallowlist_add(
self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int] self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int]
): ):
""" """
Adds a user or role to the server allowlist. Adds a user or role to the server allowlist.
""" """
if not users_or_roles:
await ctx.send_help()
return
names = [getattr(u_or_r, "name", u_or_r) for u_or_r in users_or_roles] names = [getattr(u_or_r, "name", u_or_r) for u_or_r in users_or_roles]
uids = {getattr(u_or_r, "id", u_or_r) for u_or_r in users_or_roles} uids = {getattr(u_or_r, "id", u_or_r) for u_or_r in users_or_roles}
if not (ctx.guild.owner == ctx.author or await self.bot.is_owner(ctx.author)): if not (ctx.guild.owner == ctx.author or await self.bot.is_owner(ctx.author)):
@ -2937,17 +2908,13 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
for page in pagify(msg): for page in pagify(msg):
await ctx.send(box(page)) await ctx.send(box(page))
@localallowlist.command(name="remove", usage="<user_or_role>...") @localallowlist.command(name="remove", require_var_positional=True)
async def localallowlist_remove( async def localallowlist_remove(
self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int] self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int]
): ):
""" """
Removes user or role from the allowlist. Removes user or role from the allowlist.
""" """
if not users_or_roles:
await ctx.send_help()
return
names = [getattr(u_or_r, "name", u_or_r) for u_or_r in users_or_roles] names = [getattr(u_or_r, "name", u_or_r) for u_or_r in users_or_roles]
uids = {getattr(u_or_r, "id", u_or_r) for u_or_r in users_or_roles} uids = {getattr(u_or_r, "id", u_or_r) for u_or_r in users_or_roles}
if not (ctx.guild.owner == ctx.author or await self.bot.is_owner(ctx.author)): if not (ctx.guild.owner == ctx.author or await self.bot.is_owner(ctx.author)):
@ -2984,17 +2951,13 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
""" """
pass pass
@localblocklist.command(name="add", usage="<user_or_role>...") @localblocklist.command(name="add", require_var_positional=True)
async def localblocklist_add( async def localblocklist_add(
self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int] self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int]
): ):
""" """
Adds a user or role to the blocklist. Adds a user or role to the blocklist.
""" """
if not users_or_roles:
await ctx.send_help()
return
for user_or_role in users_or_roles: for user_or_role in users_or_roles:
uid = discord.Object(id=getattr(user_or_role, "id", user_or_role)) uid = discord.Object(id=getattr(user_or_role, "id", user_or_role))
if uid.id == ctx.author.id: if uid.id == ctx.author.id:
@ -3032,17 +2995,13 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
for page in pagify(msg): for page in pagify(msg):
await ctx.send(box(page)) await ctx.send(box(page))
@localblocklist.command(name="remove", usage="<user_or_role>...") @localblocklist.command(name="remove", require_var_positional=True)
async def localblocklist_remove( async def localblocklist_remove(
self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int] self, ctx: commands.Context, *users_or_roles: Union[discord.Member, discord.Role, int]
): ):
""" """
Removes user or role from blocklist. Removes user or role from blocklist.
""" """
if not users_or_roles:
await ctx.send_help()
return
names = [getattr(u_or_r, "name", u_or_r) for u_or_r in users_or_roles] names = [getattr(u_or_r, "name", u_or_r) for u_or_r in users_or_roles]
uids = {getattr(u_or_r, "id", u_or_r) for u_or_r in users_or_roles} uids = {getattr(u_or_r, "id", u_or_r) for u_or_r in users_or_roles}
await self.bot._whiteblacklist_cache.remove_from_blacklist(ctx.guild, uids) await self.bot._whiteblacklist_cache.remove_from_blacklist(ctx.guild, uids)