diff options
| -rw-r--r-- | bot/__main__.py | 1 | ||||
| -rw-r--r-- | bot/cogs/alias.py | 153 | ||||
| -rw-r--r-- | bot/cogs/tags.py | 57 | ||||
| -rw-r--r-- | bot/converters.py | 59 |
4 files changed, 214 insertions, 56 deletions
diff --git a/bot/__main__.py b/bot/__main__.py index 3059b3ed0..f74b3545c 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -56,6 +56,7 @@ if not DEBUG_MODE: bot.load_extension("bot.cogs.verification") # Feature cogs +bot.load_extension("bot.cogs.alias") bot.load_extension("bot.cogs.deployment") bot.load_extension("bot.cogs.defcon") bot.load_extension("bot.cogs.eval") diff --git a/bot/cogs/alias.py b/bot/cogs/alias.py new file mode 100644 index 000000000..940bdaa43 --- /dev/null +++ b/bot/cogs/alias.py @@ -0,0 +1,153 @@ +import logging + +from discord import TextChannel, User +from discord.ext.commands import ( + Context, clean_content, command, group +) + +from bot.converters import TagNameConverter + +log = logging.getLogger(__name__) + + +class Alias: + """ + Aliases for more used commands + """ + + def __init__(self, bot): + self.bot = bot + + async def invoke(self, ctx, cmd_name, *args, **kwargs): + """ + Invokes a command with args and kwargs. + Fail early through `command.can_run`, and logs warnings. + + :param ctx: Context instance for command call + :param cmd_name: Name of command/subcommand to be invoked + :param args: args to be passed to the command + :param kwargs: kwargs to be passed to the command + :return: None + """ + + log.debug(f"{cmd_name} was invoked through an alias") + cmd = self.bot.get_command(cmd_name) + if not cmd: + return log.warning(f'Did not find command "{cmd_name}" to invoke.') + elif not await cmd.can_run(ctx): + return log.warning( + f'{str(ctx.author)} tried to run the command "{cmd_name}"' + ) + + await ctx.invoke(cmd, *args, **kwargs) + + @command(name="resources", aliases=("resource",), hidden=True) + async def site_resources_alias(self, ctx): + """ + Alias for invoking <prefix>site resources. + """ + + await self.invoke(ctx, "site resources") + + @command(name="watch", hidden=True) + async def bigbrother_watch_alias( + self, ctx, user: User, channel: TextChannel = None + ): + """ + Alias for invoking <prefix>bigbrother watch user [text_channel]. + """ + + await self.invoke(ctx, "bigbrother watch", user, channel) + + @command(name="unwatch", hidden=True) + async def bigbrother_unwatch_alias(self, ctx, user: User): + """ + Alias for invoking <prefix>bigbrother unwatch user. + + user: discord.User - A user instance to unwatch + """ + + await self.invoke(ctx, "bigbrother unwatch", user) + + @command(name="home", hidden=True) + async def site_home_alias(self, ctx): + """ + Alias for invoking <prefix>site home. + """ + + await self.invoke(ctx, "site home") + + @command(name="faq", hidden=True) + async def site_faq_alias(self, ctx): + """ + Alias for invoking <prefix>site faq. + """ + + await self.invoke(ctx, "site faq") + + @command(name="reload", hidden=True) + async def reload_cog_alias(self, ctx, *, cog_name: str): + """ + Alias for invoking <prefix>cogs reload cog_name. + + cog_name: str - name of the cog to be reloaded. + """ + + await self.invoke(ctx, "cogs reload", cog_name) + + @command(name="defon", hidden=True) + async def defcon_enable_alias(self, ctx): + """ + Alias for invoking <prefix>defcon enable. + """ + + await self.invoke(ctx, "defcon enable") + + @command(name="defoff", hidden=True) + async def defcon_disable_alias(self, ctx): + """ + Alias for invoking <prefix>defcon disable. + """ + + await self.invoke(ctx, "defcon disable") + + @group(name="get", + aliases=("show", "g"), + hidden=True, + invoke_without_command=True) + async def get_group_alias(self, ctx): + """ + Group for reverse aliases for commands like `tags get`, + allowing for `get tags` or `get docs`. + """ + + pass + + @get_group_alias.command(name="tags", aliases=("tag", "t"), hidden=True) + async def get_tags_command_alias( + self, ctx: Context, *, tag_name: TagNameConverter=None + ): + """ + Alias for invoking <prefix>tags get [tag_name]. + + tag_name: str - tag to be viewed. + """ + + await self.invoke(ctx, "tags get", tag_name) + + @get_group_alias.command(name="docs", aliases=("doc", "d"), hidden=True) + async def get_docs_command_alias( + self, ctx: Context, symbol: clean_content = None + ): + """ + Alias for invoking <prefix>docs get [symbol]. + + symbol: str - name of doc to be viewed. + """ + + await self.invoke(ctx, "docs get", symbol) + + +def setup(bot): + bot.add_cog(Alias(bot)) + log.info("Cog loaded: Alias") diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py index e6f9ecd89..cdc2861b1 100644 --- a/bot/cogs/tags.py +++ b/bot/cogs/tags.py @@ -6,13 +6,13 @@ from typing import Optional from discord import Colour, Embed from discord.ext.commands import ( BadArgument, Bot, - Context, Converter, group + Context, group ) from bot.constants import ( Channels, Cooldowns, ERROR_REPLIES, Keys, Roles, URLs ) -from bot.converters import ValidURL +from bot.converters import TagContentConverter, TagNameConverter, ValidURL from bot.decorators import with_role from bot.pagination import LinePaginator @@ -26,59 +26,6 @@ TEST_CHANNELS = ( ) -class TagNameConverter(Converter): - @staticmethod - async def convert(ctx: Context, tag_name: str): - def is_number(value): - try: - float(value) - except ValueError: - return False - return True - - tag_name = tag_name.lower().strip() - - # The tag name has at least one invalid character. - if ascii(tag_name)[1:-1] != tag_name: - log.warning(f"{ctx.author} tried to put an invalid character in a tag name. " - "Rejecting the request.") - raise BadArgument("Don't be ridiculous, you can't use that character!") - - # The tag name is either empty, or consists of nothing but whitespace. - elif not tag_name: - log.warning(f"{ctx.author} tried to create a tag with a name consisting only of whitespace. " - "Rejecting the request.") - raise BadArgument("Tag names should not be empty, or filled with whitespace.") - - # The tag name is a number of some kind, we don't allow that. - elif is_number(tag_name): - log.warning(f"{ctx.author} tried to create a tag with a digit as its name. " - "Rejecting the request.") - raise BadArgument("Tag names can't be numbers.") - - # The tag name is longer than 127 characters. - elif len(tag_name) > 127: - log.warning(f"{ctx.author} tried to request a tag name with over 127 characters. " - "Rejecting the request.") - raise BadArgument("Are you insane? That's way too long!") - - return tag_name - - -class TagContentConverter(Converter): - @staticmethod - async def convert(ctx: Context, tag_content: str): - tag_content = tag_content.strip() - - # The tag contents should not be empty, or filled with whitespace. - if not tag_content: - log.warning(f"{ctx.author} tried to create a tag containing only whitespace. " - "Rejecting the request.") - raise BadArgument("Tag contents should not be empty, or filled with whitespace.") - - return tag_content - - class Tags: """ Save new tags and fetch existing tags. diff --git a/bot/converters.py b/bot/converters.py index c8bc75715..069e841f9 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -1,16 +1,20 @@ +import logging import random import socket from ssl import CertificateError import discord from aiohttp import AsyncResolver, ClientConnectorError, ClientSession, TCPConnector -from discord.ext.commands import BadArgument, Converter +from discord.ext.commands import BadArgument, Context, Converter from fuzzywuzzy import fuzz from bot.constants import DEBUG_MODE, Keys, URLs from bot.utils import disambiguate +log = logging.getLogger(__name__) + + class Snake(Converter): snakes = None special_cases = None @@ -197,3 +201,56 @@ class Subreddit(Converter): ) return sub + + +class TagNameConverter(Converter): + @staticmethod + async def convert(ctx: Context, tag_name: str): + def is_number(value): + try: + float(value) + except ValueError: + return False + return True + + tag_name = tag_name.lower().strip() + + # The tag name has at least one invalid character. + if ascii(tag_name)[1:-1] != tag_name: + log.warning(f"{ctx.author} tried to put an invalid character in a tag name. " + "Rejecting the request.") + raise BadArgument("Don't be ridiculous, you can't use that character!") + + # The tag name is either empty, or consists of nothing but whitespace. + elif not tag_name: + log.warning(f"{ctx.author} tried to create a tag with a name consisting only of whitespace. " + "Rejecting the request.") + raise BadArgument("Tag names should not be empty, or filled with whitespace.") + + # The tag name is a number of some kind, we don't allow that. + elif is_number(tag_name): + log.warning(f"{ctx.author} tried to create a tag with a digit as its name. " + "Rejecting the request.") + raise BadArgument("Tag names can't be numbers.") + + # The tag name is longer than 127 characters. + elif len(tag_name) > 127: + log.warning(f"{ctx.author} tried to request a tag name with over 127 characters. " + "Rejecting the request.") + raise BadArgument("Are you insane? That's way too long!") + + return tag_name + + +class TagContentConverter(Converter): + @staticmethod + async def convert(ctx: Context, tag_content: str): + tag_content = tag_content.strip() + + # The tag contents should not be empty, or filled with whitespace. + if not tag_content: + log.warning(f"{ctx.author} tried to create a tag containing only whitespace. " + "Rejecting the request.") + raise BadArgument("Tag contents should not be empty, or filled with whitespace.") + + return tag_content |