diff options
Diffstat (limited to 'bot/exts')
| -rw-r--r-- | bot/exts/christmas/advent_of_code/_cog.py | 12 | ||||
| -rw-r--r-- | bot/exts/christmas/advent_of_code/_helpers.py | 2 | ||||
| -rw-r--r-- | bot/exts/easter/earth_photos.py | 6 | ||||
| -rw-r--r-- | bot/exts/evergreen/emoji.py (renamed from bot/exts/evergreen/emoji_count.py) | 68 | ||||
| -rw-r--r-- | bot/exts/evergreen/game.py | 3 | ||||
| -rw-r--r-- | bot/exts/evergreen/minesweeper.py | 3 | ||||
| -rw-r--r-- | bot/exts/evergreen/movie.py | 3 | ||||
| -rw-r--r-- | bot/exts/evergreen/snakes/_snakes_cog.py | 3 | ||||
| -rw-r--r-- | bot/exts/evergreen/source.py | 2 | ||||
| -rw-r--r-- | bot/exts/evergreen/space.py | 3 | ||||
| -rw-r--r-- | bot/exts/evergreen/status_codes.py | 4 | ||||
| -rw-r--r-- | bot/exts/evergreen/tic_tac_toe.py | 10 | ||||
| -rw-r--r-- | bot/exts/utils/extensions.py | 10 | ||||
| -rw-r--r-- | bot/exts/valentines/be_my_valentine.py | 3 | 
14 files changed, 87 insertions, 45 deletions
diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index 466edd48..8376987d 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -12,6 +12,7 @@ from bot.constants import (  )  from bot.exts.christmas.advent_of_code import _helpers  from bot.utils.decorators import InChannelCheckFailure, in_month, whitelist_override, with_role +from bot.utils.extensions import invoke_help_command  log = logging.getLogger(__name__) @@ -36,9 +37,6 @@ class AdventOfCode(commands.Cog):          self.about_aoc_filepath = Path("./bot/resources/advent_of_code/about.json")          self.cached_about_aoc = self._build_about_embed() -        self.countdown_task = None -        self.status_task = None -          notification_coro = _helpers.new_puzzle_notification(self.bot)          self.notification_task = self.bot.loop.create_task(notification_coro)          self.notification_task.set_name("Daily AoC Notification") @@ -54,7 +52,7 @@ class AdventOfCode(commands.Cog):      async def adventofcode_group(self, ctx: commands.Context) -> None:          """All of the Advent of Code commands."""          if not ctx.invoked_subcommand: -            await ctx.send_help(ctx.command) +            await invoke_help_command(ctx)      @adventofcode_group.command(          name="subscribe", @@ -173,6 +171,7 @@ class AdventOfCode(commands.Cog):          else:              await ctx.message.add_reaction(Emojis.envelope) +    @in_month(Month.DECEMBER)      @adventofcode_group.command(          name="leaderboard",          aliases=("board", "lb"), @@ -198,6 +197,7 @@ class AdventOfCode(commands.Cog):              await ctx.send(content=f"{header}\n\n{table}", embed=info_embed) +    @in_month(Month.DECEMBER)      @adventofcode_group.command(          name="global",          aliases=("globalboard", "gb"), @@ -244,7 +244,7 @@ class AdventOfCode(commands.Cog):              info_embed = _helpers.get_summary_embed(leaderboard)              await ctx.send(f"```\n{table}\n```", embed=info_embed) -    @with_role(Roles.admin, Roles.events_lead) +    @with_role(Roles.admin)      @adventofcode_group.command(          name="refresh",          aliases=("fetch",), @@ -268,7 +268,7 @@ class AdventOfCode(commands.Cog):      def cog_unload(self) -> None:          """Cancel season-related tasks on cog unload."""          log.debug("Unloading the cog and canceling the background task.") -        self.countdown_task.cancel() +        self.notification_task.cancel()          self.status_task.cancel()      def _build_about_embed(self) -> discord.Embed: diff --git a/bot/exts/christmas/advent_of_code/_helpers.py b/bot/exts/christmas/advent_of_code/_helpers.py index b7adc895..a16a4871 100644 --- a/bot/exts/christmas/advent_of_code/_helpers.py +++ b/bot/exts/christmas/advent_of_code/_helpers.py @@ -44,7 +44,7 @@ REQUIRED_CACHE_KEYS = (  AOC_EMBED_THUMBNAIL = (      "https://raw.githubusercontent.com/python-discord" -    "/branding/master/seasonal/christmas/server_icons/festive_256.gif" +    "/branding/main/seasonal/christmas/server_icons/festive_256.gif"  )  # Create an easy constant for the EST timezone diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 60e34b15..bf658391 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -47,8 +47,10 @@ class EarthPhotos(commands.Cog):              embed.set_image(url=embedlink)              embed.add_field(                  name="Author", -                value=f"Photo by [{username}]({profile}{rf}) \ -                on [Unsplash](https://unsplash.com{rf})." +                value=( +                    f"Photo by [{username}]({profile}{rf}) " +                    f"on [Unsplash](https://unsplash.com{rf})." +                )              )              await ctx.send(embed=embed) diff --git a/bot/exts/evergreen/emoji_count.py b/bot/exts/evergreen/emoji.py index cc43e9ab..fa3044e3 100644 --- a/bot/exts/evergreen/emoji_count.py +++ b/bot/exts/evergreen/emoji.py @@ -1,49 +1,52 @@ -import datetime  import logging  import random +import textwrap  from collections import defaultdict -from typing import List, Tuple +from datetime import datetime +from typing import List, Optional, Tuple -import discord +from discord import Color, Embed, Emoji  from discord.ext import commands  from bot.constants import Colours, ERROR_REPLIES +from bot.utils.extensions import invoke_help_command  from bot.utils.pagination import LinePaginator +from bot.utils.time import time_since  log = logging.getLogger(__name__) -class EmojiCount(commands.Cog): -    """Command that give random emoji based on category.""" +class Emojis(commands.Cog): +    """A collection of commands related to emojis in the server."""      def __init__(self, bot: commands.Bot):          self.bot = bot      @staticmethod -    def embed_builder(emoji: dict) -> Tuple[discord.Embed, List[str]]: +    def embed_builder(emoji: dict) -> Tuple[Embed, List[str]]:          """Generates an embed with the emoji names and count.""" -        embed = discord.Embed( +        embed = Embed(              color=Colours.orange,              title="Emoji Count", -            timestamp=datetime.datetime.utcnow() +            timestamp=datetime.utcnow()          )          msg = []          if len(emoji) == 1:              for category_name, category_emojis in emoji.items():                  if len(category_emojis) == 1: -                    msg.append(f"There is **{len(category_emojis)}** emoji in **{category_name}** category") +                    msg.append(f"There is **{len(category_emojis)}** emoji in the **{category_name}** category.")                  else: -                    msg.append(f"There are **{len(category_emojis)}** emojis in **{category_name}** category") +                    msg.append(f"There are **{len(category_emojis)}** emojis in the **{category_name}** category.")                  embed.set_thumbnail(url=random.choice(category_emojis).url)          else:              for category_name, category_emojis in emoji.items():                  emoji_choice = random.choice(category_emojis)                  if len(category_emojis) > 1: -                    emoji_info = f"There are **{len(category_emojis)}** emojis in **{category_name}** category" +                    emoji_info = f"There are **{len(category_emojis)}** emojis in the **{category_name}** category."                  else: -                    emoji_info = f"There is **{len(category_emojis)}** emoji in **{category_name}** category" +                    emoji_info = f"There is **{len(category_emojis)}** emoji in the **{category_name}** category."                  if emoji_choice.animated:                      msg.append(f'<a:{emoji_choice.name}:{emoji_choice.id}> {emoji_info}')                  else: @@ -51,9 +54,9 @@ class EmojiCount(commands.Cog):          return embed, msg      @staticmethod -    def generate_invalid_embed(emojis: list) -> Tuple[discord.Embed, List[str]]: -        """Generates error embed.""" -        embed = discord.Embed( +    def generate_invalid_embed(emojis: list) -> Tuple[Embed, List[str]]: +        """Generates error embed for invalid emoji categories.""" +        embed = Embed(              color=Colours.soft_red,              title=random.choice(ERROR_REPLIES)          ) @@ -64,11 +67,19 @@ class EmojiCount(commands.Cog):              emoji_dict[emoji.name.split("_")[0]].append(emoji)          error_comp = ', '.join(emoji_dict) -        msg.append(f"These are the valid categories\n```{error_comp}```") +        msg.append(f"These are the valid emoji categories:\n```{error_comp}```")          return embed, msg -    @commands.command(name="emojicount", aliases=["ec", "emojis"]) -    async def emoji_count(self, ctx: commands.Context, *, category_query: str = None) -> None: +    @commands.group(name="emoji", invoke_without_command=True) +    async def emoji_group(self, ctx: commands.Context, emoji: Optional[Emoji]) -> None: +        """A group of commands related to emojis.""" +        if emoji is not None: +            await ctx.invoke(self.info_command, emoji) +        else: +            await invoke_help_command(ctx) + +    @emoji_group.command(name="count", aliases=("c",)) +    async def count_command(self, ctx: commands.Context, *, category_query: str = None) -> None:          """Returns embed with emoji category and info given by the user."""          emoji_dict = defaultdict(list) @@ -91,7 +102,24 @@ class EmojiCount(commands.Cog):              embed, msg = self.embed_builder(emoji_dict)          await LinePaginator.paginate(lines=msg, ctx=ctx, embed=embed) +    @emoji_group.command(name="info", aliases=("i",)) +    async def info_command(self, ctx: commands.Context, emoji: Emoji) -> None: +        """Returns relevant information about a Discord Emoji.""" +        emoji_information = Embed( +            title=f"Emoji Information: {emoji.name}", +            description=textwrap.dedent(f""" +                **Name:** {emoji.name} +                **Created:** {time_since(emoji.created_at, precision="hours")} +                **Date:** {datetime.strftime(emoji.created_at, "%d/%m/%Y")} +                **ID:** {emoji.id} +            """), +            color=Color.blurple(), +            url=str(emoji.url), +        ).set_thumbnail(url=emoji.url) + +        await ctx.send(embed=emoji_information) +  def setup(bot: commands.Bot) -> None: -    """Emoji Count Cog load.""" -    bot.add_cog(EmojiCount(bot)) +    """Add the Emojis cog into the bot.""" +    bot.add_cog(Emojis(bot)) diff --git a/bot/exts/evergreen/game.py b/bot/exts/evergreen/game.py index d37be0e2..068d3f68 100644 --- a/bot/exts/evergreen/game.py +++ b/bot/exts/evergreen/game.py @@ -15,6 +15,7 @@ from discord.ext.commands import Cog, Context, group  from bot.bot import Bot  from bot.constants import STAFF_ROLES, Tokens  from bot.utils.decorators import with_role +from bot.utils.extensions import invoke_help_command  from bot.utils.pagination import ImagePaginator, LinePaginator  # Base URL of IGDB API @@ -234,7 +235,7 @@ class Games(Cog):          """          # When user didn't specified genre, send help message          if genre is None: -            await ctx.send_help("games") +            await invoke_help_command(ctx)              return          # Capitalize genre for check diff --git a/bot/exts/evergreen/minesweeper.py b/bot/exts/evergreen/minesweeper.py index 286ac7a5..3031debc 100644 --- a/bot/exts/evergreen/minesweeper.py +++ b/bot/exts/evergreen/minesweeper.py @@ -8,6 +8,7 @@ from discord.ext import commands  from bot.constants import Client  from bot.utils.exceptions import UserNotPlayingError +from bot.utils.extensions import invoke_help_command  MESSAGE_MAPPING = {      0: ":stop_button:", @@ -83,7 +84,7 @@ class Minesweeper(commands.Cog):      @commands.group(name='minesweeper', aliases=('ms',), invoke_without_command=True)      async def minesweeper_group(self, ctx: commands.Context) -> None:          """Commands for Playing Minesweeper.""" -        await ctx.send_help(ctx.command) +        await invoke_help_command(ctx)      @staticmethod      def get_neighbours(x: int, y: int) -> typing.Generator[typing.Tuple[int, int], None, None]: diff --git a/bot/exts/evergreen/movie.py b/bot/exts/evergreen/movie.py index 340a5724..b3bfe998 100644 --- a/bot/exts/evergreen/movie.py +++ b/bot/exts/evergreen/movie.py @@ -9,6 +9,7 @@ from discord import Embed  from discord.ext.commands import Bot, Cog, Context, group  from bot.constants import Tokens +from bot.utils.extensions import invoke_help_command  from bot.utils.pagination import ImagePaginator  # Define base URL of TMDB @@ -73,7 +74,7 @@ class Movie(Cog):          try:              result = await self.get_movies_list(self.http_session, MovieGenres[genre].value, 1)          except KeyError: -            await ctx.send_help('movies') +            await invoke_help_command(ctx)              return          # Check if "results" is in result. If not, throw error. diff --git a/bot/exts/evergreen/snakes/_snakes_cog.py b/bot/exts/evergreen/snakes/_snakes_cog.py index d5e4f206..3732b559 100644 --- a/bot/exts/evergreen/snakes/_snakes_cog.py +++ b/bot/exts/evergreen/snakes/_snakes_cog.py @@ -22,6 +22,7 @@ from bot.constants import ERROR_REPLIES, Tokens  from bot.exts.evergreen.snakes import _utils as utils  from bot.exts.evergreen.snakes._converter import Snake  from bot.utils.decorators import locked +from bot.utils.extensions import invoke_help_command  log = logging.getLogger(__name__) @@ -440,7 +441,7 @@ class Snakes(Cog):      @group(name='snakes', aliases=('snake',), invoke_without_command=True)      async def snakes_group(self, ctx: Context) -> None:          """Commands from our first code jam.""" -        await ctx.send_help(ctx.command) +        await invoke_help_command(ctx)      @bot_has_permissions(manage_messages=True)      @snakes_group.command(name='antidote') diff --git a/bot/exts/evergreen/source.py b/bot/exts/evergreen/source.py index cdfe54ec..45752bf9 100644 --- a/bot/exts/evergreen/source.py +++ b/bot/exts/evergreen/source.py @@ -76,7 +76,7 @@ class BotSource(commands.Cog):          file_location = Path(filename).relative_to(Path.cwd()).as_posix() -        url = f"{Source.github}/blob/master/{file_location}{lines_extension}" +        url = f"{Source.github}/blob/main/{file_location}{lines_extension}"          return url, file_location, first_line_no or None diff --git a/bot/exts/evergreen/space.py b/bot/exts/evergreen/space.py index bc8e3118..323ff659 100644 --- a/bot/exts/evergreen/space.py +++ b/bot/exts/evergreen/space.py @@ -10,6 +10,7 @@ from discord.ext.commands import BadArgument, Cog, Context, Converter, group  from bot.bot import Bot  from bot.constants import Tokens +from bot.utils.extensions import invoke_help_command  logger = logging.getLogger(__name__) @@ -63,7 +64,7 @@ class Space(Cog):      @group(name="space", invoke_without_command=True)      async def space(self, ctx: Context) -> None:          """Head command that contains commands about space.""" -        await ctx.send_help("space") +        await invoke_help_command(ctx)      @space.command(name="apod")      async def apod(self, ctx: Context, date: Optional[str] = None) -> None: diff --git a/bot/exts/evergreen/status_codes.py b/bot/exts/evergreen/status_codes.py index 874c87eb..7c00fe20 100644 --- a/bot/exts/evergreen/status_codes.py +++ b/bot/exts/evergreen/status_codes.py @@ -3,6 +3,8 @@ from http import HTTPStatus  import discord  from discord.ext import commands +from bot.utils.extensions import invoke_help_command +  HTTP_DOG_URL = "https://httpstatusdogs.com/img/{code}.jpg"  HTTP_CAT_URL = "https://http.cat/{code}.jpg" @@ -17,7 +19,7 @@ class HTTPStatusCodes(commands.Cog):      async def http_status_group(self, ctx: commands.Context) -> None:          """Group containing dog and cat http status code commands."""          if not ctx.invoked_subcommand: -            await ctx.send_help(ctx.command) +            await invoke_help_command(ctx)      @http_status_group.command(name='cat')      async def http_cat(self, ctx: commands.Context, code: int) -> None: diff --git a/bot/exts/evergreen/tic_tac_toe.py b/bot/exts/evergreen/tic_tac_toe.py index e1190502..6e21528e 100644 --- a/bot/exts/evergreen/tic_tac_toe.py +++ b/bot/exts/evergreen/tic_tac_toe.py @@ -10,8 +10,8 @@ from bot.constants import Emojis  from bot.utils.pagination import LinePaginator  CONFIRMATION_MESSAGE = ( -    "{opponent}, {requester} wants to play Tic-Tac-Toe against you. React to this message with " -    f"{Emojis.confirmation} to accept or with {Emojis.decline} to decline." +    "{opponent}, {requester} wants to play Tic-Tac-Toe against you." +    f"\nReact to this message with {Emojis.confirmation} to accept or with {Emojis.decline} to decline."  ) @@ -253,7 +253,7 @@ class TicTacToe(Cog):      @guild_only()      @is_channel_free()      @is_requester_free() -    @group(name="tictactoe", aliases=("ttt",), invoke_without_command=True) +    @group(name="tictactoe", aliases=("ttt", "tic"), invoke_without_command=True)      async def tic_tac_toe(self, ctx: Context, opponent: t.Optional[discord.User]) -> None:          """Tic Tac Toe game. Play against friends or AI. Use reactions to add your mark to field."""          if opponent == ctx.author: @@ -276,6 +276,10 @@ class TicTacToe(Cog):              )          self.games.append(game)          if opponent is not None: +            if opponent.bot:  # check whether the opponent is a bot or not +                await ctx.send("You can't play Tic-Tac-Toe with bots!") +                return +              confirmed, msg = await game.get_confirmation()              if not confirmed: diff --git a/bot/exts/utils/extensions.py b/bot/exts/utils/extensions.py index bb22c353..64e404d2 100644 --- a/bot/exts/utils/extensions.py +++ b/bot/exts/utils/extensions.py @@ -11,7 +11,7 @@ from bot import exts  from bot.bot import Bot  from bot.constants import Client, Emojis, MODERATION_ROLES, Roles  from bot.utils.checks import with_role_check -from bot.utils.extensions import EXTENSIONS, unqualify +from bot.utils.extensions import EXTENSIONS, invoke_help_command, unqualify  from bot.utils.pagination import LinePaginator  log = logging.getLogger(__name__) @@ -77,7 +77,7 @@ class Extensions(commands.Cog):      @group(name="extensions", aliases=("ext", "exts", "c", "cogs"), invoke_without_command=True)      async def extensions_group(self, ctx: Context) -> None:          """Load, unload, reload, and list loaded extensions.""" -        await ctx.send_help(ctx.command) +        await invoke_help_command(ctx)      @extensions_group.command(name="load", aliases=("l",))      async def load_command(self, ctx: Context, *extensions: Extension) -> None: @@ -87,7 +87,7 @@ class Extensions(commands.Cog):          If '\*' or '\*\*' is given as the name, all unloaded extensions will be loaded.          """  # noqa: W605          if not extensions: -            await ctx.send_help(ctx.command) +            await invoke_help_command(ctx)              return          if "*" in extensions or "**" in extensions: @@ -104,7 +104,7 @@ class Extensions(commands.Cog):          If '\*' or '\*\*' is given as the name, all loaded extensions will be unloaded.          """  # noqa: W605          if not extensions: -            await ctx.send_help(ctx.command) +            await invoke_help_command(ctx)              return          blacklisted = "\n".join(UNLOAD_BLACKLIST & set(extensions)) @@ -130,7 +130,7 @@ class Extensions(commands.Cog):          If '\*\*' is given as the name, all extensions, including unloaded ones, will be reloaded.          """  # noqa: W605          if not extensions: -            await ctx.send_help(ctx.command) +            await invoke_help_command(ctx)              return          if "**" in extensions: diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index f3392bcb..09591cf8 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -10,6 +10,7 @@ from discord.ext.commands.cooldowns import BucketType  from bot.constants import Channels, Colours, Lovefest, Month  from bot.utils.decorators import in_month +from bot.utils.extensions import invoke_help_command  log = logging.getLogger(__name__) @@ -43,7 +44,7 @@ class BeMyValentine(commands.Cog):          2) use the command \".lovefest unsub\" to get rid of the lovefest role.          """          if not ctx.invoked_subcommand: -            await ctx.send_help(ctx.command) +            await invoke_help_command(ctx)      @lovefest_role.command(name="sub")      async def add_role(self, ctx: commands.Context) -> None:  |