From 734addece0491fe16656a787e5f032e8f7190168 Mon Sep 17 00:00:00 2001 From: AtieP Date: Mon, 28 Sep 2020 16:54:08 +0200 Subject: Add time utils --- bot/utils/time.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 bot/utils/time.py (limited to 'bot') diff --git a/bot/utils/time.py b/bot/utils/time.py new file mode 100644 index 00000000..3c57e126 --- /dev/null +++ b/bot/utils/time.py @@ -0,0 +1,84 @@ +import datetime + +from dateutil.relativedelta import relativedelta + + +# All these functions are from https://github.com/python-discord/bot/blob/master/bot/utils/time.py +def _stringify_time_unit(value: int, unit: str) -> str: + """ + Returns a string to represent a value and time unit, ensuring that it uses the right plural form of the unit. + + >>> _stringify_time_unit(1, "seconds") + "1 second" + >>> _stringify_time_unit(24, "hours") + "24 hours" + >>> _stringify_time_unit(0, "minutes") + "less than a minute" + """ + if unit == "seconds" and value == 0: + return "0 seconds" + elif value == 1: + return f"{value} {unit[:-1]}" + elif value == 0: + return f"less than a {unit[:-1]}" + else: + return f"{value} {unit}" + + +def humanize_delta(delta: relativedelta, precision: str = "seconds", max_units: int = 6) -> str: + """ + Returns a human-readable version of the relativedelta. + + precision specifies the smallest unit of time to include (e.g. "seconds", "minutes"). + max_units specifies the maximum number of units of time to include (e.g. 1 may include days but not hours). + """ + if max_units <= 0: + raise ValueError("max_units must be positive") + + units = ( + ("years", delta.years), + ("months", delta.months), + ("days", delta.days), + ("hours", delta.hours), + ("minutes", delta.minutes), + ("seconds", delta.seconds), + ) + + # Add the time units that are >0, but stop at accuracy or max_units. + time_strings = [] + unit_count = 0 + for unit, value in units: + if value: + time_strings.append(_stringify_time_unit(value, unit)) + unit_count += 1 + + if unit == precision or unit_count >= max_units: + break + + # Add the 'and' between the last two units, if necessary + if len(time_strings) > 1: + time_strings[-1] = f"{time_strings[-2]} and {time_strings[-1]}" + del time_strings[-2] + + # If nothing has been found, just make the value 0 precision, e.g. `0 days`. + if not time_strings: + humanized = _stringify_time_unit(0, precision) + else: + humanized = ", ".join(time_strings) + + return humanized + + +def time_since(past_datetime: datetime.datetime, precision: str = "seconds", max_units: int = 6) -> str: + """ + Takes a datetime and returns a human-readable string that describes how long ago that datetime was. + + precision specifies the smallest unit of time to include (e.g. "seconds", "minutes"). + max_units specifies the maximum number of units of time to include (e.g. 1 may include days but not hours). + """ + now = datetime.datetime.utcnow() + delta = abs(relativedelta(now, past_datetime)) + + humanized = humanize_delta(delta, precision, max_units) + + return f"{humanized} ago" -- cgit v1.2.3 From 9813bedd3945d5efb42c6e5ca61782604ae8a343 Mon Sep 17 00:00:00 2001 From: AtieP Date: Mon, 28 Sep 2020 16:55:11 +0200 Subject: Add emojis cog --- bot/exts/evergreen/emojis.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 bot/exts/evergreen/emojis.py (limited to 'bot') diff --git a/bot/exts/evergreen/emojis.py b/bot/exts/evergreen/emojis.py new file mode 100644 index 00000000..67331941 --- /dev/null +++ b/bot/exts/evergreen/emojis.py @@ -0,0 +1,39 @@ +import textwrap + +from discord import Color, Embed, Emoji +from discord.ext import commands + +from bot.utils.time import time_since + + +class Emojis(commands.Cog): + """Has commands related to emojis.""" + + @commands.group(name="emoji", invoke_without_command=True) + async def emojis_group(self, ctx: commands.Context, emoji: Emoji) -> None: + """A group of commands related to emojis.""" + # No parameters = same as invoking info subcommand + await ctx.invoke(self.info_command, emoji) + + @emojis_group.command(name="info") + async def info_command(self, ctx: commands.Context, emoji: Emoji) -> None: + """Returns relevant information about a Discord Emoji.""" + emoji_information = Embed( + title=f'Information about "{emoji.name}"', + description=textwrap.dedent(f""" + Name: {emoji.name} + Created: {time_since(emoji.created_at)} + ID: {emoji.id} + Emote source: [Link]({emoji.url}) + """), + color=Color.blurple() + ) + emoji_information.set_thumbnail( + url=str(emoji.url) + ) + await ctx.send(embed=emoji_information) + + +def setup(bot: commands.Bot) -> None: + """Add the Emojis cog into the bot.""" + bot.add_cog(Emojis()) -- cgit v1.2.3 From cb75d950183da1ed169141dbf95a732fed366450 Mon Sep 17 00:00:00 2001 From: AtieP Date: Mon, 28 Sep 2020 17:37:09 +0200 Subject: No need to typecast emoji.url to str --- bot/exts/evergreen/emojis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/emojis.py b/bot/exts/evergreen/emojis.py index 67331941..fb4c8a44 100644 --- a/bot/exts/evergreen/emojis.py +++ b/bot/exts/evergreen/emojis.py @@ -29,7 +29,7 @@ class Emojis(commands.Cog): color=Color.blurple() ) emoji_information.set_thumbnail( - url=str(emoji.url) + url=emoji.url ) await ctx.send(embed=emoji_information) -- cgit v1.2.3 From 68a7bb5f7c12bd167e7bb7fcbdb37e6f4cbd72a1 Mon Sep 17 00:00:00 2001 From: AtieP Date: Mon, 28 Sep 2020 18:45:29 +0200 Subject: Rename the last description line --- bot/exts/evergreen/emojis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/emojis.py b/bot/exts/evergreen/emojis.py index fb4c8a44..950ec245 100644 --- a/bot/exts/evergreen/emojis.py +++ b/bot/exts/evergreen/emojis.py @@ -24,7 +24,7 @@ class Emojis(commands.Cog): Name: {emoji.name} Created: {time_since(emoji.created_at)} ID: {emoji.id} - Emote source: [Link]({emoji.url}) + [Emoji source image]({emoji.url}) """), color=Color.blurple() ) -- cgit v1.2.3 From 2fd63f6a2813c99d7098e444c5a3145f916b2729 Mon Sep 17 00:00:00 2001 From: AtieP <62116490+AtieP@users.noreply.github.com> Date: Mon, 28 Sep 2020 19:11:42 +0200 Subject: Set precision to hours Co-authored-by: gustavwilliam <65498475+gustavwilliam@users.noreply.github.com> --- bot/exts/evergreen/emojis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/emojis.py b/bot/exts/evergreen/emojis.py index 950ec245..9f825e6d 100644 --- a/bot/exts/evergreen/emojis.py +++ b/bot/exts/evergreen/emojis.py @@ -22,7 +22,7 @@ class Emojis(commands.Cog): title=f'Information about "{emoji.name}"', description=textwrap.dedent(f""" Name: {emoji.name} - Created: {time_since(emoji.created_at)} + Created: {time_since(emoji.created_at, precision="hours")} ID: {emoji.id} [Emoji source image]({emoji.url}) """), -- cgit v1.2.3 From 931fb3ea4a6eb767864b33df5bd17cfb48e1b919 Mon Sep 17 00:00:00 2001 From: Will Da Silva Date: Sun, 4 Oct 2020 22:44:49 -0400 Subject: Verify channel constants on startup Closes #393 --- bot/bot.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/bot.py b/bot/bot.py index ffaf4284..92873ba4 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -45,7 +45,7 @@ class SeasonalBot(commands.Bot): connector=TCPConnector(resolver=AsyncResolver(), family=socket.AF_INET) ) self._guild_available = asyncio.Event() - + self.loop.create_task(self.check_channels()) self.loop.create_task(self.send_log("SeasonalBot", "Connected!")) @property @@ -149,6 +149,15 @@ class SeasonalBot(commands.Bot): log.info("Nickname set successfully") return True + async def check_channels(self) -> None: + await self.wait_until_guild_available() + all_channels = set(self.get_all_channels()) + for name, channel_id in vars(Channels).items(): + if name.startswith('_'): + continue + if channel_id not in all_channels: + log.error(f'Channel "{name}" with id {channel_id} missing') + async def send_log(self, title: str, details: str = None, *, icon: str = None) -> None: """Send an embed message to the devlog channel.""" await self.wait_until_guild_available() -- cgit v1.2.3 From b907c4cc6e943904e506ec49d3a28d98e9073625 Mon Sep 17 00:00:00 2001 From: Will Da Silva Date: Sun, 4 Oct 2020 22:47:16 -0400 Subject: Add docstring to check_channels --- bot/bot.py | 1 + 1 file changed, 1 insertion(+) (limited to 'bot') diff --git a/bot/bot.py b/bot/bot.py index 92873ba4..c004414e 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -150,6 +150,7 @@ class SeasonalBot(commands.Bot): return True async def check_channels(self) -> None: + """Verifies that all channel constants refer to channels which exist.""" await self.wait_until_guild_available() all_channels = set(self.get_all_channels()) for name, channel_id in vars(Channels).items(): -- cgit v1.2.3 From 7bec6f4e9423d8e5a797a2a6e73cd235e0a5f0cf Mon Sep 17 00:00:00 2001 From: Will Da Silva Date: Sun, 4 Oct 2020 22:53:04 -0400 Subject: Capitalize "ID" in error message --- bot/bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/bot.py b/bot/bot.py index c004414e..b486201e 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -157,7 +157,7 @@ class SeasonalBot(commands.Bot): if name.startswith('_'): continue if channel_id not in all_channels: - log.error(f'Channel "{name}" with id {channel_id} missing') + log.error(f'Channel "{name}" with ID {channel_id} missing') async def send_log(self, title: str, details: str = None, *, icon: str = None) -> None: """Send an embed message to the devlog channel.""" -- cgit v1.2.3 From 3616302122f72c19b6ab4877fdb6a5236967110d Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 19 Jan 2021 06:37:09 +0530 Subject: Add connect four cog supporting player vs player and player vs ai --- bot/exts/evergreen/connect_four.py | 377 +++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 bot/exts/evergreen/connect_four.py (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py new file mode 100644 index 00000000..9519f124 --- /dev/null +++ b/bot/exts/evergreen/connect_four.py @@ -0,0 +1,377 @@ +import asyncio +import random +import typing +from functools import partial + +import discord +from discord.ext import commands + +EMOJIS = [":white_circle:", ":blue_circle:", ":red_circle:"] +NUMBERS = [ + ":one:", + ":two:", + ":three:", + ":four:", + ":five:", + ":six:", + ":seven:", + ":eight:", + ":nine:" +] +UNICODE_NUMBERS = [ + "\u0031\u20e3", + "\u0032\u20e3", + "\u0033\u20e3", + "\u0034\u20e3", + "\u0035\u20e3", + "\u0036\u20e3", + "\u0037\u20e3", + "\u0038\u20e3", + "\u0039\u20e3", +] +CROSS_EMOJI = "\u274e" +HAND_RAISED_EMOJI = "\U0001f64b" +Coordinate = typing.Optional[typing.Tuple[int, int]] + + +class Game: + """A Connect 4 Game.""" + + def __init__( + self, + bot: commands.Bot, + channel: discord.TextChannel, + player1: discord.Member, + player2: discord.Member = None, + size: int = 7, + ) -> None: + + self.bot = bot + self.channel = channel + self.player1 = player1 + self.player2 = player2 or AI(game=self) + + self.grid = self.generate_board(size) + self.grid_size = size + + self.unicode_numbers = UNICODE_NUMBERS[:self.grid_size] + + self.message = None + + self.turn = None + self.next = None + + @staticmethod + def generate_board(size: int) -> typing.List[typing.List[int]]: + """Generate the connect 4 board.""" + return [[0 for _ in range(size)] for _ in range(size)] + + async def print_grid(self) -> None: + """Formats and outputs the Connect Four grid to the channel.""" + rows = [" ".join(EMOJIS[s] for s in row) for row in self.grid] + first_row = " ".join(x for x in NUMBERS[:self.grid_size]) + formatted_grid = "\n".join([first_row] + rows) + embed = discord.Embed(title="Connect Four Board", description=formatted_grid) + + if self.message: + await self.message.edit(embed=embed) + else: + self.message = await self.channel.send(embed=embed) + for emoji in self.unicode_numbers: + await self.message.add_reaction(emoji) + + async def start_game(self) -> None: + """Begins the game.""" + self.turn, self.next = self.player1, self.player2 + + while True: + await self.print_grid() + if isinstance(self.turn, AI): + coords = self.turn.play() + else: + coords = await self.player_turn() + + if not coords: + return + + if self.check_win(coords, 1 if self.turn == self.player1 else 2): + if isinstance(self.turn, AI): + await self.channel.send(f"Game Over! {self.turn.mention} lost against AI") + else: + if isinstance(self.next, AI): + await self.channel.send(f"Game Over! {self.turn.mention} won against AI") + else: + await self.channel.send(f"Game Over! {self.turn.mention} won against {self.next.mention}") + await self.print_grid() + return + + self.turn, self.next = self.next, self.turn + + def predicate(self, reaction: discord.Reaction, user: discord.Member) -> bool: + """The predicate to check for the player's reaction.""" + return ( + reaction.message.id == self.message.id + and user.id == self.turn.id + and str(reaction.emoji) in self.unicode_numbers + ) + + async def player_turn(self) -> Coordinate: + """Initiate the player's turn.""" + message = await self.channel.send( + f"{self.turn.mention}, it's your turn! React with a column you want to place your token" + ) + player_num = 1 if self.turn == self.player1 else 2 + while True: + full_column = False + try: + reaction, user = await self.bot.wait_for("reaction_add", check=self.predicate, timeout=30.0) + except asyncio.TimeoutError: + await self.channel.send(f"{self.turn.mention}, you took too long. Game over!") + return + else: + await message.delete() + await self.message.remove_reaction(reaction, user) + column_num = self.unicode_numbers.index(str(reaction.emoji)) + + column = [row[column_num] for row in self.grid] + + for row_num, square in reversed(list(enumerate(column))): + if not square: + self.grid[row_num][column_num] = player_num + coords = row_num, column_num + break + else: + await self.channel.send(f"Column {column_num + 1} is full. Try again") + full_column = True + if not full_column: + break + return coords + + def check_win(self, coords: Coordinate, player_num: int) -> bool: + """Check that placing a counter here would cause the player to win.""" + vertical = [(-1, 0), (1, 0)] + horizontal = [(0, 1), (0, -1)] + forward_diag = [(-1, 1), (1, -1)] + backward_diag = [(-1, -1), (1, 1)] + axes = [vertical, horizontal, forward_diag, backward_diag] + + for axis in axes: + in_a_row = 1 # The initial counter that is compared to + for (row_incr, column_incr) in axis: + row, column = coords + row += row_incr + column += column_incr + + while 0 <= row < self.grid_size and 0 <= column < self.grid_size: + if self.grid[row][column] == player_num: + in_a_row += 1 + row += row_incr + column += column_incr + else: + break + if in_a_row >= 4: + return True + return False + + +class AI: + """The Computer Player for Single-Player games.""" + + def __init__(self, game: Game) -> None: + self.game = game + + def get_possible_places(self) -> typing.List[Coordinate]: + """Gets all the coordinates where the AI could possibly place a counter.""" + possible_coords = [] + for column_num in range(self.game.grid_size): + column = [row[column_num] for row in self.game.grid] + for row_num, square in reversed(list(enumerate(column))): + if not square: + possible_coords.append((row_num, column_num)) + break + return possible_coords + + def check_ai_win(self, coord_list: typing.List[Coordinate]) -> typing.Optional[Coordinate]: + """Check if placing a counter in any possible coordinate would cause the AI to win.""" + if random.randint(1, 10) == 1: # 10% chance of not winning + return + for coords in coord_list: + if self.game.check_win(coords, 2): + return coords + + def check_player_win(self, coord_list: typing.List[Coordinate]) -> typing.Optional[Coordinate]: + """Check if placing a counter in any possible coordinate would stop the player from winning.""" + if random.randint(1, 4) == 1: # 25% chance of not blocking the player + return + for coords in coord_list: + if self.game.check_win(coords, 1): + return coords + + @staticmethod + def random_coords(coord_list: typing.List[Coordinate]) -> Coordinate: + """Picks a random coordinate from the possible ones.""" + return random.choice(coord_list) + + def play(self) -> Coordinate: + """The AI's turn.""" + possible_coords = self.get_possible_places() + + coords = self.check_ai_win(possible_coords) # Win + if not coords: + coords = self.check_player_win(possible_coords) # Try to stop P1 from winning + if not coords: + coords = self.random_coords(possible_coords) + + row, column = coords + self.game.grid[row][column] = 2 + return coords + + +class ConnectFour(commands.Cog): + """Connect Four. The Classic Vertical Four-in-a-row Game!""" + + def __init__(self, bot: commands.Bot) -> None: + self.bot = bot + self.games: typing.List[Game] = [] + self.waiting: typing.List[discord.Member] = [] + + self.max_board_size = 9 + self.min_board_size = 5 + + def get_player( + self, + ctx: commands.Context, + announcement: discord.Message, + reaction: discord.Reaction, + user: discord.Member + ) -> bool: + """Predicate checking the criteria for the announcement message.""" + if self.already_playing(ctx.author): # If they've joined a game since requesting a player 2 + return True # Is dealt with later on + if ( + user.id not in (ctx.me.id, ctx.author.id) + and str(reaction.emoji) == HAND_RAISED_EMOJI + and reaction.message.id == announcement.id + ): + if self.already_playing(user): + self.bot.loop.create_task(ctx.send(f"{user.mention} You're already playing a game!")) + self.bot.loop.create_task(announcement.remove_reaction(reaction, user)) + return False + + if user in self.waiting: + self.bot.loop.create_task(ctx.send( + f"{user.mention} Please cancel your game first before joining another one." + )) + self.bot.loop.create_task(announcement.remove_reaction(reaction, user)) + return False + + return True + + if ( + user.id == ctx.author.id + and str(reaction.emoji) == CROSS_EMOJI + and reaction.message.id == announcement.id + ): + return True + return False + + def already_playing(self, player: discord.Member) -> bool: + """Check if someone is already in a game.""" + return any(player in (game.player1, game.player2) for game in self.games) + + async def _play_game(self, ctx: commands.Context, user: typing.Optional[discord.Member], board_size: int) -> None: + """Helper for playing a game of connect four.""" + try: + game = Game(self.bot, ctx.channel, ctx.author, user, size=board_size) + self.games.append(game) + await game.start_game() + self.games.remove(game) + except Exception: + # End the game in the event of an unforseen error so the players aren't stuck in a game + await ctx.send(f"{ctx.author.mention} {user.mention if user else ''} An error occurred. Game failed") + self.games.remove(game) + raise + + @commands.group(invoke_without_command=True, aliases=[ + "4inarow", "4-in-a-row", "4_in_a_row", "connect4", "connect-four", "connect_four" + ]) + @commands.guild_only() + async def connectfour(self, ctx: commands.Context, board_size: int = 7) -> None: + """ + Play the classic game of Connect Four with someone! + + Sets up a message waiting for someone else to react and play along. + The game will start once someone has reacted. + All inputs will be through reactions. + """ + if self.already_playing(ctx.author): + await ctx.send("You're already playing a game!") + return + + if ctx.author in self.waiting: + await ctx.send("You've already sent out a request for a player 2") + return + + if board_size > self.max_board_size or board_size < self.min_board_size: + await ctx.send(f"{board_size} is not a valid board size. A valid board size it " + f"between `{self.min_board_size}` to `{self.max_board_size}`") + return + + announcement = await ctx.send( + "**Connect Four**: A new game is about to start!\n" + f"Press {HAND_RAISED_EMOJI} to play against {ctx.author.mention}!\n" + f"(Cancel the game with {CROSS_EMOJI}.)" + ) + self.waiting.append(ctx.author) + await announcement.add_reaction(HAND_RAISED_EMOJI) + await announcement.add_reaction(CROSS_EMOJI) + + try: + reaction, user = await self.bot.wait_for( + "reaction_add", + check=partial(self.get_player, ctx, announcement), + timeout=60.0 + ) + except asyncio.TimeoutError: + self.waiting.remove(ctx.author) + await announcement.delete() + await ctx.send(f"{ctx.author.mention} Seems like there's no one here to play" + f"Use `{ctx.prefix}{ctx.invoked_with} ai` to play against a computer." + ) + return + + if str(reaction.emoji) == CROSS_EMOJI: + self.waiting.remove(ctx.author) + await announcement.delete() + await ctx.send(f"{ctx.author.mention} Game cancelled.") + return + + await announcement.delete() + self.waiting.remove(ctx.author) + if self.already_playing(ctx.author): + return + + await self._play_game(ctx, user, board_size) + + @connectfour.command(aliases=["AI", "CPU", "computer", "cpu", "Computer"]) + async def ai(self, ctx: commands.Context, board_size: int = 7) -> None: + """Play Connect Four against a computer player.""" + if self.already_playing(ctx.author): + await ctx.send("You're already playing a game!") + return + + if ctx.author in self.waiting: + await ctx.send("You've already sent out a request for a player 2") + return + + if board_size > self.max_board_size or board_size < self.min_board_size: + await ctx.send(f"{board_size} is not a valid board size. A valid board size it " + f"between `{self.min_board_size}` to `{self.max_board_size}`") + return + + await self._play_game(ctx, user=None, board_size=board_size) + + +def setup(bot: commands.Bot) -> None: + """Load ConnectFour Cog.""" + bot.add_cog(ConnectFour(bot)) -- cgit v1.2.3 From f44a39ddc14ee23dd9394deac4a90cf0300ebbab Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Wed, 20 Jan 2021 05:28:10 +0530 Subject: fix grammar and spacing --- bot/exts/evergreen/connect_four.py | 62 ++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 9519f124..2592bf3f 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -58,8 +58,8 @@ class Game: self.message = None - self.turn = None - self.next = None + self.player_active = None + self.player_inactive = None @staticmethod def generate_board(size: int) -> typing.List[typing.List[int]]: @@ -82,51 +82,51 @@ class Game: async def start_game(self) -> None: """Begins the game.""" - self.turn, self.next = self.player1, self.player2 + self.player_active, self.player_inactive = self.player1, self.player2 while True: await self.print_grid() - if isinstance(self.turn, AI): - coords = self.turn.play() + if isinstance(self.player_active, AI): + coords = self.player_active.play() else: coords = await self.player_turn() if not coords: return - if self.check_win(coords, 1 if self.turn == self.player1 else 2): - if isinstance(self.turn, AI): - await self.channel.send(f"Game Over! {self.turn.mention} lost against AI") + if self.check_win(coords, 1 if self.player_active == self.player1 else 2): + if isinstance(self.player_active, AI): + await self.channel.send(f"Game Over! {self.player_active.mention} lost against AI") else: - if isinstance(self.next, AI): - await self.channel.send(f"Game Over! {self.turn.mention} won against AI") + if isinstance(self.player_inactive, AI): + await self.channel.send(f"Game Over! {self.player_active.mention} won against AI") else: - await self.channel.send(f"Game Over! {self.turn.mention} won against {self.next.mention}") + await self.channel.send(f"Game Over! {self.player_active.mention} won against {self.player_inactive.mention}") await self.print_grid() return - self.turn, self.next = self.next, self.turn + self.player_active, self.player_inactive = self.player_inactive, self.player_active def predicate(self, reaction: discord.Reaction, user: discord.Member) -> bool: """The predicate to check for the player's reaction.""" return ( reaction.message.id == self.message.id - and user.id == self.turn.id + and user.id == self.player_active.id and str(reaction.emoji) in self.unicode_numbers ) async def player_turn(self) -> Coordinate: """Initiate the player's turn.""" message = await self.channel.send( - f"{self.turn.mention}, it's your turn! React with a column you want to place your token" + f"{self.turn.mention}, it's your turn! React with the column you want to place your token in." ) - player_num = 1 if self.turn == self.player1 else 2 + player_num = 1 if self.player_active == self.player1 else 2 while True: full_column = False try: reaction, user = await self.bot.wait_for("reaction_add", check=self.predicate, timeout=30.0) except asyncio.TimeoutError: - await self.channel.send(f"{self.turn.mention}, you took too long. Game over!") + await self.channel.send(f"{self.player_active.mention}, you took too long. Game over!") return else: await message.delete() @@ -156,7 +156,7 @@ class Game: axes = [vertical, horizontal, forward_diag, backward_diag] for axis in axes: - in_a_row = 1 # The initial counter that is compared to + counters_in_a_row = 1 # The initial counter that is compared to for (row_incr, column_incr) in axis: row, column = coords row += row_incr @@ -164,12 +164,12 @@ class Game: while 0 <= row < self.grid_size and 0 <= column < self.grid_size: if self.grid[row][column] == player_num: - in_a_row += 1 + counters_in_a_row += 1 row += row_incr column += column_incr else: break - if in_a_row >= 4: + if counters_in_a_row >= 4: return True return False @@ -287,16 +287,17 @@ class ConnectFour(commands.Cog): await game.start_game() self.games.remove(game) except Exception: - # End the game in the event of an unforseen error so the players aren't stuck in a game + # End the game in the event of an unforeseen error so the players aren't stuck in a game await ctx.send(f"{ctx.author.mention} {user.mention if user else ''} An error occurred. Game failed") self.games.remove(game) raise - @commands.group(invoke_without_command=True, aliases=[ - "4inarow", "4-in-a-row", "4_in_a_row", "connect4", "connect-four", "connect_four" - ]) + @commands.group( + invoke_without_command=True, + aliases=["4inarow", "connect4", "connectfour", "c4"] + ) @commands.guild_only() - async def connectfour(self, ctx: commands.Context, board_size: int = 7) -> None: + async def connect_four(self, ctx: commands.Context, board_size: int = 7) -> None: """ Play the classic game of Connect Four with someone! @@ -313,8 +314,8 @@ class ConnectFour(commands.Cog): return if board_size > self.max_board_size or board_size < self.min_board_size: - await ctx.send(f"{board_size} is not a valid board size. A valid board size it " - f"between `{self.min_board_size}` to `{self.max_board_size}`") + await ctx.send(f"{board_size} is not a valid board size. A valid board size is " + f"between `{self.min_board_size}` and `{self.max_board_size}`.") return announcement = await ctx.send( @@ -335,9 +336,10 @@ class ConnectFour(commands.Cog): except asyncio.TimeoutError: self.waiting.remove(ctx.author) await announcement.delete() - await ctx.send(f"{ctx.author.mention} Seems like there's no one here to play" - f"Use `{ctx.prefix}{ctx.invoked_with} ai` to play against a computer." - ) + await ctx.send( + f"{ctx.author.mention} Seems like there's no one here to play. " + f"Use `{ctx.prefix}{ctx.invoked_with} ai` to play against a computer." + ) return if str(reaction.emoji) == CROSS_EMOJI: @@ -353,7 +355,7 @@ class ConnectFour(commands.Cog): await self._play_game(ctx, user, board_size) - @connectfour.command(aliases=["AI", "CPU", "computer", "cpu", "Computer"]) + @connectfour.command(aliases=["bot", "computer", "cpu"]) async def ai(self, ctx: commands.Context, board_size: int = 7) -> None: """Play Connect Four against a computer player.""" if self.already_playing(ctx.author): -- cgit v1.2.3 From 24e7f9508b61675d17f8fabf58f2fef4e7f97084 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Wed, 20 Jan 2021 05:45:26 +0530 Subject: COrrect annotations and improve docstrings ; make code more pythonic --- bot/exts/evergreen/connect_four.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 2592bf3f..1d2c82a2 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -42,7 +42,7 @@ class Game: bot: commands.Bot, channel: discord.TextChannel, player1: discord.Member, - player2: discord.Member = None, + player2: typing.Optional[discord.Member], size: int = 7, ) -> None: @@ -64,7 +64,7 @@ class Game: @staticmethod def generate_board(size: int) -> typing.List[typing.List[int]]: """Generate the connect 4 board.""" - return [[0 for _ in range(size)] for _ in range(size)] + return [[0]*size]*size async def print_grid(self) -> None: """Formats and outputs the Connect Four grid to the channel.""" @@ -101,7 +101,9 @@ class Game: if isinstance(self.player_inactive, AI): await self.channel.send(f"Game Over! {self.player_active.mention} won against AI") else: - await self.channel.send(f"Game Over! {self.player_active.mention} won against {self.player_inactive.mention}") + await self.channel.send( + f"Game Over! {self.player_active.mention} won against {self.player_inactive.mention}" + ) await self.print_grid() return @@ -213,14 +215,22 @@ class AI: return random.choice(coord_list) def play(self) -> Coordinate: - """The AI's turn.""" + """ + Plays for the AI. + + Gets all possible coords, and determins the move: + 1. coords where it can win. + 2. coords where the player can win. + 3. Random coord + The first possible value is choosen. + """ possible_coords = self.get_possible_places() - coords = self.check_ai_win(possible_coords) # Win - if not coords: - coords = self.check_player_win(possible_coords) # Try to stop P1 from winning - if not coords: - coords = self.random_coords(possible_coords) + coords = ( + self.check_ai_win(possible_coords) + or self.check_player_win(possible_coords) + or self.random_coords(possible_coords) + ) row, column = coords self.game.grid[row][column] = 2 @@ -296,7 +306,6 @@ class ConnectFour(commands.Cog): invoke_without_command=True, aliases=["4inarow", "connect4", "connectfour", "c4"] ) - @commands.guild_only() async def connect_four(self, ctx: commands.Context, board_size: int = 7) -> None: """ Play the classic game of Connect Four with someone! @@ -313,7 +322,7 @@ class ConnectFour(commands.Cog): await ctx.send("You've already sent out a request for a player 2") return - if board_size > self.max_board_size or board_size < self.min_board_size: + if not self.min_board_size <= board_size <= self.max_board_size: await ctx.send(f"{board_size} is not a valid board size. A valid board size is " f"between `{self.min_board_size}` and `{self.max_board_size}`.") return @@ -355,7 +364,7 @@ class ConnectFour(commands.Cog): await self._play_game(ctx, user, board_size) - @connectfour.command(aliases=["bot", "computer", "cpu"]) + @connect_four.command(aliases=["bot", "computer", "cpu"]) async def ai(self, ctx: commands.Context, board_size: int = 7) -> None: """Play Connect Four against a computer player.""" if self.already_playing(ctx.author): -- cgit v1.2.3 From d1acfa3ecc37b63b21a1889d38ae1405b917238f Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Wed, 20 Jan 2021 07:02:08 +0530 Subject: Change Ai to bot's user and add stop game functionality, remove redundant code, and DRY --- bot/exts/evergreen/connect_four.py | 68 ++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 29 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 1d2c82a2..1e5d6fac 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -49,7 +49,7 @@ class Game: self.bot = bot self.channel = channel self.player1 = player1 - self.player2 = player2 or AI(game=self) + self.player2 = player2 or AI(self.bot, game=self) self.grid = self.generate_board(size) self.grid_size = size @@ -64,7 +64,7 @@ class Game: @staticmethod def generate_board(size: int) -> typing.List[typing.List[int]]: """Generate the connect 4 board.""" - return [[0]*size]*size + return [[0 for _ in range(size)] for _ in range(size)] async def print_grid(self) -> None: """Formats and outputs the Connect Four grid to the channel.""" @@ -79,6 +79,7 @@ class Game: self.message = await self.channel.send(embed=embed) for emoji in self.unicode_numbers: await self.message.add_reaction(emoji) + await self.message.add_reaction(CROSS_EMOJI) async def start_game(self) -> None: """Begins the game.""" @@ -96,10 +97,12 @@ class Game: if self.check_win(coords, 1 if self.player_active == self.player1 else 2): if isinstance(self.player_active, AI): - await self.channel.send(f"Game Over! {self.player_active.mention} lost against AI") + await self.channel.send(f"Game Over! {self.player_inactive.mention} lost against" + f" {self.bot.user.mention}") else: if isinstance(self.player_inactive, AI): - await self.channel.send(f"Game Over! {self.player_active.mention} won against AI") + await self.channel.send(f"Game Over! {self.player_active.mention} won against" + f" {self.bot.user.mention}") else: await self.channel.send( f"Game Over! {self.player_active.mention} won against {self.player_inactive.mention}" @@ -114,13 +117,13 @@ class Game: return ( reaction.message.id == self.message.id and user.id == self.player_active.id - and str(reaction.emoji) in self.unicode_numbers + and str(reaction.emoji) in (*self.unicode_numbers, CROSS_EMOJI) ) async def player_turn(self) -> Coordinate: """Initiate the player's turn.""" message = await self.channel.send( - f"{self.turn.mention}, it's your turn! React with the column you want to place your token in." + f"{self.player_active.mention}, it's your turn! React with the column you want to place your token in." ) player_num = 1 if self.player_active == self.player1 else 2 while True: @@ -131,6 +134,13 @@ class Game: await self.channel.send(f"{self.player_active.mention}, you took too long. Game over!") return else: + if str(reaction.emoji) == CROSS_EMOJI: + await message.delete() + await self.channel.send( + f"{user.mention} has abandoned the game :(" + ) + return + await message.delete() await self.message.remove_reaction(reaction, user) column_num = self.unicode_numbers.index(str(reaction.emoji)) @@ -179,8 +189,9 @@ class Game: class AI: """The Computer Player for Single-Player games.""" - def __init__(self, game: Game) -> None: + def __init__(self, bot: commands.Bot, game: Game) -> None: self.game = game + self.mention = bot.user.mention def get_possible_places(self) -> typing.List[Coordinate]: """Gets all the coordinates where the AI could possibly place a counter.""" @@ -248,6 +259,23 @@ class ConnectFour(commands.Cog): self.max_board_size = 9 self.min_board_size = 5 + async def check_author(self, ctx: commands.Context, board_size: int) -> bool: + """Check if the requester is free and the board size is correct.""" + if self.already_playing(ctx.author): + await ctx.send("You're already playing a game!") + return False + + if ctx.author in self.waiting: + await ctx.send("You've already sent out a request for a player 2") + return False + + if not self.min_board_size <= board_size <= self.max_board_size: + await ctx.send(f"{board_size} is not a valid board size. A valid board size is " + f"between `{self.min_board_size}` and `{self.max_board_size}`.") + return False + + return True + def get_player( self, ctx: commands.Context, @@ -314,17 +342,8 @@ class ConnectFour(commands.Cog): The game will start once someone has reacted. All inputs will be through reactions. """ - if self.already_playing(ctx.author): - await ctx.send("You're already playing a game!") - return - - if ctx.author in self.waiting: - await ctx.send("You've already sent out a request for a player 2") - return - - if not self.min_board_size <= board_size <= self.max_board_size: - await ctx.send(f"{board_size} is not a valid board size. A valid board size is " - f"between `{self.min_board_size}` and `{self.max_board_size}`.") + check_author_result = await self.check_author(ctx, board_size) + if not check_author_result: return announcement = await ctx.send( @@ -367,17 +386,8 @@ class ConnectFour(commands.Cog): @connect_four.command(aliases=["bot", "computer", "cpu"]) async def ai(self, ctx: commands.Context, board_size: int = 7) -> None: """Play Connect Four against a computer player.""" - if self.already_playing(ctx.author): - await ctx.send("You're already playing a game!") - return - - if ctx.author in self.waiting: - await ctx.send("You've already sent out a request for a player 2") - return - - if board_size > self.max_board_size or board_size < self.min_board_size: - await ctx.send(f"{board_size} is not a valid board size. A valid board size it " - f"between `{self.min_board_size}` to `{self.max_board_size}`") + check_author_result = await self.check_author(ctx, board_size) + if not check_author_result: return await self._play_game(ctx, user=None, board_size=board_size) -- cgit v1.2.3 From 46e594c390cce07f522329b5fc012b886bcdbb81 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Thu, 21 Jan 2021 07:40:53 +0530 Subject: Add loading message before finishing all reactions and improve embed title --- bot/exts/evergreen/connect_four.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 1e5d6fac..a4f29172 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -68,18 +68,24 @@ class Game: async def print_grid(self) -> None: """Formats and outputs the Connect Four grid to the channel.""" + title = ( + f'Connect 4: {self.player1.display_name}' + f'VS {self.player2.display_name}' + ) + rows = [" ".join(EMOJIS[s] for s in row) for row in self.grid] first_row = " ".join(x for x in NUMBERS[:self.grid_size]) formatted_grid = "\n".join([first_row] + rows) - embed = discord.Embed(title="Connect Four Board", description=formatted_grid) + embed = discord.Embed(title=title, description=formatted_grid) if self.message: await self.message.edit(embed=embed) else: - self.message = await self.channel.send(embed=embed) + self.message = await self.channel.send(content='Loading ....') for emoji in self.unicode_numbers: await self.message.add_reaction(emoji) await self.message.add_reaction(CROSS_EMOJI) + await self.message.edit(content=None, embed=embed) async def start_game(self) -> None: """Begins the game.""" -- cgit v1.2.3 From 089baf161da449995b475971c5e0689a5b24c7e8 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Thu, 21 Jan 2021 09:59:11 +0530 Subject: Improve embeds and docstrings --- bot/exts/evergreen/connect_four.py | 58 +++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 23 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index a4f29172..38647f8e 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -38,12 +38,12 @@ class Game: """A Connect 4 Game.""" def __init__( - self, - bot: commands.Bot, - channel: discord.TextChannel, - player1: discord.Member, - player2: typing.Optional[discord.Member], - size: int = 7, + self, + bot: commands.Bot, + channel: discord.TextChannel, + player1: discord.Member, + player2: typing.Optional[discord.Member], + size: int = 7, ) -> None: self.bot = bot @@ -70,7 +70,7 @@ class Game: """Formats and outputs the Connect Four grid to the channel.""" title = ( f'Connect 4: {self.player1.display_name}' - f'VS {self.player2.display_name}' + f'VS {self.bot.user.display_name if isinstance(self.player2, AI) else self.player2.display_name}' ) rows = [" ".join(EMOJIS[s] for s in row) for row in self.grid] @@ -211,16 +211,26 @@ class AI: return possible_coords def check_ai_win(self, coord_list: typing.List[Coordinate]) -> typing.Optional[Coordinate]: - """Check if placing a counter in any possible coordinate would cause the AI to win.""" - if random.randint(1, 10) == 1: # 10% chance of not winning + """ + Check AI win. + + Check if placing a counter in any possible coordinate would cause the AI to win + with 10% chance of not winning and returning None + """ + if random.randint(1, 10) == 1: return for coords in coord_list: if self.game.check_win(coords, 2): return coords def check_player_win(self, coord_list: typing.List[Coordinate]) -> typing.Optional[Coordinate]: - """Check if placing a counter in any possible coordinate would stop the player from winning.""" - if random.randint(1, 4) == 1: # 25% chance of not blocking the player + """ + Check Player win. + + Check if placing a counter in possible coordinates would stop the player + from winning with 25% of not blocking them and returning None. + """ + if random.randint(1, 4) == 1: return for coords in coord_list: if self.game.check_win(coords, 1): @@ -283,19 +293,20 @@ class ConnectFour(commands.Cog): return True def get_player( - self, - ctx: commands.Context, - announcement: discord.Message, - reaction: discord.Reaction, - user: discord.Member + self, + ctx: commands.Context, + announcement: discord.Message, + reaction: discord.Reaction, + user: discord.Member ) -> bool: """Predicate checking the criteria for the announcement message.""" if self.already_playing(ctx.author): # If they've joined a game since requesting a player 2 return True # Is dealt with later on + if ( - user.id not in (ctx.me.id, ctx.author.id) - and str(reaction.emoji) == HAND_RAISED_EMOJI - and reaction.message.id == announcement.id + user.id not in (ctx.me.id, ctx.author.id) + and str(reaction.emoji) == HAND_RAISED_EMOJI + and reaction.message.id == announcement.id ): if self.already_playing(user): self.bot.loop.create_task(ctx.send(f"{user.mention} You're already playing a game!")) @@ -312,9 +323,9 @@ class ConnectFour(commands.Cog): return True if ( - user.id == ctx.author.id - and str(reaction.emoji) == CROSS_EMOJI - and reaction.message.id == announcement.id + user.id == ctx.author.id + and str(reaction.emoji) == CROSS_EMOJI + and reaction.message.id == announcement.id ): return True return False @@ -333,7 +344,8 @@ class ConnectFour(commands.Cog): except Exception: # End the game in the event of an unforeseen error so the players aren't stuck in a game await ctx.send(f"{ctx.author.mention} {user.mention if user else ''} An error occurred. Game failed") - self.games.remove(game) + if game in self.games: + self.games.remove(game) raise @commands.group( -- cgit v1.2.3 From a972cd19e993e5ea9a1120432d7523329cb22d9b Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Thu, 21 Jan 2021 11:32:41 +0530 Subject: Add ability to get custom tokens from the bot --- bot/exts/evergreen/connect_four.py | 67 +++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 23 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 38647f8e..6ae14f53 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -6,7 +6,7 @@ from functools import partial import discord from discord.ext import commands -EMOJIS = [":white_circle:", ":blue_circle:", ":red_circle:"] +EMOJIS = None NUMBERS = [ ":one:", ":two:", @@ -38,12 +38,12 @@ class Game: """A Connect 4 Game.""" def __init__( - self, - bot: commands.Bot, - channel: discord.TextChannel, - player1: discord.Member, - player2: typing.Optional[discord.Member], - size: int = 7, + self, + bot: commands.Bot, + channel: discord.TextChannel, + player1: discord.Member, + player2: typing.Optional[discord.Member], + size: int = 7, ) -> None: self.bot = bot @@ -293,20 +293,20 @@ class ConnectFour(commands.Cog): return True def get_player( - self, - ctx: commands.Context, - announcement: discord.Message, - reaction: discord.Reaction, - user: discord.Member + self, + ctx: commands.Context, + announcement: discord.Message, + reaction: discord.Reaction, + user: discord.Member ) -> bool: """Predicate checking the criteria for the announcement message.""" if self.already_playing(ctx.author): # If they've joined a game since requesting a player 2 return True # Is dealt with later on if ( - user.id not in (ctx.me.id, ctx.author.id) - and str(reaction.emoji) == HAND_RAISED_EMOJI - and reaction.message.id == announcement.id + user.id not in (ctx.me.id, ctx.author.id) + and str(reaction.emoji) == HAND_RAISED_EMOJI + and reaction.message.id == announcement.id ): if self.already_playing(user): self.bot.loop.create_task(ctx.send(f"{user.mention} You're already playing a game!")) @@ -323,9 +323,9 @@ class ConnectFour(commands.Cog): return True if ( - user.id == ctx.author.id - and str(reaction.emoji) == CROSS_EMOJI - and reaction.message.id == announcement.id + user.id == ctx.author.id + and str(reaction.emoji) == CROSS_EMOJI + and reaction.message.id == announcement.id ): return True return False @@ -334,9 +334,18 @@ class ConnectFour(commands.Cog): """Check if someone is already in a game.""" return any(player in (game.player1, game.player2) for game in self.games) - async def _play_game(self, ctx: commands.Context, user: typing.Optional[discord.Member], board_size: int) -> None: + async def _play_game( + self, + ctx: commands.Context, + user: typing.Optional[discord.Member], + board_size: int, + emoji1: str, + emoji2: str + ) -> None: """Helper for playing a game of connect four.""" try: + global EMOJIS + EMOJIS = [":white_circle:", str(emoji1), str(emoji2)] game = Game(self.bot, ctx.channel, ctx.author, user, size=board_size) self.games.append(game) await game.start_game() @@ -352,7 +361,13 @@ class ConnectFour(commands.Cog): invoke_without_command=True, aliases=["4inarow", "connect4", "connectfour", "c4"] ) - async def connect_four(self, ctx: commands.Context, board_size: int = 7) -> None: + async def connect_four( + self, + ctx: commands.Context, + board_size: int = 7, + emoji1: str = ":blue_circle:", + emoji2: str = ":red_circle:" + ) -> None: """ Play the classic game of Connect Four with someone! @@ -399,16 +414,22 @@ class ConnectFour(commands.Cog): if self.already_playing(ctx.author): return - await self._play_game(ctx, user, board_size) + await self._play_game(ctx, user, board_size, emoji1, emoji2) @connect_four.command(aliases=["bot", "computer", "cpu"]) - async def ai(self, ctx: commands.Context, board_size: int = 7) -> None: + async def ai( + self, + ctx: commands.Context, + board_size: int = 7, + emoji1: str = ":blue_circle:", + emoji2: str = ":red_circle:" + ) -> None: """Play Connect Four against a computer player.""" check_author_result = await self.check_author(ctx, board_size) if not check_author_result: return - await self._play_game(ctx, user=None, board_size=board_size) + await self._play_game(ctx, None, board_size, emoji1, emoji2) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From 8175bc0fbe1fad08372a27b1fb340baf8f20062b Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Thu, 21 Jan 2021 14:01:45 +0530 Subject: Remove redundant code --- bot/exts/evergreen/connect_four.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 6ae14f53..e6d4b41a 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -133,7 +133,6 @@ class Game: ) player_num = 1 if self.player_active == self.player1 else 2 while True: - full_column = False try: reaction, user = await self.bot.wait_for("reaction_add", check=self.predicate, timeout=30.0) except asyncio.TimeoutError: @@ -149,21 +148,15 @@ class Game: await message.delete() await self.message.remove_reaction(reaction, user) - column_num = self.unicode_numbers.index(str(reaction.emoji)) + column_num = self.unicode_numbers.index(str(reaction.emoji)) column = [row[column_num] for row in self.grid] for row_num, square in reversed(list(enumerate(column))): if not square: self.grid[row_num][column_num] = player_num - coords = row_num, column_num - break - else: - await self.channel.send(f"Column {column_num + 1} is full. Try again") - full_column = True - if not full_column: - break - return coords + return row_num, column_num + message = await self.channel.send(f"Column {column_num + 1} is full. Try again") def check_win(self, coords: Coordinate, player_num: int) -> bool: """Check that placing a counter here would cause the player to win.""" -- cgit v1.2.3 From 35b2984674c3a1645476a8c2172deadd51472f0f Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Thu, 21 Jan 2021 14:14:15 +0530 Subject: Check if the emoji given by user is available --- bot/exts/evergreen/connect_four.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index e6d4b41a..a44d6dbf 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -358,8 +358,8 @@ class ConnectFour(commands.Cog): self, ctx: commands.Context, board_size: int = 7, - emoji1: str = ":blue_circle:", - emoji2: str = ":red_circle:" + emoji1: discord.Emoji = ":blue_circle:", + emoji2: discord.Emoji = ":red_circle:" ) -> None: """ Play the classic game of Connect Four with someone! @@ -407,6 +407,9 @@ class ConnectFour(commands.Cog): if self.already_playing(ctx.author): return + emoji1 = str(emoji1) + emoji2 = str(emoji2) + await self._play_game(ctx, user, board_size, emoji1, emoji2) @connect_four.command(aliases=["bot", "computer", "cpu"]) @@ -414,14 +417,17 @@ class ConnectFour(commands.Cog): self, ctx: commands.Context, board_size: int = 7, - emoji1: str = ":blue_circle:", - emoji2: str = ":red_circle:" + emoji1: discord.Emoji = ":blue_circle:", + emoji2: discord.Emoji = ":red_circle:" ) -> None: """Play Connect Four against a computer player.""" check_author_result = await self.check_author(ctx, board_size) if not check_author_result: return + emoji1 = str(emoji1) + emoji2 = str(emoji2) + await self._play_game(ctx, None, board_size, emoji1, emoji2) -- cgit v1.2.3 From db53775344e0ceef247fb0e045bc515c9d9591b8 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 23 Jan 2021 05:35:09 +0530 Subject: Fix user given emoji check --- bot/exts/evergreen/connect_four.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index a44d6dbf..be370a83 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -6,7 +6,7 @@ from functools import partial import discord from discord.ext import commands -EMOJIS = None +EMOJI_TOKENS = [":white_circle:", ":blue_circle:", ":red_circle:"] NUMBERS = [ ":one:", ":two:", @@ -32,6 +32,7 @@ UNICODE_NUMBERS = [ CROSS_EMOJI = "\u274e" HAND_RAISED_EMOJI = "\U0001f64b" Coordinate = typing.Optional[typing.Tuple[int, int]] +EMOJI_CHECK = typing.Union[discord.Emoji, str] class Game: @@ -336,9 +337,10 @@ class ConnectFour(commands.Cog): emoji2: str ) -> None: """Helper for playing a game of connect four.""" + global EMOJIS + EMOJIS = [":white_circle:", str(emoji1), str(emoji2)] + try: - global EMOJIS - EMOJIS = [":white_circle:", str(emoji1), str(emoji2)] game = Game(self.bot, ctx.channel, ctx.author, user, size=board_size) self.games.append(game) await game.start_game() @@ -358,8 +360,8 @@ class ConnectFour(commands.Cog): self, ctx: commands.Context, board_size: int = 7, - emoji1: discord.Emoji = ":blue_circle:", - emoji2: discord.Emoji = ":red_circle:" + emoji1: EMOJI_CHECK = ":blue_circle:", + emoji2: EMOJI_CHECK = ":red_circle:" ) -> None: """ Play the classic game of Connect Four with someone! @@ -368,6 +370,11 @@ class ConnectFour(commands.Cog): The game will start once someone has reacted. All inputs will be through reactions. """ + if isinstance(emoji1, str) and len(emoji1) > 1: + raise commands.EmojiNotFound(emoji1) + if isinstance(emoji2, str) and len(emoji2) > 1: + raise commands.EmojiNotFound(emoji2) + check_author_result = await self.check_author(ctx, board_size) if not check_author_result: return @@ -407,28 +414,22 @@ class ConnectFour(commands.Cog): if self.already_playing(ctx.author): return - emoji1 = str(emoji1) - emoji2 = str(emoji2) - - await self._play_game(ctx, user, board_size, emoji1, emoji2) + await self._play_game(ctx, user, board_size, str(emoji1), str(emoji2)) @connect_four.command(aliases=["bot", "computer", "cpu"]) async def ai( self, ctx: commands.Context, board_size: int = 7, - emoji1: discord.Emoji = ":blue_circle:", - emoji2: discord.Emoji = ":red_circle:" + emoji1: EMOJI_CHECK = ":blue_circle:" ) -> None: """Play Connect Four against a computer player.""" + if isinstance(emoji1, str) and len(emoji1) > 1: + raise commands.EmojiNotFound(emoji1) check_author_result = await self.check_author(ctx, board_size) if not check_author_result: return - - emoji1 = str(emoji1) - emoji2 = str(emoji2) - - await self._play_game(ctx, None, board_size, emoji1, emoji2) + await self._play_game(ctx, None, board_size, str(emoji1), ":red_circle:") def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From f701e93cfb768f7a04c786437cdbe3a7105d4bc9 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sun, 24 Jan 2021 16:58:07 +0530 Subject: Send a message on draw (was catching a error earlier) ; Improve send game over (winner/loser) code ; add case_insensitive alias --- bot/exts/evergreen/connect_four.py | 57 ++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index be370a83..7c5261c5 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -71,7 +71,7 @@ class Game: """Formats and outputs the Connect Four grid to the channel.""" title = ( f'Connect 4: {self.player1.display_name}' - f'VS {self.bot.user.display_name if isinstance(self.player2, AI) else self.player2.display_name}' + f' VS {self.bot.user.display_name if isinstance(self.player2, AI) else self.player2.display_name}' ) rows = [" ".join(EMOJIS[s] for s in row) for row in self.grid] @@ -88,14 +88,23 @@ class Game: await self.message.add_reaction(CROSS_EMOJI) await self.message.edit(content=None, embed=embed) + async def game_over(self, winner: discord.user, loser: discord.user) -> None: + """Removes games from list of current games and announces to public chat.""" + await self.channel.send(f"Game Over! {winner.mention} won against {loser.mention}") + await self.print_grid() + async def start_game(self) -> None: """Begins the game.""" self.player_active, self.player_inactive = self.player1, self.player2 while True: await self.print_grid() + if isinstance(self.player_active, AI): coords = self.player_active.play() + if not coords: + await self.channel.send(f"Game Over! Its's A Draw :tada:") + await self.print_grid() else: coords = await self.player_turn() @@ -103,18 +112,10 @@ class Game: return if self.check_win(coords, 1 if self.player_active == self.player1 else 2): - if isinstance(self.player_active, AI): - await self.channel.send(f"Game Over! {self.player_inactive.mention} lost against" - f" {self.bot.user.mention}") - else: - if isinstance(self.player_inactive, AI): - await self.channel.send(f"Game Over! {self.player_active.mention} won against" - f" {self.bot.user.mention}") - else: - await self.channel.send( - f"Game Over! {self.player_active.mention} won against {self.player_inactive.mention}" - ) - await self.print_grid() + await self.game_over( + self.bot.user if isinstance(self.player_active, AI) else {self.player_active}, + self.bot.user if isinstance(self.player_inactive, AI) else {self.player_inactive}, + ) return self.player_active, self.player_inactive = self.player_inactive, self.player_active @@ -122,9 +123,9 @@ class Game: def predicate(self, reaction: discord.Reaction, user: discord.Member) -> bool: """The predicate to check for the player's reaction.""" return ( - reaction.message.id == self.message.id - and user.id == self.player_active.id - and str(reaction.emoji) in (*self.unicode_numbers, CROSS_EMOJI) + reaction.message.id == self.message.id + and user.id == self.player_active.id + and str(reaction.emoji) in (*self.unicode_numbers, CROSS_EMOJI) ) async def player_turn(self) -> Coordinate: @@ -142,9 +143,7 @@ class Game: else: if str(reaction.emoji) == CROSS_EMOJI: await message.delete() - await self.channel.send( - f"{user.mention} has abandoned the game :(" - ) + await self.channel.send(f"{self.player_active.user} surrendered. Game over!") return await message.delete() @@ -235,7 +234,7 @@ class AI: """Picks a random coordinate from the possible ones.""" return random.choice(coord_list) - def play(self) -> Coordinate: + def play(self) -> typing.Union[Coordinate, bool]: """ Plays for the AI. @@ -247,10 +246,13 @@ class AI: """ possible_coords = self.get_possible_places() + if not possible_coords: + return False + coords = ( - self.check_ai_win(possible_coords) - or self.check_player_win(possible_coords) - or self.random_coords(possible_coords) + self.check_ai_win(possible_coords) + or self.check_player_win(possible_coords) + or self.random_coords(possible_coords) ) row, column = coords @@ -354,14 +356,15 @@ class ConnectFour(commands.Cog): @commands.group( invoke_without_command=True, - aliases=["4inarow", "connect4", "connectfour", "c4"] + aliases=["4inarow", "connect4", "connectfour", "c4"], + case_insensitive=True ) async def connect_four( self, ctx: commands.Context, board_size: int = 7, - emoji1: EMOJI_CHECK = ":blue_circle:", - emoji2: EMOJI_CHECK = ":red_circle:" + emoji1: EMOJI_CHECK = "\U0001f535", + emoji2: EMOJI_CHECK = "\U0001f534" ) -> None: """ Play the classic game of Connect Four with someone! @@ -421,7 +424,7 @@ class ConnectFour(commands.Cog): self, ctx: commands.Context, board_size: int = 7, - emoji1: EMOJI_CHECK = ":blue_circle:" + emoji1: EMOJI_CHECK = "\U0001f535" ) -> None: """Play Connect Four against a computer player.""" if isinstance(emoji1, str) and len(emoji1) > 1: -- cgit v1.2.3 From 914f2a8340c8c5636589f4e11de880f48cac52e2 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sun, 24 Jan 2021 17:02:11 +0530 Subject: Fix lint issues --- bot/exts/evergreen/connect_four.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 7c5261c5..51d1adc3 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -103,7 +103,7 @@ class Game: if isinstance(self.player_active, AI): coords = self.player_active.play() if not coords: - await self.channel.send(f"Game Over! Its's A Draw :tada:") + await self.channel.send("Game Over! It's A Draw :tada:") await self.print_grid() else: coords = await self.player_turn() @@ -123,9 +123,9 @@ class Game: def predicate(self, reaction: discord.Reaction, user: discord.Member) -> bool: """The predicate to check for the player's reaction.""" return ( - reaction.message.id == self.message.id - and user.id == self.player_active.id - and str(reaction.emoji) in (*self.unicode_numbers, CROSS_EMOJI) + reaction.message.id == self.message.id + and user.id == self.player_active.id + and str(reaction.emoji) in (*self.unicode_numbers, CROSS_EMOJI) ) async def player_turn(self) -> Coordinate: @@ -250,9 +250,9 @@ class AI: return False coords = ( - self.check_ai_win(possible_coords) - or self.check_player_win(possible_coords) - or self.random_coords(possible_coords) + self.check_ai_win(possible_coords) + or self.check_player_win(possible_coords) + or self.random_coords(possible_coords) ) row, column = coords -- cgit v1.2.3 From 53af90f92258905c2bfc4c2db2341dfd1fdc0124 Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 06:52:15 -0800 Subject: Fixed linting errors. --- bot/bot.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/bot.py b/bot/bot.py index 112c9a48..81d59706 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -37,7 +37,6 @@ class Bot(commands.Bot): self.loop.create_task(self.check_channels()) self.loop.create_task(self.send_log(self.name, "Connected!")) - @property def member(self) -> Optional[discord.Member]: """Retrieves the guild member object for the bot.""" @@ -76,7 +75,7 @@ class Bot(commands.Bot): """Verifies that all channel constants refer to channels which exist.""" await self.wait_until_guild_available() all_channels = set(self.get_all_channels()) - for name, channel_id in vars(Channels).items(): + for name, channel_id in vars(constants.Channels).items(): if name.startswith('_'): continue if channel_id not in all_channels: -- cgit v1.2.3 From a563d3ae23c1c1eff01a284e0510bdc364cc415a Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 30 Jan 2021 17:21:11 +0530 Subject: Fix misleading game_over docstring --- bot/exts/evergreen/connect_four.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 51d1adc3..19067277 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -89,7 +89,7 @@ class Game: await self.message.edit(content=None, embed=embed) async def game_over(self, winner: discord.user, loser: discord.user) -> None: - """Removes games from list of current games and announces to public chat.""" + """Announces to public chat.""" await self.channel.send(f"Game Over! {winner.mention} won against {loser.mention}") await self.print_grid() -- cgit v1.2.3 From 79fb946c55b9f3049b0e2f0c5fd38f2ee2ee5add Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 30 Jan 2021 17:22:45 +0530 Subject: Line 114, 115 was cuasing error as a set was being sent to it instead discord.member object --- bot/exts/evergreen/connect_four.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 19067277..858caf78 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -113,8 +113,8 @@ class Game: if self.check_win(coords, 1 if self.player_active == self.player1 else 2): await self.game_over( - self.bot.user if isinstance(self.player_active, AI) else {self.player_active}, - self.bot.user if isinstance(self.player_inactive, AI) else {self.player_inactive}, + self.bot.user if isinstance(self.player_active, AI) else self.player_active, + self.bot.user if isinstance(self.player_inactive, AI) else self.player_inactive, ) return -- cgit v1.2.3 From 9675434e1437b4c182e1eccbeeba9aa064ce779b Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 30 Jan 2021 17:23:37 +0530 Subject: REmove repeating code --- bot/exts/evergreen/connect_four.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 858caf78..30eb0ff9 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -141,12 +141,11 @@ class Game: await self.channel.send(f"{self.player_active.mention}, you took too long. Game over!") return else: + await message.delete() if str(reaction.emoji) == CROSS_EMOJI: - await message.delete() await self.channel.send(f"{self.player_active.user} surrendered. Game over!") return - - await message.delete() + await self.message.remove_reaction(reaction, user) column_num = self.unicode_numbers.index(str(reaction.emoji)) -- cgit v1.2.3 From 630f46a197c89a137e89c0bba526090c8f0ace33 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 30 Jan 2021 17:25:45 +0530 Subject: Error while sending surrender message as it was taking .user instead of .mention --- bot/exts/evergreen/connect_four.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 30eb0ff9..7ad0d723 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -82,7 +82,7 @@ class Game: if self.message: await self.message.edit(embed=embed) else: - self.message = await self.channel.send(content='Loading ....') + self.message = await self.channel.send(content='Loading...') for emoji in self.unicode_numbers: await self.message.add_reaction(emoji) await self.message.add_reaction(CROSS_EMOJI) @@ -143,7 +143,7 @@ class Game: else: await message.delete() if str(reaction.emoji) == CROSS_EMOJI: - await self.channel.send(f"{self.player_active.user} surrendered. Game over!") + await self.channel.send(f"{self.player_active.mention} surrendered. Game over!") return await self.message.remove_reaction(reaction, user) -- cgit v1.2.3 From 46ca17d5fe41e704e40e22839e9d8b21c9a7b659 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sun, 31 Jan 2021 04:55:57 +0530 Subject: Let game_over function handle all gane over instances --- bot/exts/evergreen/connect_four.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 7ad0d723..31b85bbe 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -88,9 +88,14 @@ class Game: await self.message.add_reaction(CROSS_EMOJI) await self.message.edit(content=None, embed=embed) - async def game_over(self, winner: discord.user, loser: discord.user) -> None: + async def game_over(self, action: str, player1: discord.user, player2: discord.user) -> None: """Announces to public chat.""" - await self.channel.send(f"Game Over! {winner.mention} won against {loser.mention}") + if action == "win": + await self.channel.send(f"Game Over! {player1.mention} won against {player2.mention}") + elif action == "draw": + await self.channel.send(f"Game Over! {player1.mention} {player2.mention} It's A Draw :tada:") + elif action == "quit": + await self.channel.send(f"{self.player1.mention} surrendered. Game over!") await self.print_grid() async def start_game(self) -> None: @@ -103,8 +108,11 @@ class Game: if isinstance(self.player_active, AI): coords = self.player_active.play() if not coords: - await self.channel.send("Game Over! It's A Draw :tada:") - await self.print_grid() + await self.game_over( + "draw", + self.bot.user if isinstance(self.player_active, AI) else self.player_active, + self.bot.user if isinstance(self.player_inactive, AI) else self.player_inactive, + ) else: coords = await self.player_turn() @@ -113,6 +121,7 @@ class Game: if self.check_win(coords, 1 if self.player_active == self.player1 else 2): await self.game_over( + "win", self.bot.user if isinstance(self.player_active, AI) else self.player_active, self.bot.user if isinstance(self.player_inactive, AI) else self.player_inactive, ) @@ -143,9 +152,9 @@ class Game: else: await message.delete() if str(reaction.emoji) == CROSS_EMOJI: - await self.channel.send(f"{self.player_active.mention} surrendered. Game over!") + await self.game_over("quit", self.player_active, self.player_inactive) return - + await self.message.remove_reaction(reaction, user) column_num = self.unicode_numbers.index(str(reaction.emoji)) -- cgit v1.2.3 From 259686206e71496131872788a746186ee34920d8 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sun, 31 Jan 2021 05:05:54 +0530 Subject: Add ability to choose ai token while playing against ai --- bot/exts/evergreen/connect_four.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 31b85bbe..50632c1b 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -338,6 +338,15 @@ class ConnectFour(commands.Cog): """Check if someone is already in a game.""" return any(player in (game.player1, game.player2) for game in self.games) + @staticmethod + def check_emojis(e1: EMOJI_CHECK, e2: EMOJI_CHECK) -> typing.Tuple[bool, typing.Optional[str]]: + """Validate the emojis, the user put.""" + if isinstance(e1, str) and len(e1) > 1: + return False, e1 + if isinstance(e2, str) and len(e2) > 1: + return False, e2 + return True, None + async def _play_game( self, ctx: commands.Context, @@ -381,10 +390,9 @@ class ConnectFour(commands.Cog): The game will start once someone has reacted. All inputs will be through reactions. """ - if isinstance(emoji1, str) and len(emoji1) > 1: - raise commands.EmojiNotFound(emoji1) - if isinstance(emoji2, str) and len(emoji2) > 1: - raise commands.EmojiNotFound(emoji2) + check, emoji = self.check_emojis(emoji1, emoji2) + if not check: + raise commands.EmojiNotFound(emoji) check_author_result = await self.check_author(ctx, board_size) if not check_author_result: @@ -432,15 +440,19 @@ class ConnectFour(commands.Cog): self, ctx: commands.Context, board_size: int = 7, - emoji1: EMOJI_CHECK = "\U0001f535" + emoji1: EMOJI_CHECK = "\U0001f535", + emoji2: EMOJI_CHECK = "\U0001f534" ) -> None: """Play Connect Four against a computer player.""" - if isinstance(emoji1, str) and len(emoji1) > 1: - raise commands.EmojiNotFound(emoji1) + check, emoji = self.check_emojis(emoji1, emoji2) + if not check: + raise commands.EmojiNotFound(emoji) + check_author_result = await self.check_author(ctx, board_size) if not check_author_result: return - await self._play_game(ctx, None, board_size, str(emoji1), ":red_circle:") + + await self._play_game(ctx, None, board_size, str(emoji1), str(emoji2)) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From 29c84ad7cc6729c0887f49206ade8f98e2655fd1 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 1 Feb 2021 13:37:04 +0530 Subject: Remove the use of globals and instead use class variables --- bot/exts/evergreen/connect_four.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 50632c1b..48473d30 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -6,7 +6,6 @@ from functools import partial import discord from discord.ext import commands -EMOJI_TOKENS = [":white_circle:", ":blue_circle:", ":red_circle:"] NUMBERS = [ ":one:", ":two:", @@ -44,13 +43,15 @@ class Game: channel: discord.TextChannel, player1: discord.Member, player2: typing.Optional[discord.Member], - size: int = 7, + tokens: typing.List[str], + size: int = 7 ) -> None: self.bot = bot self.channel = channel self.player1 = player1 self.player2 = player2 or AI(self.bot, game=self) + self.tokens = tokens self.grid = self.generate_board(size) self.grid_size = size @@ -74,7 +75,7 @@ class Game: f' VS {self.bot.user.display_name if isinstance(self.player2, AI) else self.player2.display_name}' ) - rows = [" ".join(EMOJIS[s] for s in row) for row in self.grid] + rows = [" ".join(self.tokens[s] for s in row) for row in self.grid] first_row = " ".join(x for x in NUMBERS[:self.grid_size]) formatted_grid = "\n".join([first_row] + rows) embed = discord.Embed(title=title, description=formatted_grid) @@ -276,6 +277,8 @@ class ConnectFour(commands.Cog): self.games: typing.List[Game] = [] self.waiting: typing.List[discord.Member] = [] + self.tokens = [":white_circle:", ":blue_circle:", ":red_circle:"] + self.max_board_size = 9 self.min_board_size = 5 @@ -356,11 +359,10 @@ class ConnectFour(commands.Cog): emoji2: str ) -> None: """Helper for playing a game of connect four.""" - global EMOJIS - EMOJIS = [":white_circle:", str(emoji1), str(emoji2)] + self.tokens = [":white_circle:", str(emoji1), str(emoji2)] try: - game = Game(self.bot, ctx.channel, ctx.author, user, size=board_size) + game = Game(self.bot, ctx.channel, ctx.author, user, self.tokens, size=board_size) self.games.append(game) await game.start_game() self.games.remove(game) -- cgit v1.2.3 From 4b8f5789aa0c9f6ce005273ed1affdbc3a87c16a Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 1 Feb 2021 14:46:55 +0530 Subject: Add check if game is not intialized --- bot/exts/evergreen/connect_four.py | 1 + 1 file changed, 1 insertion(+) (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 48473d30..bf604e2a 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -360,6 +360,7 @@ class ConnectFour(commands.Cog): ) -> None: """Helper for playing a game of connect four.""" self.tokens = [":white_circle:", str(emoji1), str(emoji2)] + game = None # if game fails to intialize in try...except try: game = Game(self.bot, ctx.channel, ctx.author, user, self.tokens, size=board_size) -- cgit v1.2.3 From 4687f3d142a40fecc8d851e598dabb6c474059f1 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Thu, 4 Feb 2021 17:28:03 +0530 Subject: Intial Commit; Change secret functionality and fix member intents issue --- bot/exts/valentines/be_my_valentine.py | 70 +++++++++------------------------- 1 file changed, 17 insertions(+), 53 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index 4db4d191..818d539a 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -2,13 +2,13 @@ import logging import random from json import load from pathlib import Path -from typing import Optional, Tuple +from typing import Tuple import discord from discord.ext import commands from discord.ext.commands.cooldowns import BucketType -from bot.constants import Channels, Client, Colours, Lovefest, Month +from bot.constants import Channels, Colours, Lovefest, Month from bot.utils.decorators import in_month log = logging.getLogger(__name__) @@ -70,15 +70,14 @@ class BeMyValentine(commands.Cog): @commands.cooldown(1, 1800, BucketType.user) @commands.group(name='bemyvalentine', invoke_without_command=True) async def send_valentine( - self, ctx: commands.Context, user: Optional[discord.Member] = None, *, valentine_type: str = None + self, ctx: commands.Context, user: discord.Member, *, valentine_type: str = None ) -> None: """ Send a valentine to user, if specified, or to a random user with the lovefest role. - syntax: .bemyvalentine [user](optional) [p/poem/c/compliment/or you can type your own valentine message] + syntax: .bemyvalentine [user] [p/poem/c/compliment/or you can type your own valentine message] (optional) - example: .bemyvalentine (sends valentine as a poem or a compliment to a random user) example: .bemyvalentine Iceman#6508 p (sends a poem to Iceman) example: .bemyvalentine Iceman Hey I love you, wanna hang around ? (sends the custom message to Iceman) NOTE : AVOID TAGGING THE USER MOST OF THE TIMES.JUST TRIM THE '@' when using this command. @@ -88,26 +87,18 @@ class BeMyValentine(commands.Cog): msg = "You are supposed to use this command in the server." return await ctx.send(msg) - if user: - if Lovefest.role_id not in [role.id for role in user.roles]: - message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!" - return await ctx.send(message) + if Lovefest.role_id not in [role.id for role in user.roles]: + message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!" + return await ctx.send(message) if user == ctx.author: # Well a user can't valentine himself/herself. return await ctx.send("Come on dude, you can't send a valentine to yourself :expressionless:") emoji_1, emoji_2 = self.random_emoji() - lovefest_role = discord.utils.get(ctx.guild.roles, id=Lovefest.role_id) channel = self.bot.get_channel(Channels.community_bot_commands) valentine, title = self.valentine_check(valentine_type) - if user is None: - author = ctx.author - user = self.random_user(author, lovefest_role.members) - if user is None: - return await ctx.send("There are no users avilable to whome your valentine can be sent.") - embed = discord.Embed( title=f'{emoji_1} {title} {user.display_name} {emoji_2}', description=f'{valentine} \n **{emoji_2}From {ctx.author}{emoji_1}**', @@ -118,47 +109,31 @@ class BeMyValentine(commands.Cog): @commands.cooldown(1, 1800, BucketType.user) @send_valentine.command(name='secret') async def anonymous( - self, ctx: commands.Context, user: Optional[discord.Member] = None, *, valentine_type: str = None + self, ctx: commands.Context, user: discord.Member, *, valentine_type: str = None ) -> None: """ Send an anonymous Valentine via DM to to a user, if specified, or to a random with the lovefest role. - **This command should be DMed to the bot.** - - syntax : .bemyvalentine secret [user](optional) [p/poem/c/compliment/or you can type your own valentine message] + syntax : .bemyvalentine secret [user] [p/poem/c/compliment/or you can type your own valentine message] (optional) - example : .bemyvalentine secret (sends valentine as a poem or a compliment to a random user in DM making you - anonymous) example : .bemyvalentine secret Iceman#6508 p (sends a poem to Iceman in DM making you anonymous) example : .bemyvalentine secret Iceman#6508 Hey I love you, wanna hang around ? (sends the custom message to Iceman in DM making you anonymous) """ - if ctx.guild is not None: - # This command is only DM specific - msg = "You are not supposed to use this command in the server, DM the command to the bot." - return await ctx.send(msg) - - if user: - if Lovefest.role_id not in [role.id for role in user.roles]: - message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!" - return await ctx.send(message) + if Lovefest.role_id not in [role.id for role in user.roles]: + message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!" + await ctx.message.delete() + return await ctx.author.send(message) if user == ctx.author: # Well a user cant valentine himself/herself. - return await ctx.send('Come on dude, you cant send a valentine to yourself :expressionless:') + await ctx.message.delete() + return await ctx.author.send('Come on dude, you cant send a valentine to yourself :expressionless:') - guild = self.bot.get_guild(id=Client.guild) emoji_1, emoji_2 = self.random_emoji() - lovefest_role = discord.utils.get(guild.roles, id=Lovefest.role_id) valentine, title = self.valentine_check(valentine_type) - if user is None: - author = ctx.author - user = self.random_user(author, lovefest_role.members) - if user is None: - return await ctx.send("There are no users avilable to whome your valentine can be sent.") - embed = discord.Embed( title=f'{emoji_1}{title} {user.display_name}{emoji_2}', description=f'{valentine} \n **{emoji_2}From anonymous{emoji_1}**', @@ -166,8 +141,9 @@ class BeMyValentine(commands.Cog): ) try: await user.send(embed=embed) + await ctx.message.delete() except discord.Forbidden: - await ctx.author.send(f"{user} has DMs disabled, so I couldn't send the message. Sorry!") + await ctx.send(f"{user} has DMs disabled, so I couldn't send the message. Sorry!") else: await ctx.author.send(f"Your message has been sent to {user}") @@ -190,18 +166,6 @@ class BeMyValentine(commands.Cog): title = 'A message for' return valentine, title - @staticmethod - def random_user(author: discord.Member, members: discord.Member) -> None: - """ - Picks a random member from the list provided in `members`. - - The invoking author is ignored. - """ - if author in members: - members.remove(author) - - return random.choice(members) if members else None - @staticmethod def random_emoji() -> Tuple[str, str]: """Return two random emoji from the module-defined constants.""" -- cgit v1.2.3 From ae518304b130af53846d8cbd425463661dbc068f Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Fri, 5 Feb 2021 06:43:25 +0530 Subject: Fix return statements and return type annotations --- bot/exts/valentines/be_my_valentine.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index 818d539a..41959409 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -85,15 +85,18 @@ class BeMyValentine(commands.Cog): if ctx.guild is None: # This command should only be used in the server msg = "You are supposed to use this command in the server." - return await ctx.send(msg) + await ctx.send(msg) + return if Lovefest.role_id not in [role.id for role in user.roles]: message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!" - return await ctx.send(message) + await ctx.send(message) + return if user == ctx.author: # Well a user can't valentine himself/herself. - return await ctx.send("Come on dude, you can't send a valentine to yourself :expressionless:") + await ctx.send("Come on dude, you can't send a valentine to yourself :expressionless:") + return emoji_1, emoji_2 = self.random_emoji() channel = self.bot.get_channel(Channels.community_bot_commands) -- cgit v1.2.3 From 1951ce5fe0a2ae3bd8ef27abe68b1abe3b12be28 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Fri, 5 Feb 2021 06:46:48 +0530 Subject: Remove code that requires intents.member set True --- bot/exts/valentines/lovecalculator.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/lovecalculator.py b/bot/exts/valentines/lovecalculator.py index c75ea6cf..5cc08fed 100644 --- a/bot/exts/valentines/lovecalculator.py +++ b/bot/exts/valentines/lovecalculator.py @@ -11,8 +11,6 @@ from discord import Member from discord.ext import commands from discord.ext.commands import BadArgument, Cog, clean_content -from bot.constants import Roles - log = logging.getLogger(__name__) with Path("bot/resources/valentines/love_matches.json").open(encoding="utf8") as file: @@ -28,7 +26,7 @@ class LoveCalculator(Cog): @commands.command(aliases=('love_calculator', 'love_calc')) @commands.cooldown(rate=1, per=5, type=commands.BucketType.user) - async def love(self, ctx: commands.Context, who: Union[Member, str], whom: Union[Member, str] = None) -> None: + async def love(self, ctx: commands.Context, who: Union[Member, str], whom: Union[Member, str]) -> None: """ Tells you how much the two love each other. @@ -46,13 +44,7 @@ class LoveCalculator(Cog): If you want to use multiple words for one argument, you must include quotes. .love "Zes Vappa" "morning coffee" - - If only one argument is provided, the subject will become one of the helpers at random. """ - if whom is None: - staff = ctx.guild.get_role(Roles.helpers).members - whom = random.choice(staff) - def normalize(arg: Union[Member, str]) -> str: if isinstance(arg, Member): # If we are given a member, return name#discrim without any extra changes -- cgit v1.2.3 From d9a40f8591de1537b38d261e77b42ddc8cbc5688 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Fri, 5 Feb 2021 06:54:02 +0530 Subject: If whom is None, take the user as whom --- bot/exts/valentines/lovecalculator.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/lovecalculator.py b/bot/exts/valentines/lovecalculator.py index 5cc08fed..966acc82 100644 --- a/bot/exts/valentines/lovecalculator.py +++ b/bot/exts/valentines/lovecalculator.py @@ -4,7 +4,7 @@ import json import logging import random from pathlib import Path -from typing import Union +from typing import Coroutine, Union import discord from discord import Member @@ -26,7 +26,7 @@ class LoveCalculator(Cog): @commands.command(aliases=('love_calculator', 'love_calc')) @commands.cooldown(rate=1, per=5, type=commands.BucketType.user) - async def love(self, ctx: commands.Context, who: Union[Member, str], whom: Union[Member, str]) -> None: + async def love(self, ctx: commands.Context, who: Union[Member, str], whom: Union[Member, str] = None) -> None: """ Tells you how much the two love each other. @@ -45,7 +45,10 @@ class LoveCalculator(Cog): If you want to use multiple words for one argument, you must include quotes. .love "Zes Vappa" "morning coffee" """ - def normalize(arg: Union[Member, str]) -> str: + if whom is None: + whom = ctx.author + + def normalize(arg: Union[Member, str]) -> Coroutine: if isinstance(arg, Member): # If we are given a member, return name#discrim without any extra changes arg = str(arg) -- cgit v1.2.3 From 370535b80690f89544840dc3967bfa7c59e6e667 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 6 Feb 2021 08:43:07 +0530 Subject: Improve grammar and update docstrings, add try..except block while sending DMs --- bot/exts/valentines/be_my_valentine.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index 41959409..26966804 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -73,7 +73,7 @@ class BeMyValentine(commands.Cog): self, ctx: commands.Context, user: discord.Member, *, valentine_type: str = None ) -> None: """ - Send a valentine to user, if specified, or to a random user with the lovefest role. + Send a valentine to a specified user with the lovefest role. syntax: .bemyvalentine [user] [p/poem/c/compliment/or you can type your own valentine message] (optional) @@ -89,7 +89,7 @@ class BeMyValentine(commands.Cog): return if Lovefest.role_id not in [role.id for role in user.roles]: - message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!" + message = f"You cannot send a valentine to {user} as they do not have the lovefest role!" await ctx.send(message) return @@ -115,7 +115,7 @@ class BeMyValentine(commands.Cog): self, ctx: commands.Context, user: discord.Member, *, valentine_type: str = None ) -> None: """ - Send an anonymous Valentine via DM to to a user, if specified, or to a random with the lovefest role. + Send an anonymous Valentine via DM to to a specified user with the lovefest role. syntax : .bemyvalentine secret [user] [p/poem/c/compliment/or you can type your own valentine message] (optional) @@ -125,14 +125,17 @@ class BeMyValentine(commands.Cog): Iceman in DM making you anonymous) """ if Lovefest.role_id not in [role.id for role in user.roles]: - message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!" + message = f"You cannot send a valentine to {user} as they do not have the lovefest role!" await ctx.message.delete() - return await ctx.author.send(message) + try: + await ctx.author.send(message) + except discord.Forbidden: + await ctx.send(message) if user == ctx.author: # Well a user cant valentine himself/herself. await ctx.message.delete() - return await ctx.author.send('Come on dude, you cant send a valentine to yourself :expressionless:') + await ctx.send('Come on dude, you cant send a valentine to yourself :expressionless:') emoji_1, emoji_2 = self.random_emoji() valentine, title = self.valentine_check(valentine_type) -- cgit v1.2.3 From a1ba7e857ecfae6382afc6f7fd479a246d953d36 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 6 Feb 2021 09:09:25 +0530 Subject: Slight modifications to functionality of bemyvalentine secret and its messages --- bot/exts/valentines/be_my_valentine.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index 26966804..d5668738 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -95,7 +95,7 @@ class BeMyValentine(commands.Cog): if user == ctx.author: # Well a user can't valentine himself/herself. - await ctx.send("Come on dude, you can't send a valentine to yourself :expressionless:") + await ctx.send("Come on, you can't send a valentine to yourself :expressionless:") return emoji_1, emoji_2 = self.random_emoji() @@ -109,7 +109,7 @@ class BeMyValentine(commands.Cog): ) await channel.send(user.mention, embed=embed) - @commands.cooldown(1, 1800, BucketType.user) + # @commands.cooldown(1, 1800, BucketType.user) @send_valentine.command(name='secret') async def anonymous( self, ctx: commands.Context, user: discord.Member, *, valentine_type: str = None @@ -131,11 +131,12 @@ class BeMyValentine(commands.Cog): await ctx.author.send(message) except discord.Forbidden: await ctx.send(message) + return if user == ctx.author: # Well a user cant valentine himself/herself. - await ctx.message.delete() - await ctx.send('Come on dude, you cant send a valentine to yourself :expressionless:') + await ctx.send('Come on, you cant send a valentine to yourself :expressionless:') + return emoji_1, emoji_2 = self.random_emoji() valentine, title = self.valentine_check(valentine_type) -- cgit v1.2.3 From 4d8e0c205aaa4a8e47486cccbeee383b5d899191 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 6 Feb 2021 09:09:51 +0530 Subject: Remove debug code --- bot/exts/valentines/be_my_valentine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index d5668738..9ffa8769 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -109,7 +109,7 @@ class BeMyValentine(commands.Cog): ) await channel.send(user.mention, embed=embed) - # @commands.cooldown(1, 1800, BucketType.user) + @commands.cooldown(1, 1800, BucketType.user) @send_valentine.command(name='secret') async def anonymous( self, ctx: commands.Context, user: discord.Member, *, valentine_type: str = None -- cgit v1.2.3 From 24342ed41fea4079f464954fcaf873edcedabb07 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sat, 6 Feb 2021 09:11:38 +0530 Subject: Small grammar fix --- bot/exts/valentines/be_my_valentine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index 9ffa8769..d79b28e8 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -135,7 +135,7 @@ class BeMyValentine(commands.Cog): if user == ctx.author: # Well a user cant valentine himself/herself. - await ctx.send('Come on, you cant send a valentine to yourself :expressionless:') + await ctx.send('Come on, you can\'t send a valentine to yourself :expressionless:') return emoji_1, emoji_2 = self.random_emoji() -- cgit v1.2.3 From 0073e85b0adce4de6246a2e1013e3d84808de481 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Sun, 7 Feb 2021 00:39:09 +0300 Subject: Overhauls In Channel Check Upgrades in channel check to support categories, and in the case of overrides, roles too. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/__main__.py | 5 +-- bot/utils/decorators.py | 110 +++++++++++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 52 deletions(-) (limited to 'bot') diff --git a/bot/__main__.py b/bot/__main__.py index e9b14a53..c6e5fa57 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -6,10 +6,9 @@ from sentry_sdk.integrations.redis import RedisIntegration from bot.bot import bot from bot.constants import Client, GIT_SHA, STAFF_ROLES, WHITELISTED_CHANNELS -from bot.utils.decorators import in_channel_check +from bot.utils.decorators import whitelist_check from bot.utils.extensions import walk_extensions - sentry_logging = LoggingIntegration( level=logging.DEBUG, event_level=logging.WARNING @@ -26,7 +25,7 @@ sentry_sdk.init( log = logging.getLogger(__name__) -bot.add_check(in_channel_check(*WHITELISTED_CHANNELS, bypass_roles=STAFF_ROLES)) +bot.add_check(whitelist_check(channels=WHITELISTED_CHANNELS, roles=STAFF_ROLES)) for ext in walk_extensions(): bot.load_extension(ext) diff --git a/bot/utils/decorators.py b/bot/utils/decorators.py index 9cdaad3f..66b30b97 100644 --- a/bot/utils/decorators.py +++ b/bot/utils/decorators.py @@ -13,6 +13,7 @@ from discord.ext.commands import CheckFailure, Command, Context from bot.constants import ERROR_REPLIES, Month from bot.utils import human_months, resolve_current_month +from bot.utils.checks import in_whitelist_check ONE_DAY = 24 * 60 * 60 @@ -186,82 +187,93 @@ def without_role(*role_ids: int) -> t.Callable: return commands.check(predicate) -def in_channel_check(*channels: int, bypass_roles: t.Container[int] = None) -> t.Callable[[Context], bool]: +def whitelist_check(**default_kwargs: t.Container[int]) -> t.Callable[[Context], bool]: """ - Checks that the message is in a whitelisted channel or optionally has a bypass role. + Checks if a message is sent in a whitelisted context. - If `in_channel_override` is present, check if it contains channels - and use them in place of the global whitelist. + All arguments from `in_whitelist_check` are supported, with the exception of "fail_silently". + If `whitelist_override` is present, it is added to the global whitelist. """ def predicate(ctx: Context) -> bool: + # Skip DM invocations if not ctx.guild: log.debug(f"{ctx.author} tried to use the '{ctx.command.name}' command from a DM.") return True - if ctx.channel.id in channels: - log.debug( - f"{ctx.author} tried to call the '{ctx.command.name}' command " - f"and the command was used in a whitelisted channel." - ) - return True - if bypass_roles and any(r.id in bypass_roles for r in ctx.author.roles): - log.debug( - f"{ctx.author} called the '{ctx.command.name}' command and " - f"had a role to bypass the in_channel check." - ) - return True + kwargs = default_kwargs.copy() - if hasattr(ctx.command.callback, "in_channel_override"): - override = ctx.command.callback.in_channel_override - if override is None: + # Update kwargs based on override + if hasattr(ctx.command.callback, "override"): + # Remove default kwargs if reset is True + if ctx.command.callback.override_reset: + kwargs = {} log.debug( - f"{ctx.author} called the '{ctx.command.name}' command " - f"and the command was whitelisted to bypass the in_channel check." + f"{ctx.author} called the '{ctx.command.name}' command and " + f"overrode default checks." ) - return True - else: - if ctx.channel.id in override: - log.debug( - f"{ctx.author} tried to call the '{ctx.command.name}' command " - f"and the command was used in an overridden whitelisted channel." - ) - return True - log.debug( - f"{ctx.author} tried to call the '{ctx.command.name}' command. " - f"The overridden in_channel check failed." - ) - channels_str = ', '.join(f"<#{c_id}>" for c_id in override) - raise InChannelCheckFailure( - f"Sorry, but you may only use this command within {channels_str}." - ) + # Merge overwrites and defaults + for arg in ctx.command.callback.override: + default_value = kwargs.get(arg) + new_value = ctx.command.callback.override[arg] + + # Skip values that don't need merging, or can't be merged + if default_value is None or isinstance(arg, int): + kwargs[arg] = new_value + + # Merge containers + elif isinstance(default_value, t.Container): + if isinstance(new_value, t.Container): + kwargs[arg] = (*default_value, *new_value) + else: + kwargs[arg] = new_value + + log.debug( + f"Updated default check arguments for '{ctx.command.name}' " + f"invoked by {ctx.author}." + ) + + log.trace(f"Calling whitelist check for {ctx.author} for command {ctx.command.name}.") + result = in_whitelist_check(ctx, fail_silently=True, **kwargs) + + # Return if check passed + if result: + log.debug( + f"{ctx.author} tried to call the '{ctx.command.name}' command " + f"and the command was used in an overridden context." + ) + return result log.debug( f"{ctx.author} tried to call the '{ctx.command.name}' command. " - f"The in_channel check failed." - ) - - channels_str = ', '.join(f"<#{c_id}>" for c_id in channels) - raise InChannelCheckFailure( - f"Sorry, but you may only use this command within {channels_str}." + f"The whitelist check failed." ) - return predicate + # Raise error if the check did not pass + channels = kwargs.get("channels") + if channels: + channels_str = ', '.join(f"<#{c_id}>" for c_id in channels) + message = f"Sorry, but you may only use this command within {channels_str}." + else: + message = "Sorry, but you may not use this command." + raise InChannelCheckFailure(message) -in_channel = commands.check(in_channel_check) + return predicate -def override_in_channel(channels: t.Tuple[int] = None) -> t.Callable: +def whitelist_override(bypass_defaults: bool = False, **kwargs: t.Container[int]) -> t.Callable: """ - Set command callback attribute for detection in `in_channel_check`. + Override global whitelist context, with the kwargs specified. - Override global whitelist if channels are specified. + All arguments from `in_whitelist_check` are supported, with the exception of `fail_silently`. + Set `bypass_defaults` to True if you want to completely bypass global checks. This decorator has to go before (below) below the `command` decorator. """ def inner(func: t.Callable) -> t.Callable: - func.in_channel_override = channels + func.override = kwargs + func.override_reset = bypass_defaults return func return inner -- cgit v1.2.3 From 9e714107d3ebe6b5f17a9705cdb69aafd7e0a07d Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Sun, 7 Feb 2021 00:42:19 +0300 Subject: Switches To Whitelist Check Switches all instances of override_in_channel to whitelist override. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/christmas/advent_of_code/_cog.py | 20 ++++++++++---------- bot/exts/evergreen/conversationstarters.py | 4 ++-- bot/exts/halloween/hacktoberstats.py | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'bot') diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index c3b87f96..466edd48 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -11,7 +11,7 @@ from bot.constants import ( AdventOfCode as AocConfig, Channels, Colours, Emojis, Month, Roles, WHITELISTED_CHANNELS, ) from bot.exts.christmas.advent_of_code import _helpers -from bot.utils.decorators import InChannelCheckFailure, in_month, override_in_channel, with_role +from bot.utils.decorators import InChannelCheckFailure, in_month, whitelist_override, with_role log = logging.getLogger(__name__) @@ -50,7 +50,7 @@ class AdventOfCode(commands.Cog): self.status_task.add_done_callback(_helpers.background_task_callback) @commands.group(name="adventofcode", aliases=("aoc",)) - @override_in_channel(AOC_WHITELIST) + @whitelist_override(channels=AOC_WHITELIST) async def adventofcode_group(self, ctx: commands.Context) -> None: """All of the Advent of Code commands.""" if not ctx.invoked_subcommand: @@ -61,7 +61,7 @@ class AdventOfCode(commands.Cog): aliases=("sub", "notifications", "notify", "notifs"), brief="Notifications for new days" ) - @override_in_channel(AOC_WHITELIST) + @whitelist_override(channels=AOC_WHITELIST) async def aoc_subscribe(self, ctx: commands.Context) -> None: """Assign the role for notifications about new days being ready.""" current_year = datetime.now().year @@ -82,7 +82,7 @@ class AdventOfCode(commands.Cog): @in_month(Month.DECEMBER) @adventofcode_group.command(name="unsubscribe", aliases=("unsub",), brief="Notifications for new days") - @override_in_channel(AOC_WHITELIST) + @whitelist_override(channels=AOC_WHITELIST) async def aoc_unsubscribe(self, ctx: commands.Context) -> None: """Remove the role for notifications about new days being ready.""" role = ctx.guild.get_role(AocConfig.role_id) @@ -94,7 +94,7 @@ class AdventOfCode(commands.Cog): await ctx.send("Hey, you don't even get any notifications about new Advent of Code tasks currently anyway.") @adventofcode_group.command(name="countdown", aliases=("count", "c"), brief="Return time left until next day") - @override_in_channel(AOC_WHITELIST) + @whitelist_override(channels=AOC_WHITELIST) async def aoc_countdown(self, ctx: commands.Context) -> None: """Return time left until next day.""" if not _helpers.is_in_advent(): @@ -123,13 +123,13 @@ class AdventOfCode(commands.Cog): await ctx.send(f"There are {hours} hours and {minutes} minutes left until day {tomorrow.day}.") @adventofcode_group.command(name="about", aliases=("ab", "info"), brief="Learn about Advent of Code") - @override_in_channel(AOC_WHITELIST) + @whitelist_override(channels=AOC_WHITELIST) async def about_aoc(self, ctx: commands.Context) -> None: """Respond with an explanation of all things Advent of Code.""" await ctx.send("", embed=self.cached_about_aoc) @adventofcode_group.command(name="join", aliases=("j",), brief="Learn how to join the leaderboard (via DM)") - @override_in_channel(AOC_WHITELIST) + @whitelist_override(channels=AOC_WHITELIST) async def join_leaderboard(self, ctx: commands.Context) -> None: """DM the user the information for joining the Python Discord leaderboard.""" current_year = datetime.now().year @@ -178,7 +178,7 @@ class AdventOfCode(commands.Cog): aliases=("board", "lb"), brief="Get a snapshot of the PyDis private AoC leaderboard", ) - @override_in_channel(AOC_WHITELIST_RESTRICTED) + @whitelist_override(channels=AOC_WHITELIST_RESTRICTED) async def aoc_leaderboard(self, ctx: commands.Context) -> None: """Get the current top scorers of the Python Discord Leaderboard.""" async with ctx.typing(): @@ -203,7 +203,7 @@ class AdventOfCode(commands.Cog): aliases=("globalboard", "gb"), brief="Get a link to the global leaderboard", ) - @override_in_channel(AOC_WHITELIST_RESTRICTED) + @whitelist_override(channels=AOC_WHITELIST_RESTRICTED) async def aoc_global_leaderboard(self, ctx: commands.Context) -> None: """Get a link to the global Advent of Code leaderboard.""" url = self.global_leaderboard_url @@ -219,7 +219,7 @@ class AdventOfCode(commands.Cog): aliases=("dailystats", "ds"), brief="Get daily statistics for the Python Discord leaderboard" ) - @override_in_channel(AOC_WHITELIST_RESTRICTED) + @whitelist_override(channels=AOC_WHITELIST_RESTRICTED) async def private_leaderboard_daily_stats(self, ctx: commands.Context) -> None: """Send an embed with daily completion statistics for the Python Discord leaderboard.""" try: diff --git a/bot/exts/evergreen/conversationstarters.py b/bot/exts/evergreen/conversationstarters.py index 576b8d76..e7058961 100644 --- a/bot/exts/evergreen/conversationstarters.py +++ b/bot/exts/evergreen/conversationstarters.py @@ -5,7 +5,7 @@ from discord import Color, Embed from discord.ext import commands from bot.constants import WHITELISTED_CHANNELS -from bot.utils.decorators import override_in_channel +from bot.utils.decorators import whitelist_override from bot.utils.randomization import RandomCycle SUGGESTION_FORM = 'https://forms.gle/zw6kkJqv8U43Nfjg9' @@ -38,7 +38,7 @@ class ConvoStarters(commands.Cog): self.bot = bot @commands.command() - @override_in_channel(ALL_ALLOWED_CHANNELS) + @whitelist_override(channels=ALL_ALLOWED_CHANNELS) async def topic(self, ctx: commands.Context) -> None: """ Responds with a random topic to start a conversation. diff --git a/bot/exts/halloween/hacktoberstats.py b/bot/exts/halloween/hacktoberstats.py index a1c55922..d9fc0e8a 100644 --- a/bot/exts/halloween/hacktoberstats.py +++ b/bot/exts/halloween/hacktoberstats.py @@ -11,7 +11,7 @@ from async_rediscache import RedisCache from discord.ext import commands from bot.constants import Channels, Month, NEGATIVE_REPLIES, Tokens, WHITELISTED_CHANNELS -from bot.utils.decorators import in_month, override_in_channel +from bot.utils.decorators import in_month, whitelist_override log = logging.getLogger(__name__) @@ -44,7 +44,7 @@ class HacktoberStats(commands.Cog): @in_month(Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER) @commands.group(name="hacktoberstats", aliases=("hackstats",), invoke_without_command=True) - @override_in_channel(HACKTOBER_WHITELIST) + @whitelist_override(channels=HACKTOBER_WHITELIST) async def hacktoberstats_group(self, ctx: commands.Context, github_username: str = None) -> None: """ Display an embed for a user's Hacktoberfest contributions. @@ -72,7 +72,7 @@ class HacktoberStats(commands.Cog): @in_month(Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER) @hacktoberstats_group.command(name="link") - @override_in_channel(HACKTOBER_WHITELIST) + @whitelist_override(channels=HACKTOBER_WHITELIST) async def link_user(self, ctx: commands.Context, github_username: str = None) -> None: """ Link the invoking user's Github github_username to their Discord ID. @@ -96,7 +96,7 @@ class HacktoberStats(commands.Cog): @in_month(Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER) @hacktoberstats_group.command(name="unlink") - @override_in_channel(HACKTOBER_WHITELIST) + @whitelist_override(channels=HACKTOBER_WHITELIST) async def unlink_user(self, ctx: commands.Context) -> None: """Remove the invoking user's account link from the log.""" author_id, author_mention = self._author_mention_from_context(ctx) -- cgit v1.2.3 From ba439921a2164613ea7809cc006c621500bd727e Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Sun, 7 Feb 2021 09:42:24 +0300 Subject: Adds Whitelist Check To Cheat Sheet Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/evergreen/cheatsheet.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index 97485365..8e61f63e 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -8,8 +8,8 @@ from discord.ext import commands from discord.ext.commands import BucketType, Context from bot import constants -from bot.constants import Categories, Channels, Colours, ERROR_REPLIES, Roles, WHITELISTED_CHANNELS -from bot.utils.decorators import with_role +from bot.constants import Categories, Channels, Colours, ERROR_REPLIES +from bot.utils.decorators import whitelist_override ERROR_MESSAGE = f""" Unknown cheat sheet. Please try to reformulate your query. @@ -73,7 +73,7 @@ class CheatSheet(commands.Cog): aliases=("cht.sh", "cheatsheet", "cheat-sheet", "cht"), ) @commands.cooldown(1, 10, BucketType.user) - @with_role(Roles.everyone_role) + @whitelist_override(categories=[Categories.help_in_use]) async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: """ Search cheat.sh. @@ -82,12 +82,6 @@ class CheatSheet(commands.Cog): Usage: --> .cht read json """ - if not ( - ctx.channel.category.id == Categories.help_in_use - or ctx.channel.id in WHITELISTED_CHANNELS - ): - return - async with ctx.typing(): search_string = quote_plus(" ".join(search_terms)) -- cgit v1.2.3 From 73f11e22deda8bc25a03c75f3b7f380dd7f67f4e Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Sun, 7 Feb 2021 10:09:06 +0300 Subject: Adds Category Channels To Error Message Adds the channels within categories to the failure message of the command whitelist check. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/utils/decorators.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/utils/decorators.py b/bot/utils/decorators.py index 66b30b97..c12a15ff 100644 --- a/bot/utils/decorators.py +++ b/bot/utils/decorators.py @@ -250,7 +250,18 @@ def whitelist_check(**default_kwargs: t.Container[int]) -> t.Callable[[Context], ) # Raise error if the check did not pass - channels = kwargs.get("channels") + channels = set(kwargs.get("channels") or {}) + categories = kwargs.get("categories") + + # Add all whitelisted category channels + if categories: + for category_id in categories: + category = ctx.guild.get_channel(category_id) + if category is None: + continue + + [channels.add(channel.id) for channel in category.text_channels] + if channels: channels_str = ', '.join(f"<#{c_id}>" for c_id in channels) message = f"Sorry, but you may only use this command within {channels_str}." -- cgit v1.2.3 From 3242cc6c1dba0a0ecf3b5c0cdf5b90a4784dbfd1 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 8 Feb 2021 05:51:14 +0530 Subject: Add curl User Agent Headers --- bot/exts/evergreen/cheatsheet.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index 97485365..f6dce995 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -26,6 +26,7 @@ If the problem persists send a message in <#{Channels.dev_contrib}> URL = 'https://cheat.sh/python/{search}' ESCAPE_TT = str.maketrans({"`": "\\`"}) ANSI_RE = re.compile(r"\x1b\[.*?m") +HEADERS = {'User-Agent': 'curl/7.68.0'} class CheatSheet(commands.Cog): @@ -92,7 +93,7 @@ class CheatSheet(commands.Cog): search_string = quote_plus(" ".join(search_terms)) async with self.bot.http_session.get( - URL.format(search=search_string) + URL.format(search=search_string), headers=HEADERS ) as response: result = ANSI_RE.sub("", await response.text()).translate(ESCAPE_TT) -- cgit v1.2.3 From 8321add8d6a55132c96a620da2aac5c4bc44c284 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 8 Feb 2021 06:59:24 +0530 Subject: Use emojis library to do the check instead of checking len() == 1 since some emojis are made of len() > 1 --- Pipfile | 1 + Pipfile.lock | 55 ++++++++++++++++++++++---------------- bot/exts/evergreen/connect_four.py | 9 ++++--- 3 files changed, 39 insertions(+), 26 deletions(-) (limited to 'bot') diff --git a/Pipfile b/Pipfile index c382902f..e7e01a31 100644 --- a/Pipfile +++ b/Pipfile @@ -14,6 +14,7 @@ sentry-sdk = "~=0.19" PyYAML = "~=5.3.1" "discord.py" = {extras = ["voice"], version = "~=1.5.1"} async-rediscache = {extras = ["fakeredis"], version = "~=0.1.4"} +emojis = "~=0.6.0" [dev-packages] flake8 = "~=3.8" diff --git a/Pipfile.lock b/Pipfile.lock index be6f9574..cca89cf9 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9be419062bd9db364ac9dddfcd50aef9c932384b45850363e482591fe7d12403" + "sha256": "b4aaaacbab13179145e36d7b86c736db512286f6cce8e513cc30c48d68fe3810" }, "pipfile-spec": 6, "requires": { @@ -119,6 +119,7 @@ "sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009", "sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03", "sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b", + "sha256:7ef7d4ced6b325e92eb4d3502946c78c5367bc416398d387b39591532536734e", "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909", "sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53", "sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35", @@ -160,6 +161,14 @@ "index": "pypi", "version": "==1.5.1" }, + "emojis": { + "hashes": [ + "sha256:7da34c8a78ae262fd68cef9e2c78a3c1feb59784489eeea0f54ba1d4b7111c7c", + "sha256:bf605d1f1a27a81cd37fe82eb65781c904467f569295a541c33710b97e4225ec" + ], + "index": "pypi", + "version": "==0.6.0" + }, "fakeredis": { "hashes": [ "sha256:01cb47d2286825a171fb49c0e445b1fa9307087e07cbb3d027ea10dbff108b6a", @@ -229,11 +238,11 @@ }, "idna": { "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16", + "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.10" + "markers": "python_version >= '3.4'", + "version": "==3.1" }, "multidict": { "hashes": [ @@ -436,11 +445,11 @@ }, "urllib3": { "hashes": [ - "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08", - "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473" + "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", + "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.2" + "version": "==1.26.3" }, "yarl": { "hashes": [ @@ -514,11 +523,11 @@ }, "flake8-annotations": { "hashes": [ - "sha256:0bcebb0792f1f96d617ded674dca7bf64181870bfe5dace353a1483551f8e5f1", - "sha256:bebd11a850f6987a943ce8cdff4159767e0f5f89b3c88aca64680c2175ee02df" + "sha256:3a377140556aecf11fa9f3bb18c10db01f5ea56dc79a730e2ec9b4f1f49e2055", + "sha256:e17947a48a5b9f632fe0c72682fc797c385e451048e7dfb20139f448a074cb3e" ], "index": "pypi", - "version": "==2.4.1" + "version": "==2.5.0" }, "flake8-bugbear": { "hashes": [ @@ -576,11 +585,11 @@ }, "identify": { "hashes": [ - "sha256:943cd299ac7f5715fcb3f684e2fc1594c1e0f22a90d15398e5888143bd4144b5", - "sha256:cc86e6a9a390879dcc2976cef169dd9cc48843ed70b7380f321d1b118163c60e" + "sha256:70b638cf4743f33042bebb3b51e25261a0a10e80f978739f17e7fd4837664a66", + "sha256:9dfb63a2e871b807e3ba62f029813552a24b5289504f5b071dea9b041aee9fe4" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.10" + "version": "==1.5.13" }, "mccabe": { "hashes": [ @@ -606,11 +615,11 @@ }, "pre-commit": { "hashes": [ - "sha256:6c86d977d00ddc8a60d68eec19f51ef212d9462937acf3ea37c7adec32284ac0", - "sha256:ee784c11953e6d8badb97d19bc46b997a3a9eded849881ec587accd8608d74a4" + "sha256:16212d1fde2bed88159287da88ff03796863854b04dc9f838a55979325a3d20e", + "sha256:399baf78f13f4de82a29b649afd74bef2c4e28eb4f021661fc7f29246e8c7a3a" ], "index": "pypi", - "version": "==2.9.3" + "version": "==2.10.1" }, "pycodestyle": { "hashes": [ @@ -665,10 +674,10 @@ }, "snowballstemmer": { "hashes": [ - "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0", - "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52" + "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2", + "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914" ], - "version": "==2.0.0" + "version": "==2.1.0" }, "toml": { "hashes": [ @@ -680,11 +689,11 @@ }, "virtualenv": { "hashes": [ - "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c", - "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b" + "sha256:147b43894e51dd6bba882cf9c282447f780e2251cd35172403745fc381a0a80d", + "sha256:2be72df684b74df0ea47679a7df93fd0e04e72520022c57b479d8f881485dbe3" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.2" + "version": "==20.4.2" } } } diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index bf604e2a..02e876f4 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -4,6 +4,7 @@ import typing from functools import partial import discord +import emojis from discord.ext import commands NUMBERS = [ @@ -342,11 +343,13 @@ class ConnectFour(commands.Cog): return any(player in (game.player1, game.player2) for game in self.games) @staticmethod - def check_emojis(e1: EMOJI_CHECK, e2: EMOJI_CHECK) -> typing.Tuple[bool, typing.Optional[str]]: + def check_emojis( + e1: EMOJI_CHECK, e2: EMOJI_CHECK + ) -> typing.Tuple[bool, typing.Optional[str]]: """Validate the emojis, the user put.""" - if isinstance(e1, str) and len(e1) > 1: + if isinstance(e1, str) and emojis.count(e1) != 1: return False, e1 - if isinstance(e2, str) and len(e2) > 1: + if isinstance(e2, str) and emojis.count(e2) != 1: return False, e2 return True, None -- cgit v1.2.3 From af1d11067daf1304c3c166202c13d8373da9e9b7 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 8 Feb 2021 14:08:54 +0530 Subject: Add comment explaining why we need to pass curl as user agent --- bot/exts/evergreen/cheatsheet.py | 1 + 1 file changed, 1 insertion(+) (limited to 'bot') diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index f6dce995..a64ddd69 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -26,6 +26,7 @@ If the problem persists send a message in <#{Channels.dev_contrib}> URL = 'https://cheat.sh/python/{search}' ESCAPE_TT = str.maketrans({"`": "\\`"}) ANSI_RE = re.compile(r"\x1b\[.*?m") +# We need to pass headers as curl otherwise it would default to aiohttp which would return raw html. HEADERS = {'User-Agent': 'curl/7.68.0'} -- cgit v1.2.3 From 2f032a71beadd6c9613b89d525004c98a4cf6ab9 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Tue, 9 Feb 2021 11:41:28 +0100 Subject: Add location mocks to the wolfram cog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the server IP address could be leaked using some query such as “what is the weather here?” or simply “what’s my ip?”. This aims to fix it by using mock locations. --- bot/exts/evergreen/wolfram.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/wolfram.py b/bot/exts/evergreen/wolfram.py index 898e8d2a..d3b4df5c 100644 --- a/bot/exts/evergreen/wolfram.py +++ b/bot/exts/evergreen/wolfram.py @@ -108,7 +108,10 @@ async def get_pod_pages(ctx: Context, bot: commands.Bot, query: str) -> Optional "input": query, "appid": APPID, "output": DEFAULT_OUTPUT_FORMAT, - "format": "image,plaintext" + "format": "image,plaintext", + "location": "the moon", + "latlong": "0.0,0.0", + "ip": "1.1.1.1" }) request_url = QUERY.format(request="query", data=url_str) -- cgit v1.2.3 From 87c4066eb016dace5d48d87fba83ce6424408878 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Tue, 9 Feb 2021 12:22:26 +0100 Subject: Apply mock locations to every subcommands --- bot/exts/evergreen/wolfram.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'bot') diff --git a/bot/exts/evergreen/wolfram.py b/bot/exts/evergreen/wolfram.py index d3b4df5c..437d9e1a 100644 --- a/bot/exts/evergreen/wolfram.py +++ b/bot/exts/evergreen/wolfram.py @@ -171,6 +171,9 @@ class Wolfram(Cog): url_str = parse.urlencode({ "i": query, "appid": APPID, + "location": "the moon", + "latlong": "0.0,0.0", + "ip": "1.1.1.1" }) query = QUERY.format(request="simple", data=url_str) @@ -251,6 +254,9 @@ class Wolfram(Cog): url_str = parse.urlencode({ "i": query, "appid": APPID, + "location": "the moon", + "latlong": "0.0,0.0", + "ip": "1.1.1.1" }) query = QUERY.format(request="result", data=url_str) -- cgit v1.2.3 From 4c6d87c48bc44235a511f9266f986c219ac93f7e Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 13 Feb 2021 15:44:27 +0000 Subject: Raise user input error to reset cd --- bot/exts/valentines/be_my_valentine.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index d79b28e8..aac38edb 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -86,17 +86,17 @@ class BeMyValentine(commands.Cog): # This command should only be used in the server msg = "You are supposed to use this command in the server." await ctx.send(msg) - return + raise commands.UserInputError if Lovefest.role_id not in [role.id for role in user.roles]: message = f"You cannot send a valentine to {user} as they do not have the lovefest role!" await ctx.send(message) - return + raise commands.UserInputError if user == ctx.author: # Well a user can't valentine himself/herself. await ctx.send("Come on, you can't send a valentine to yourself :expressionless:") - return + raise commands.UserInputError emoji_1, emoji_2 = self.random_emoji() channel = self.bot.get_channel(Channels.community_bot_commands) @@ -131,12 +131,12 @@ class BeMyValentine(commands.Cog): await ctx.author.send(message) except discord.Forbidden: await ctx.send(message) - return + raise commands.UserInputError if user == ctx.author: # Well a user cant valentine himself/herself. await ctx.send('Come on, you can\'t send a valentine to yourself :expressionless:') - return + raise commands.UserInputError emoji_1, emoji_2 = self.random_emoji() valentine, title = self.valentine_check(valentine_type) @@ -151,6 +151,7 @@ class BeMyValentine(commands.Cog): await ctx.message.delete() except discord.Forbidden: await ctx.send(f"{user} has DMs disabled, so I couldn't send the message. Sorry!") + raise commands.UserInputError else: await ctx.author.send(f"Your message has been sent to {user}") -- cgit v1.2.3 From 8bc6f497d01d6b848ba868f4ac662100cdee48d3 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Sat, 13 Feb 2021 11:03:14 -0800 Subject: Added description and url to embed of xkcd command --- bot/exts/evergreen/xkcd.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index d3224bfe..43f05864 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -69,6 +69,8 @@ class XKCD(Cog): return embed.title = f"XKCD comic #{info['num']}" + embed.description = info['alt'] + embed.url = f"{BASE_URL}/{comic}" if info["img"][-3:] in ("jpg", "png", "gif"): embed.set_image(url=info["img"]) -- cgit v1.2.3 From 7343af2b3a3cd0d0333a16de0557435ba21ba7ce Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Sat, 13 Feb 2021 11:34:37 -0800 Subject: FIxed error in which link would 404 if user did .xkcd latest --- Pipfile.lock | 132 ++++++++++++++++++++++----------------------- bot/exts/evergreen/xkcd.py | 2 +- 2 files changed, 67 insertions(+), 67 deletions(-) (limited to 'bot') diff --git a/Pipfile.lock b/Pipfile.lock index be6f9574..bd894ffa 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -103,44 +103,45 @@ }, "cffi": { "hashes": [ - "sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e", - "sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d", - "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a", - "sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec", - "sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362", - "sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668", - "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c", - "sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b", - "sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06", - "sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698", - "sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2", - "sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c", - "sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7", - "sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009", - "sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03", - "sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b", - "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909", - "sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53", - "sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35", - "sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26", - "sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b", - "sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01", - "sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb", - "sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293", - "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd", - "sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d", - "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3", - "sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d", - "sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e", - "sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca", - "sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d", - "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775", - "sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375", - "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b", - "sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b", - "sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f" - ], - "version": "==1.14.4" + "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813", + "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06", + "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea", + "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee", + "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396", + "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73", + "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315", + "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1", + "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49", + "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892", + "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482", + "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058", + "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5", + "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53", + "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045", + "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3", + "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5", + "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e", + "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c", + "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369", + "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827", + "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053", + "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa", + "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4", + "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322", + "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132", + "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62", + "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa", + "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0", + "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396", + "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e", + "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991", + "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6", + "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1", + "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406", + "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d", + "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c" + ], + "version": "==1.14.5" }, "chardet": { "hashes": [ @@ -229,11 +230,11 @@ }, "idna": { "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16", + "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.10" + "markers": "python_version >= '3.4'", + "version": "==3.1" }, "multidict": { "hashes": [ @@ -405,11 +406,10 @@ }, "sentry-sdk": { "hashes": [ - "sha256:0a711ec952441c2ec89b8f5d226c33bc697914f46e876b44a4edd3e7864cf4d0", - "sha256:737a094e49a529dd0fdcaafa9e97cf7c3d5eb964bd229821d640bc77f3502b3f" + "sha256:3693cb47ba8d90c004ac002425770b32aaf0c83a846ec48e2d1364e7db1d072d" ], "index": "pypi", - "version": "==0.19.5" + "version": "==0.20.1" }, "six": { "hashes": [ @@ -428,19 +428,19 @@ }, "soupsieve": { "hashes": [ - "sha256:4bb21a6ee4707bf43b61230e80740e71bfe56e55d1f1f50924b087bb2975c851", - "sha256:6dc52924dc0bc710a5d16794e6b3480b2c7c08b07729505feab2b2c16661ff6e" + "sha256:407fa1e8eb3458d1b5614df51d9651a1180ea5fedf07feb46e45d7e25e6d6cdd", + "sha256:d3a5ea5b350423f47d07639f74475afedad48cf41c0ad7a82ca13a3928af34f6" ], "markers": "python_version >= '3.0'", - "version": "==2.1" + "version": "==2.2" }, "urllib3": { "hashes": [ - "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08", - "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473" + "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", + "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.2" + "version": "==1.26.3" }, "yarl": { "hashes": [ @@ -514,11 +514,11 @@ }, "flake8-annotations": { "hashes": [ - "sha256:0bcebb0792f1f96d617ded674dca7bf64181870bfe5dace353a1483551f8e5f1", - "sha256:bebd11a850f6987a943ce8cdff4159767e0f5f89b3c88aca64680c2175ee02df" + "sha256:3a377140556aecf11fa9f3bb18c10db01f5ea56dc79a730e2ec9b4f1f49e2055", + "sha256:e17947a48a5b9f632fe0c72682fc797c385e451048e7dfb20139f448a074cb3e" ], "index": "pypi", - "version": "==2.4.1" + "version": "==2.5.0" }, "flake8-bugbear": { "hashes": [ @@ -576,11 +576,11 @@ }, "identify": { "hashes": [ - "sha256:943cd299ac7f5715fcb3f684e2fc1594c1e0f22a90d15398e5888143bd4144b5", - "sha256:cc86e6a9a390879dcc2976cef169dd9cc48843ed70b7380f321d1b118163c60e" + "sha256:70b638cf4743f33042bebb3b51e25261a0a10e80f978739f17e7fd4837664a66", + "sha256:9dfb63a2e871b807e3ba62f029813552a24b5289504f5b071dea9b041aee9fe4" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.10" + "version": "==1.5.13" }, "mccabe": { "hashes": [ @@ -606,11 +606,11 @@ }, "pre-commit": { "hashes": [ - "sha256:6c86d977d00ddc8a60d68eec19f51ef212d9462937acf3ea37c7adec32284ac0", - "sha256:ee784c11953e6d8badb97d19bc46b997a3a9eded849881ec587accd8608d74a4" + "sha256:16212d1fde2bed88159287da88ff03796863854b04dc9f838a55979325a3d20e", + "sha256:399baf78f13f4de82a29b649afd74bef2c4e28eb4f021661fc7f29246e8c7a3a" ], "index": "pypi", - "version": "==2.9.3" + "version": "==2.10.1" }, "pycodestyle": { "hashes": [ @@ -665,10 +665,10 @@ }, "snowballstemmer": { "hashes": [ - "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0", - "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52" + "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2", + "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914" ], - "version": "==2.0.0" + "version": "==2.1.0" }, "toml": { "hashes": [ @@ -680,11 +680,11 @@ }, "virtualenv": { "hashes": [ - "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c", - "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b" + "sha256:147b43894e51dd6bba882cf9c282447f780e2251cd35172403745fc381a0a80d", + "sha256:2be72df684b74df0ea47679a7df93fd0e04e72520022c57b479d8f881485dbe3" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.2" + "version": "==20.4.2" } } } diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index 43f05864..1ff98ca2 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -70,7 +70,7 @@ class XKCD(Cog): embed.title = f"XKCD comic #{info['num']}" embed.description = info['alt'] - embed.url = f"{BASE_URL}/{comic}" + embed.url = f"{BASE_URL}/{info['num']}" if info["img"][-3:] in ("jpg", "png", "gif"): embed.set_image(url=info["img"]) -- cgit v1.2.3 From 2d33d53bf2c3a26e68abdcf2a2f91dac5bd495fc Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 13 Feb 2021 23:12:43 +0000 Subject: Output message in the same embed. --- bot/exts/valentines/be_my_valentine.py | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index aac38edb..fe52936b 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -84,19 +84,16 @@ class BeMyValentine(commands.Cog): """ if ctx.guild is None: # This command should only be used in the server - msg = "You are supposed to use this command in the server." - await ctx.send(msg) - raise commands.UserInputError + raise commands.UserInputError("You are supposed to use this command in the server.") if Lovefest.role_id not in [role.id for role in user.roles]: - message = f"You cannot send a valentine to {user} as they do not have the lovefest role!" - await ctx.send(message) - raise commands.UserInputError + raise commands.UserInputError( + f"You cannot send a valentine to {user} as they do not have the lovefest role!" + ) if user == ctx.author: # Well a user can't valentine himself/herself. - await ctx.send("Come on, you can't send a valentine to yourself :expressionless:") - raise commands.UserInputError + raise commands.UserInputError("Come on, you can't send a valentine to yourself :expressionless:") emoji_1, emoji_2 = self.random_emoji() channel = self.bot.get_channel(Channels.community_bot_commands) @@ -125,18 +122,14 @@ class BeMyValentine(commands.Cog): Iceman in DM making you anonymous) """ if Lovefest.role_id not in [role.id for role in user.roles]: - message = f"You cannot send a valentine to {user} as they do not have the lovefest role!" await ctx.message.delete() - try: - await ctx.author.send(message) - except discord.Forbidden: - await ctx.send(message) - raise commands.UserInputError + raise commands.UserInputError( + f"You cannot send a valentine to {user}> as they do not have the lovefest role!" + ) if user == ctx.author: # Well a user cant valentine himself/herself. - await ctx.send('Come on, you can\'t send a valentine to yourself :expressionless:') - raise commands.UserInputError + raise commands.UserInputError("Come on, you can't send a valentine to yourself :expressionless:") emoji_1, emoji_2 = self.random_emoji() valentine, title = self.valentine_check(valentine_type) @@ -146,12 +139,11 @@ class BeMyValentine(commands.Cog): description=f'{valentine} \n **{emoji_2}From anonymous{emoji_1}**', color=Colours.pink ) + await ctx.message.delete() try: await user.send(embed=embed) - await ctx.message.delete() except discord.Forbidden: - await ctx.send(f"{user} has DMs disabled, so I couldn't send the message. Sorry!") - raise commands.UserInputError + raise commands.UserInputError(f"{user} has DMs disabled, so I couldn't send the message. Sorry!") else: await ctx.author.send(f"Your message has been sent to {user}") -- cgit v1.2.3 From ab5e00d836a4c01c581a877c2dc992f3fa8d9243 Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 13 Feb 2021 23:16:48 +0000 Subject: Remove leftover > from testing. --- bot/exts/valentines/be_my_valentine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index fe52936b..f3392bcb 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -124,7 +124,7 @@ class BeMyValentine(commands.Cog): if Lovefest.role_id not in [role.id for role in user.roles]: await ctx.message.delete() raise commands.UserInputError( - f"You cannot send a valentine to {user}> as they do not have the lovefest role!" + f"You cannot send a valentine to {user} as they do not have the lovefest role!" ) if user == ctx.author: -- cgit v1.2.3 From 7ba7149c688ba35d60934fdc68b92b82862065c7 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Tue, 16 Feb 2021 09:10:57 -0800 Subject: Add .pyfacts command --- bot/exts/evergreen/pythonfacts.py | 23 +++++++++++++++++++++++ bot/resources/evergreen/python_facts.txt | 3 +++ 2 files changed, 26 insertions(+) create mode 100644 bot/exts/evergreen/pythonfacts.py create mode 100644 bot/resources/evergreen/python_facts.txt (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py new file mode 100644 index 00000000..ba792561 --- /dev/null +++ b/bot/exts/evergreen/pythonfacts.py @@ -0,0 +1,23 @@ +import random + +import discord +from discord.ext import commands +from discord.ext.commands.bot import Bot + + +class PythonFacts(commands.Cog): + """Gives a random fun fact about Python.""" + + def __init__(self, bot: Bot) -> None: + self.bot = bot + + @commands.command(name='pythonfact', aliases=['pyfact']) + async def get_python_fact(self, ctx: commands.Context) -> None: + """Gives a Random fun fact about Python.""" + with open('bot/resources/evergreen/python_facts.txt') as file: + await ctx.send(embed=discord.Embed(title='Python Facts', description=f'**{random.choice(list(file))}**')) + + +def setup(bot: commands.Bot) -> None: + """Adding the cog to the bot.""" + bot.add_cog(PythonFacts(bot)) diff --git a/bot/resources/evergreen/python_facts.txt b/bot/resources/evergreen/python_facts.txt new file mode 100644 index 00000000..d9e63a11 --- /dev/null +++ b/bot/resources/evergreen/python_facts.txt @@ -0,0 +1,3 @@ +Python was named after Monty Python, which Guido van Rossum likes. +If you type `import this` in the Python REPL, you'll get a poem about the philosophies about Python. (check it out by doing !zen in <#267659945086812160>) +If you type `import antigravity` in the Python REPL, you'll be directed to an [xkcd comic](https://xkcd.com/353/) about how easy Python is. -- cgit v1.2.3 From fdfa5c75b74a898512bfac6fa3ac14d452eae05d Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Tue, 16 Feb 2021 10:44:21 -0800 Subject: Remove unused import --- bot/exts/evergreen/pythonfacts.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index ba792561..b1c28d4b 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -2,13 +2,12 @@ import random import discord from discord.ext import commands -from discord.ext.commands.bot import Bot class PythonFacts(commands.Cog): """Gives a random fun fact about Python.""" - def __init__(self, bot: Bot) -> None: + def __init__(self, bot: commands.Bot) -> None: self.bot = bot @commands.command(name='pythonfact', aliases=['pyfact']) -- cgit v1.2.3 From 06d600f0fd927e566d23879638d10c6d66a63a21 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Tue, 16 Feb 2021 10:48:13 -0800 Subject: Move loading of file outside of command --- bot/exts/evergreen/pythonfacts.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index b1c28d4b..c6592add 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -4,6 +4,10 @@ import discord from discord.ext import commands +with open('bot/resources/evergreen/python_facts.txt') as file: + FACTS = list(file) + + class PythonFacts(commands.Cog): """Gives a random fun fact about Python.""" @@ -13,8 +17,7 @@ class PythonFacts(commands.Cog): @commands.command(name='pythonfact', aliases=['pyfact']) async def get_python_fact(self, ctx: commands.Context) -> None: """Gives a Random fun fact about Python.""" - with open('bot/resources/evergreen/python_facts.txt') as file: - await ctx.send(embed=discord.Embed(title='Python Facts', description=f'**{random.choice(list(file))}**')) + await ctx.send(embed=discord.Embed(title='Python Facts', description=f'**{random.choice(FACTS)}**')) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From 57aec016ac74465212744a9ec4173515dca98ba1 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon <74436682+MrKomodoDragon@users.noreply.github.com> Date: Tue, 16 Feb 2021 17:57:51 -0800 Subject: Remove bold Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/evergreen/pythonfacts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index c6592add..fcb78168 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -17,7 +17,7 @@ class PythonFacts(commands.Cog): @commands.command(name='pythonfact', aliases=['pyfact']) async def get_python_fact(self, ctx: commands.Context) -> None: """Gives a Random fun fact about Python.""" - await ctx.send(embed=discord.Embed(title='Python Facts', description=f'**{random.choice(FACTS)}**')) + await ctx.send(embed=discord.Embed(title='Python Facts', description=random.choice(FACTS))) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From a68e8f558cfee18bdb04c9e9a07cc9d293bd6c71 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon <74436682+MrKomodoDragon@users.noreply.github.com> Date: Tue, 16 Feb 2021 17:58:31 -0800 Subject: Update docstring for Cog Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/evergreen/pythonfacts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index fcb78168..dbc38ef4 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -21,5 +21,5 @@ class PythonFacts(commands.Cog): def setup(bot: commands.Bot) -> None: - """Adding the cog to the bot.""" + """Load PythonFacts Cog.""" bot.add_cog(PythonFacts(bot)) -- cgit v1.2.3 From 6aae339f33ee471bafe9338db5046b774c6b4aad Mon Sep 17 00:00:00 2001 From: MrKomodoDragon <74436682+MrKomodoDragon@users.noreply.github.com> Date: Tue, 16 Feb 2021 18:03:31 -0800 Subject: Change Docstring for command Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/evergreen/pythonfacts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index dbc38ef4..c0cdf111 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -16,7 +16,7 @@ class PythonFacts(commands.Cog): @commands.command(name='pythonfact', aliases=['pyfact']) async def get_python_fact(self, ctx: commands.Context) -> None: - """Gives a Random fun fact about Python.""" + """Sends a Random fun fact about Python.""" await ctx.send(embed=discord.Embed(title='Python Facts', description=random.choice(FACTS))) -- cgit v1.2.3 From 5164ba4e367efbfe78f8dd2b08646fe6605a8b42 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Tue, 16 Feb 2021 18:21:12 -0800 Subject: Add colors and move embed out of send statement; add more info about Monty Python for Fact 1 --- bot/exts/evergreen/pythonfacts.py | 7 +++++-- bot/resources/evergreen/python_facts.txt | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index c0cdf111..734782b8 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -7,9 +7,11 @@ from discord.ext import commands with open('bot/resources/evergreen/python_facts.txt') as file: FACTS = list(file) +COLORS = [0x4B8BBE, 0xFFD43B, ] + class PythonFacts(commands.Cog): - """Gives a random fun fact about Python.""" + """Sends a random fun fact about Python.""" def __init__(self, bot: commands.Bot) -> None: self.bot = bot @@ -17,7 +19,8 @@ class PythonFacts(commands.Cog): @commands.command(name='pythonfact', aliases=['pyfact']) async def get_python_fact(self, ctx: commands.Context) -> None: """Sends a Random fun fact about Python.""" - await ctx.send(embed=discord.Embed(title='Python Facts', description=random.choice(FACTS))) + embed = discord.Embed(title='Python Facts', description=random.choice(FACTS), colour=random.choice(COLORS)) + await ctx.send(embed=embed) def setup(bot: commands.Bot) -> None: diff --git a/bot/resources/evergreen/python_facts.txt b/bot/resources/evergreen/python_facts.txt index d9e63a11..0abd971b 100644 --- a/bot/resources/evergreen/python_facts.txt +++ b/bot/resources/evergreen/python_facts.txt @@ -1,3 +1,3 @@ -Python was named after Monty Python, which Guido van Rossum likes. +Python was named after Monty Python, a British Comedy Troupe, which Guido van Rossum likes. If you type `import this` in the Python REPL, you'll get a poem about the philosophies about Python. (check it out by doing !zen in <#267659945086812160>) If you type `import antigravity` in the Python REPL, you'll be directed to an [xkcd comic](https://xkcd.com/353/) about how easy Python is. -- cgit v1.2.3 From 7bc0ea474ed39dbddca3958bb90fc072f0d7aa1d Mon Sep 17 00:00:00 2001 From: Arez1337 <> Date: Sat, 20 Feb 2021 20:43:59 +0100 Subject: Removed the Question about the Nile and changed the IDs to matc the order again --- bot/resources/evergreen/trivia_quiz.json | 57 ++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'bot') diff --git a/bot/resources/evergreen/trivia_quiz.json b/bot/resources/evergreen/trivia_quiz.json index faa3bc3b..a4225eb1 100644 --- a/bot/resources/evergreen/trivia_quiz.json +++ b/bot/resources/evergreen/trivia_quiz.json @@ -2,36 +2,51 @@ "retro": [ { "id": 1, - "hints": ["It is not a mainline Mario Game, although the plumber is present.", "It is not a mainline Zelda Game, although Link is present."], + "hints": [ + "It is not a mainline Mario Game, although the plumber is present.", + "It is not a mainline Zelda Game, although Link is present." + ], "question": "What is the best selling game on the Nintendo GameCube?", "answer": "Super Smash Bros" }, { "id": 2, - "hints": ["It was released before the 90's.", "It was released after 1980."], + "hints": [ + "It was released before the 90's.", + "It was released after 1980." + ], "question": "What year was Tetris released?", "answer": "1984" }, { "id": 3, - "hints": ["The occupation was in construction", "He appeared as this kind of worker in 1981's Donkey Kong"], + "hints": [ + "The occupation was in construction", + "He appeared as this kind of worker in 1981's Donkey Kong" + ], "question": "What was Mario's original occupation?", "answer": "Carpenter" }, { "id": 4, - "hints": ["It was revealed in the Nintendo Character Guide in 1993.", "His last name has to do with eating Mario's enemies."], + "hints": [ + "It was revealed in the Nintendo Character Guide in 1993.", + "His last name has to do with eating Mario's enemies." + ], "question": "What is Yoshi's (from Mario Bros.) full name?", "answer": "Yoshisaur Munchakoopas" }, { "id": 5, - "hints": ["The game was released in 1990.", "It was released on the SNES."], + "hints": [ + "The game was released in 1990.", + "It was released on the SNES." + ], "question": "What was the first game Yoshi appeared in?", "answer": "Super Mario World" } ], - "general":[ + "general": [ { "id": 100, "question": "Name \"the land of a thousand lakes\"", @@ -114,7 +129,7 @@ "id": 113, "question": "What's the name of the tallest waterfall in the world.", "answer": "Angel Falls", - "info": "Angel Falls (Salto Ángel) in Venezuela is the highest waterfall in the world. The falls are 3230 feet in height, with an uninterrupted drop of 2647 feet. Angel Falls is located on a tributary of the Rio Caroni." + "info": "Angel Falls (Salto \u00c1ngel) in Venezuela is the highest waterfall in the world. The falls are 3230 feet in height, with an uninterrupted drop of 2647 feet. Angel Falls is located on a tributary of the Rio Caroni." }, { "id": 114, @@ -180,7 +195,7 @@ "id": 124, "question": "When did the Second World War end?", "answer": "1945", - "info": "World War 2 ended with the unconditional surrender of the Axis powers. On 8 May 1945, the Allies accepted Germany's surrender, about a week after Adolf Hitler had committed suicide. VE Day – Victory in Europe celebrates the end of the Second World War on 8 May 1945." + "info": "World War 2 ended with the unconditional surrender of the Axis powers. On 8 May 1945, the Allies accepted Germany's surrender, about a week after Adolf Hitler had committed suicide. VE Day \u2013 Victory in Europe celebrates the end of the Second World War on 8 May 1945." }, { "id": 125, @@ -190,72 +205,66 @@ }, { "id": 126, - "question": "What's the name of the largest river in the world?", - "answer": "Nile", - "info": "The Nile, which is about 6,650 km (4,130 mi) long, is an \"international\" river as its drainage basin covers eleven countries, namely, Tanzania, Uganda, Rwanda, Burundi, the Democratic Republic of the Congo, Kenya, Ethiopia, Eritrea, South Sudan, Republic of the Sudan and Egypt." - }, - { - "id": 127, "question": "Which is the smallest planet in the Solar System?", "answer": "Mercury", "info": "Mercury is the smallest planet in our solar system. It's just a little bigger than Earth's moon. It is the closest planet to the sun, but it's actually not the hottest. Venus is hotter." }, { - "id": 128, + "id": 127, "question": "What is the smallest country?", "answer": "Vatican City", "info": "With an area of 0.17 square miles (0.44 km2) and a population right around 1,000, Vatican City is the smallest country in the world, both in terms of size and population." }, { - "id": 129, + "id": 128, "question": "What's the name of the largest bird?", "answer": "Ostrich", "info": "The largest living bird, a member of the Struthioniformes, is the ostrich (Struthio camelus), from the plains of Africa and Arabia. A large male ostrich can reach a height of 2.8 metres (9.2 feet) and weigh over 156 kilograms (344 pounds)." }, { - "id": 130, + "id": 129, "question": "What does the acronym GPRS stand for?", "answer": "General Packet Radio Service", "info": "General Packet Radio Service (GPRS) is a packet-based mobile data service on the global system for mobile communications (GSM) of 3G and 2G cellular communication systems. It is a non-voice, high-speed and useful packet-switching technology intended for GSM networks." }, { - "id": 131, + "id": 130, "question": "In what country is the Ebro river located?", "answer": "Spain", "info": "The Ebro river is located in Spain. It is 930 kilometers long and it's the second longest river that ends on the Mediterranean Sea." }, { - "id": 132, + "id": 131, "question": "What year was the IBM PC model 5150 introduced into the market?", "answer": "1981", "info": "The IBM PC was introduced into the market in 1981. It used the Intel 8088, with a clock speed of 4.77 MHz, along with the MDA and CGA as a video card." }, { - "id": 133, + "id": 132, "question": "What's the world's largest urban area?", "answer": "Tokyo", "info": "Tokyo is the most populated city in the world, with a population of 37 million people. It is located in Japan." }, { - "id": 134, + "id": 133, "question": "How many planets are there in the Solar system?", "answer": "8", "info": "In the Solar system, there are 8 planets: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune. Pluto isn't considered a planet in the Solar System anymore." }, { - "id": 135, + "id": 134, "question": "What is the capital of Iraq?", "answer": "Baghdad", "info": "Baghdad is the capital of Iraq. It has a population of 7 million people." }, { - "id": 136, + "id": 135, "question": "The United Nations headquarters is located at which city?", "answer": "New York", "info": "The United Nations is headquartered in New York City in a complex designed by a board of architects led by Wallace Harrison and built by the architectural firm Harrison & Abramovitz. The complex has served as the official headquarters of the United Nations since its completion in 1951." }, { - "id": 137, + "id": 136, "question": "At what year did Christopher Columbus discover America?", "answer": "1492", "info": "The explorer Christopher Columbus made four trips across the Atlantic Ocean from Spain: in 1492, 1493, 1498 and 1502. He was determined to find a direct water route west from Europe to Asia, but he never did. Instead, he stumbled upon the Americas" -- cgit v1.2.3 From 8cdd0b337fadc7085638517af5e8a7474ea3271c Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 22 Feb 2021 20:40:10 +0530 Subject: Improve wikipedia command to send a snippet of wikipedia article and use pagination instead of asking user for input --- bot/exts/evergreen/wikipedia.py | 168 ++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 92 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/wikipedia.py b/bot/exts/evergreen/wikipedia.py index be36e2c4..0d100d90 100644 --- a/bot/exts/evergreen/wikipedia.py +++ b/bot/exts/evergreen/wikipedia.py @@ -1,114 +1,98 @@ -import asyncio -import datetime import logging +import re +from datetime import datetime +from enum import Enum +from html import unescape from typing import List, Optional -from aiohttp import client_exceptions -from discord import Color, Embed, Message +from discord import Color, Embed from discord.ext import commands -from bot.constants import Wikipedia +from bot.bot import Bot +from bot.utils import LinePaginator log = logging.getLogger(__name__) -SEARCH_API = "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch={search_term}&format=json" -WIKIPEDIA_URL = "https://en.wikipedia.org/wiki/{title}" +SEARCH_API = "https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&inprop=url&utf8=& \ + format=json&origin=*&srlimit={number_of_results}&srsearch={string}" +WIKI_THUMBNAIL = "https://upload.wikimedia.org/wikipedia/en/thumb/8/80/Wikipedia-logo-v2.svg" \ + "/330px-Wikipedia-logo-v2.svg.png" +WIKI_SNIPPET_REGEX = r'(|<[^>]*>)' +WIKI_SEARCH_RESULT = ( + "**[{name}]({url})**\n" + "{description}\n" +) -class WikipediaSearch(commands.Cog): - """Get info from wikipedia.""" +class WikipediaSearchErrors(Enum): + """Errors returned in wikipedia search function.""" - def __init__(self, bot: commands.Bot): - self.bot = bot - self.http_session = bot.http_session + no_results = "Sorry, we could not find a wikipedia article using that search term." + api_issue = "Whoops, the Wikipedia API is having some issues right now. Try again later." - @staticmethod - def formatted_wiki_url(index: int, title: str) -> str: - """Formating wikipedia link with index and title.""" - return f'`{index}` [{title}]({WIKIPEDIA_URL.format(title=title.replace(" ", "_"))})' - async def search_wikipedia(self, search_term: str) -> Optional[List[str]]: - """Search wikipedia and return the first 10 pages found.""" - pages = [] - async with self.http_session.get(SEARCH_API.format(search_term=search_term)) as response: - try: - data = await response.json() +class WikipediaSearch(commands.Cog): + """Get info from wikipedia.""" - search_results = data["query"]["search"] + def __init__(self, bot: Bot): + self.bot = bot - # Ignore pages with "may refer to" - for search_result in search_results: - log.info("trying to append titles") - if "may refer to" not in search_result["snippet"]: - pages.append(search_result["title"]) - except client_exceptions.ContentTypeError: - pages = None + async def wiki_request(self, ctx: commands.Context, search: str) -> Optional[List[str]]: + """Search wikipedia search string and return formatted first 10 pages found.""" + url = SEARCH_API.format(number_of_results=10, string=search) + async with self.bot.http_session.get(url=url) as resp: + if resp.status == 200: + raw_data = await resp.json() + number_of_results = raw_data['query']['searchinfo']['totalhits'] + + if number_of_results: + results = raw_data['query']['search'] + lines = [] + + for article in results: + formatting = { + 'name': article['title'], + 'description': unescape( + re.sub( + WIKI_SNIPPET_REGEX, '', article['snippet'] + ) + ), + 'url': f"https://en.wikipedia.org/?curid={article['pageid']}" + } + line = WIKI_SEARCH_RESULT.format(**formatting) + lines.append(line) + + return lines - log.info("Finished appending titles") - return pages + else: + await ctx.send( + WikipediaSearchErrors.no_results.value + ) + return None + else: + await ctx.send( + WikipediaSearchErrors.api_issue.value + ) + return None @commands.cooldown(1, 10, commands.BucketType.user) @commands.command(name="wikipedia", aliases=["wiki"]) async def wikipedia_search_command(self, ctx: commands.Context, *, search: str) -> None: - """Return list of results containing your search query from wikipedia.""" - titles = await self.search_wikipedia(search) - - def check(message: Message) -> bool: - return message.author.id == ctx.author.id and message.channel == ctx.channel - - if not titles: - await ctx.send("Sorry, we could not find a wikipedia article using that search term") - return - - async with ctx.typing(): - log.info("Finished appending titles to titles_no_underscore list") - - s_desc = "\n".join(self.formatted_wiki_url(index, title) for index, title in enumerate(titles, start=1)) - embed = Embed(colour=Color.blue(), title=f"Wikipedia results for `{search}`", description=s_desc) - embed.timestamp = datetime.datetime.utcnow() - await ctx.send(embed=embed) - embed = Embed(colour=Color.green(), description="Enter number to choose") - msg = await ctx.send(embed=embed) - titles_len = len(titles) # getting length of list - - for retry_count in range(1, Wikipedia.total_chance + 1): - retries_left = Wikipedia.total_chance - retry_count - if retry_count < Wikipedia.total_chance: - error_msg = f"You have `{retries_left}/{Wikipedia.total_chance}` chances left" - else: - error_msg = 'Please try again by using `.wiki` command' - try: - message = await ctx.bot.wait_for('message', timeout=60.0, check=check) - response_from_user = await self.bot.get_context(message) - - if response_from_user.command: - return - - response = int(message.content) - if response < 0: - await ctx.send(f"Sorry, but you can't give negative index, {error_msg}") - elif response == 0: - await ctx.send(f"Sorry, please give an integer between `1` to `{titles_len}`, {error_msg}") - else: - await ctx.send(WIKIPEDIA_URL.format(title=titles[response - 1].replace(" ", "_"))) - break - - except asyncio.TimeoutError: - embed = Embed(colour=Color.red(), description=f"Time's up {ctx.author.mention}") - await msg.edit(embed=embed) - break - - except ValueError: - await ctx.send(f"Sorry, but you cannot do that, I will only accept an positive integer, {error_msg}") - - except IndexError: - await ctx.send(f"Sorry, please give an integer between `1` to `{titles_len}`, {error_msg}") - - except Exception as e: - log.info(f"Caught exception {e}, breaking out of retry loop") - break - - -def setup(bot: commands.Bot) -> None: + """Sends paginated top 10 results of Wikipedia search..""" + contents = await self.wiki_request(ctx, search) + + if contents: + embed = Embed( + title="Wikipedia Search Results", + colour=Color.blurple() + ) + embed.set_thumbnail(url=WIKI_THUMBNAIL) + embed.timestamp = datetime.utcnow() + await LinePaginator.paginate( + contents, ctx, embed + ) + + +def setup(bot: Bot) -> None: """Wikipedia Cog load.""" bot.add_cog(WikipediaSearch(bot)) -- cgit v1.2.3 From 86dc294eb22f233ccd381529a8191d2285889784 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 22 Feb 2021 20:40:56 +0530 Subject: Goodbye Wikipedia Class, no need of you anymore --- bot/constants.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'bot') diff --git a/bot/constants.py b/bot/constants.py index bb538487..c31cd958 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -281,10 +281,6 @@ class RedisConfig(NamedTuple): use_fakeredis = environ.get("USE_FAKEREDIS", "false").lower() == "true" -class Wikipedia: - total_chance = 3 - - class Source: github = "https://github.com/python-discord/sir-lancebot" github_avatar_url = "https://avatars1.githubusercontent.com/u/9919" -- cgit v1.2.3 From 16476ab7b4d5efe36a9e101b382f7be24888dec5 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Mon, 22 Feb 2021 11:13:01 -0800 Subject: Switch to itertools.cycle and add colors to constants.py --- bot/constants.py | 2 ++ bot/exts/evergreen/pythonfacts.py | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/constants.py b/bot/constants.py index bb538487..3aec6ba3 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -156,6 +156,8 @@ class Colours: soft_orange = 0xf9cb54 soft_red = 0xcd6d6d yellow = 0xf9f586 + python_blue = 0x4B8BBE + python_yellow = 0xFFD43B class Emojis: diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index 734782b8..8e6d300b 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -1,13 +1,16 @@ -import random +import itertools import discord from discord.ext import commands +from bot.constants import Colours with open('bot/resources/evergreen/python_facts.txt') as file: FACTS = list(file) + FACT_CYCLE = itertools.cycle(FACTS) -COLORS = [0x4B8BBE, 0xFFD43B, ] +COLORS = [Colours.python_blue, Colours.python_yellow] +COLOR_CYCLE = itertools.cycle(COLORS) class PythonFacts(commands.Cog): @@ -19,7 +22,7 @@ class PythonFacts(commands.Cog): @commands.command(name='pythonfact', aliases=['pyfact']) async def get_python_fact(self, ctx: commands.Context) -> None: """Sends a Random fun fact about Python.""" - embed = discord.Embed(title='Python Facts', description=random.choice(FACTS), colour=random.choice(COLORS)) + embed = discord.Embed(title='Python Facts', description=next(FACT_CYCLE), colour=next(COLOR_CYCLE)) await ctx.send(embed=embed) -- cgit v1.2.3 From fa9e205338429def46b1c962138eda52c44ba824 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 23 Feb 2021 12:06:59 +0530 Subject: Add log.info() statement if the wikipedia api request status code is not 200 --- bot/exts/evergreen/wikipedia.py | 1 + 1 file changed, 1 insertion(+) (limited to 'bot') diff --git a/bot/exts/evergreen/wikipedia.py b/bot/exts/evergreen/wikipedia.py index 0d100d90..0b64136f 100644 --- a/bot/exts/evergreen/wikipedia.py +++ b/bot/exts/evergreen/wikipedia.py @@ -70,6 +70,7 @@ class WikipediaSearch(commands.Cog): ) return None else: + log.info(f"Unexpected response `{resp.status}` while searching wikipedia for `{search}`") await ctx.send( WikipediaSearchErrors.api_issue.value ) -- cgit v1.2.3 From 13dad6bf796a6009db4ff768795a3d45d044ff0e Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 23 Feb 2021 16:46:08 +0530 Subject: Fix pipfile conflicts, and add/use emojis from constants.py --- Pipfile.lock | 21 +++++++++++++++------ bot/constants.py | 5 ++++- bot/exts/evergreen/connect_four.py | 37 +++++++++---------------------------- 3 files changed, 28 insertions(+), 35 deletions(-) (limited to 'bot') diff --git a/Pipfile.lock b/Pipfile.lock index bd894ffa..ec801979 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9be419062bd9db364ac9dddfcd50aef9c932384b45850363e482591fe7d12403" + "sha256": "b4aaaacbab13179145e36d7b86c736db512286f6cce8e513cc30c48d68fe3810" }, "pipfile-spec": 6, "requires": { @@ -161,6 +161,14 @@ "index": "pypi", "version": "==1.5.1" }, + "emojis": { + "hashes": [ + "sha256:7da34c8a78ae262fd68cef9e2c78a3c1feb59784489eeea0f54ba1d4b7111c7c", + "sha256:bf605d1f1a27a81cd37fe82eb65781c904467f569295a541c33710b97e4225ec" + ], + "index": "pypi", + "version": "==0.6.0" + }, "fakeredis": { "hashes": [ "sha256:01cb47d2286825a171fb49c0e445b1fa9307087e07cbb3d027ea10dbff108b6a", @@ -406,10 +414,11 @@ }, "sentry-sdk": { "hashes": [ - "sha256:3693cb47ba8d90c004ac002425770b32aaf0c83a846ec48e2d1364e7db1d072d" + "sha256:4ae8d1ced6c67f1c8ea51d82a16721c166c489b76876c9f2c202b8a50334b237", + "sha256:e75c8c58932bda8cd293ea8e4b242527129e1caaec91433d21b8b2f20fee030b" ], "index": "pypi", - "version": "==0.20.1" + "version": "==0.20.3" }, "six": { "hashes": [ @@ -576,11 +585,11 @@ }, "identify": { "hashes": [ - "sha256:70b638cf4743f33042bebb3b51e25261a0a10e80f978739f17e7fd4837664a66", - "sha256:9dfb63a2e871b807e3ba62f029813552a24b5289504f5b071dea9b041aee9fe4" + "sha256:de7129142a5c86d75a52b96f394d94d96d497881d2aaf8eafe320cdbe8ac4bcc", + "sha256:e0dae57c0397629ce13c289f6ddde0204edf518f557bfdb1e56474aa143e77c3" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.13" + "version": "==1.5.14" }, "mccabe": { "hashes": [ diff --git a/bot/constants.py b/bot/constants.py index bb538487..682ccf6f 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -165,6 +165,7 @@ class Emojis: envelope = "\U0001F4E8" trashcan = "<:trashcan:637136429717389331>" ok_hand = ":ok_hand:" + hand_raised = "\U0001f64b" dice_1 = "<:dice_1:755891608859443290>" dice_2 = "<:dice_2:755891608741740635>" @@ -179,7 +180,6 @@ class Emojis: pull_request_closed = "<:PRClosed:629695470519713818>" merge = "<:PRMerged:629695470570176522>" - # TicTacToe Emojis number_emojis = { 1: "\u0031\ufe0f\u20e3", 2: "\u0032\ufe0f\u20e3", @@ -191,8 +191,11 @@ class Emojis: 8: "\u0038\ufe0f\u20e3", 9: "\u0039\ufe0f\u20e3" } + confirmation = "\u2705" decline = "\u274c" + incident_unactioned = "<:incident_unactioned:719645583245180960>" + x = "\U0001f1fd" o = "\U0001f1f4" diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 02e876f4..65458dbc 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -7,30 +7,11 @@ import discord import emojis from discord.ext import commands -NUMBERS = [ - ":one:", - ":two:", - ":three:", - ":four:", - ":five:", - ":six:", - ":seven:", - ":eight:", - ":nine:" -] -UNICODE_NUMBERS = [ - "\u0031\u20e3", - "\u0032\u20e3", - "\u0033\u20e3", - "\u0034\u20e3", - "\u0035\u20e3", - "\u0036\u20e3", - "\u0037\u20e3", - "\u0038\u20e3", - "\u0039\u20e3", -] -CROSS_EMOJI = "\u274e" -HAND_RAISED_EMOJI = "\U0001f64b" +from bot.constants import Emojis + +NUMBERS = list(Emojis.number_emojis.values()) +CROSS_EMOJI = Emojis.incident_unactioned + Coordinate = typing.Optional[typing.Tuple[int, int]] EMOJI_CHECK = typing.Union[discord.Emoji, str] @@ -57,7 +38,7 @@ class Game: self.grid = self.generate_board(size) self.grid_size = size - self.unicode_numbers = UNICODE_NUMBERS[:self.grid_size] + self.unicode_numbers = NUMBERS[:self.grid_size] self.message = None @@ -313,7 +294,7 @@ class ConnectFour(commands.Cog): if ( user.id not in (ctx.me.id, ctx.author.id) - and str(reaction.emoji) == HAND_RAISED_EMOJI + and str(reaction.emoji) == Emojis.hand_raised and reaction.message.id == announcement.id ): if self.already_playing(user): @@ -406,11 +387,11 @@ class ConnectFour(commands.Cog): announcement = await ctx.send( "**Connect Four**: A new game is about to start!\n" - f"Press {HAND_RAISED_EMOJI} to play against {ctx.author.mention}!\n" + f"Press {Emojis.hand_raised} to play against {ctx.author.mention}!\n" f"(Cancel the game with {CROSS_EMOJI}.)" ) self.waiting.append(ctx.author) - await announcement.add_reaction(HAND_RAISED_EMOJI) + await announcement.add_reaction(Emojis.hand_raised) await announcement.add_reaction(CROSS_EMOJI) try: -- cgit v1.2.3 From aef25cb560eb525305c583a8ff2834b503cb91d4 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Tue, 23 Feb 2021 09:03:05 -0800 Subject: Remove unused variables --- bot/exts/evergreen/pythonfacts.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index 8e6d300b..11b258f9 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -6,11 +6,9 @@ from discord.ext import commands from bot.constants import Colours with open('bot/resources/evergreen/python_facts.txt') as file: - FACTS = list(file) - FACT_CYCLE = itertools.cycle(FACTS) + FACTS = itertools.cycle(list(file)) -COLORS = [Colours.python_blue, Colours.python_yellow] -COLOR_CYCLE = itertools.cycle(COLORS) +COLORS = itertools.cycle([Colours.python_blue, Colours.python_yellow]) class PythonFacts(commands.Cog): @@ -22,7 +20,7 @@ class PythonFacts(commands.Cog): @commands.command(name='pythonfact', aliases=['pyfact']) async def get_python_fact(self, ctx: commands.Context) -> None: """Sends a Random fun fact about Python.""" - embed = discord.Embed(title='Python Facts', description=next(FACT_CYCLE), colour=next(COLOR_CYCLE)) + embed = discord.Embed(title='Python Facts', description=next(FACTS), colour=next(COLORS)) await ctx.send(embed=embed) -- cgit v1.2.3 From b70a3fb551600fc34ea4d9e5111957149dceb1a2 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Wed, 24 Feb 2021 17:28:08 +0530 Subject: Make connect 4 and its sub command ai guild only --- bot/exts/evergreen/connect_four.py | 3 + bot/exts/evergreen/error_handler.py | 129 ------------------------------------ 2 files changed, 3 insertions(+), 129 deletions(-) delete mode 100644 bot/exts/evergreen/error_handler.py (limited to 'bot') diff --git a/bot/exts/evergreen/connect_four.py b/bot/exts/evergreen/connect_four.py index 65458dbc..7e3ec42b 100644 --- a/bot/exts/evergreen/connect_four.py +++ b/bot/exts/evergreen/connect_four.py @@ -6,6 +6,7 @@ from functools import partial import discord import emojis from discord.ext import commands +from discord.ext.commands import guild_only from bot.constants import Emojis @@ -358,6 +359,7 @@ class ConnectFour(commands.Cog): self.games.remove(game) raise + @guild_only() @commands.group( invoke_without_command=True, aliases=["4inarow", "connect4", "connectfour", "c4"], @@ -422,6 +424,7 @@ class ConnectFour(commands.Cog): await self._play_game(ctx, user, board_size, str(emoji1), str(emoji2)) + @guild_only() @connect_four.command(aliases=["bot", "computer", "cpu"]) async def ai( self, diff --git a/bot/exts/evergreen/error_handler.py b/bot/exts/evergreen/error_handler.py deleted file mode 100644 index 99af1519..00000000 --- a/bot/exts/evergreen/error_handler.py +++ /dev/null @@ -1,129 +0,0 @@ -import logging -import math -import random -from typing import Iterable, Union - -from discord import Embed, Message -from discord.ext import commands -from sentry_sdk import push_scope - -from bot.constants import Colours, ERROR_REPLIES, NEGATIVE_REPLIES -from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure -from bot.utils.exceptions import UserNotPlayingError - -log = logging.getLogger(__name__) - - -class CommandErrorHandler(commands.Cog): - """A error handler for the PythonDiscord server.""" - - def __init__(self, bot: commands.Bot): - self.bot = bot - - @staticmethod - def revert_cooldown_counter(command: commands.Command, message: Message) -> None: - """Undoes the last cooldown counter for user-error cases.""" - if command._buckets.valid: - bucket = command._buckets.get_bucket(message) - bucket._tokens = min(bucket.rate, bucket._tokens + 1) - logging.debug("Cooldown counter reverted as the command was not used correctly.") - - @staticmethod - def error_embed(message: str, title: Union[Iterable, str] = ERROR_REPLIES) -> Embed: - """Build a basic embed with red colour and either a random error title or a title provided.""" - embed = Embed(colour=Colours.soft_red) - if isinstance(title, str): - embed.title = title - else: - embed.title = random.choice(title) - embed.description = message - return embed - - @commands.Cog.listener() - async def on_command_error(self, ctx: commands.Context, error: commands.CommandError) -> None: - """Activates when a command opens an error.""" - if getattr(error, 'handled', False): - logging.debug(f"Command {ctx.command} had its error already handled locally; ignoring.") - return - - error = getattr(error, 'original', error) - logging.debug( - f"Error Encountered: {type(error).__name__} - {str(error)}, " - f"Command: {ctx.command}, " - f"Author: {ctx.author}, " - f"Channel: {ctx.channel}" - ) - - if isinstance(error, commands.CommandNotFound): - return - - if isinstance(error, (InChannelCheckFailure, InMonthCheckFailure)): - await ctx.send(embed=self.error_embed(str(error), NEGATIVE_REPLIES), delete_after=7.5) - return - - if isinstance(error, commands.UserInputError): - self.revert_cooldown_counter(ctx.command, ctx.message) - embed = self.error_embed( - f"Your input was invalid: {error}\n\nUsage:\n```{ctx.prefix}{ctx.command} {ctx.command.signature}```" - ) - await ctx.send(embed=embed) - return - - if isinstance(error, commands.CommandOnCooldown): - mins, secs = divmod(math.ceil(error.retry_after), 60) - embed = self.error_embed( - f"This command is on cooldown:\nPlease retry in {mins} minutes {secs} seconds.", - NEGATIVE_REPLIES - ) - await ctx.send(embed=embed, delete_after=7.5) - return - - if isinstance(error, commands.DisabledCommand): - await ctx.send(embed=self.error_embed("This command has been disabled.", NEGATIVE_REPLIES)) - return - - if isinstance(error, commands.NoPrivateMessage): - await ctx.send(embed=self.error_embed("This command can only be used in the server.", NEGATIVE_REPLIES)) - return - - if isinstance(error, commands.BadArgument): - self.revert_cooldown_counter(ctx.command, ctx.message) - embed = self.error_embed( - "The argument you provided was invalid: " - f"{error}\n\nUsage:\n```{ctx.prefix}{ctx.command} {ctx.command.signature}```" - ) - await ctx.send(embed=embed) - return - - if isinstance(error, commands.CheckFailure): - await ctx.send(embed=self.error_embed("You are not authorized to use this command.", NEGATIVE_REPLIES)) - return - - if isinstance(error, UserNotPlayingError): - await ctx.send("Game not found.") - return - - with push_scope() as scope: - scope.user = { - "id": ctx.author.id, - "username": str(ctx.author) - } - - scope.set_tag("command", ctx.command.qualified_name) - scope.set_tag("message_id", ctx.message.id) - scope.set_tag("channel_id", ctx.channel.id) - - scope.set_extra("full_message", ctx.message.content) - - if ctx.guild is not None: - scope.set_extra( - "jump_to", - f"https://discordapp.com/channels/{ctx.guild.id}/{ctx.channel.id}/{ctx.message.id}" - ) - - log.exception(f"Unhandled command error: {str(error)}", exc_info=error) - - -def setup(bot: commands.Bot) -> None: - """Error handler Cog load.""" - bot.add_cog(CommandErrorHandler(bot)) -- cgit v1.2.3 From fadb1c4e13086d9ecf17629d98668364bd78bf54 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Wed, 24 Feb 2021 17:28:38 +0530 Subject: Mentioned community bot commands channel while sending embed for No Private Message error --- bot/exts/evergreen/error_handler.py | 133 ++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 bot/exts/evergreen/error_handler.py (limited to 'bot') diff --git a/bot/exts/evergreen/error_handler.py b/bot/exts/evergreen/error_handler.py new file mode 100644 index 00000000..54878c08 --- /dev/null +++ b/bot/exts/evergreen/error_handler.py @@ -0,0 +1,133 @@ +import logging +import math +import random +from typing import Iterable, Union + +from discord import Embed, Message +from discord.ext import commands +from sentry_sdk import push_scope + +from bot.constants import Colours, ERROR_REPLIES, NEGATIVE_REPLIES, Channels +from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure +from bot.utils.exceptions import UserNotPlayingError + +log = logging.getLogger(__name__) + + +class CommandErrorHandler(commands.Cog): + """A error handler for the PythonDiscord server.""" + + def __init__(self, bot: commands.Bot): + self.bot = bot + + @staticmethod + def revert_cooldown_counter(command: commands.Command, message: Message) -> None: + """Undoes the last cooldown counter for user-error cases.""" + if command._buckets.valid: + bucket = command._buckets.get_bucket(message) + bucket._tokens = min(bucket.rate, bucket._tokens + 1) + logging.debug("Cooldown counter reverted as the command was not used correctly.") + + @staticmethod + def error_embed(message: str, title: Union[Iterable, str] = ERROR_REPLIES) -> Embed: + """Build a basic embed with red colour and either a random error title or a title provided.""" + embed = Embed(colour=Colours.soft_red) + if isinstance(title, str): + embed.title = title + else: + embed.title = random.choice(title) + embed.description = message + return embed + + @commands.Cog.listener() + async def on_command_error(self, ctx: commands.Context, error: commands.CommandError) -> None: + """Activates when a command opens an error.""" + if getattr(error, 'handled', False): + logging.debug(f"Command {ctx.command} had its error already handled locally; ignoring.") + return + + error = getattr(error, 'original', error) + logging.debug( + f"Error Encountered: {type(error).__name__} - {str(error)}, " + f"Command: {ctx.command}, " + f"Author: {ctx.author}, " + f"Channel: {ctx.channel}" + ) + + if isinstance(error, commands.CommandNotFound): + return + + if isinstance(error, (InChannelCheckFailure, InMonthCheckFailure)): + await ctx.send(embed=self.error_embed(str(error), NEGATIVE_REPLIES), delete_after=7.5) + return + + if isinstance(error, commands.UserInputError): + self.revert_cooldown_counter(ctx.command, ctx.message) + embed = self.error_embed( + f"Your input was invalid: {error}\n\nUsage:\n```{ctx.prefix}{ctx.command} {ctx.command.signature}```" + ) + await ctx.send(embed=embed) + return + + if isinstance(error, commands.CommandOnCooldown): + mins, secs = divmod(math.ceil(error.retry_after), 60) + embed = self.error_embed( + f"This command is on cooldown:\nPlease retry in {mins} minutes {secs} seconds.", + NEGATIVE_REPLIES + ) + await ctx.send(embed=embed, delete_after=7.5) + return + + if isinstance(error, commands.DisabledCommand): + await ctx.send(embed=self.error_embed("This command has been disabled.", NEGATIVE_REPLIES)) + return + + if isinstance(error, commands.NoPrivateMessage): + await ctx.send( + embed=self.error_embed( + f"This command can only be used in the server. Go to <#{Channels.community_bot_commands}> instead!", + NEGATIVE_REPLIES) + ) + return + + if isinstance(error, commands.BadArgument): + self.revert_cooldown_counter(ctx.command, ctx.message) + embed = self.error_embed( + "The argument you provided was invalid: " + f"{error}\n\nUsage:\n```{ctx.prefix}{ctx.command} {ctx.command.signature}```" + ) + await ctx.send(embed=embed) + return + + if isinstance(error, commands.CheckFailure): + await ctx.send(embed=self.error_embed("You are not authorized to use this command.", NEGATIVE_REPLIES)) + return + + if isinstance(error, UserNotPlayingError): + await ctx.send("Game not found.") + return + + with push_scope() as scope: + scope.user = { + "id": ctx.author.id, + "username": str(ctx.author) + } + + scope.set_tag("command", ctx.command.qualified_name) + scope.set_tag("message_id", ctx.message.id) + scope.set_tag("channel_id", ctx.channel.id) + + scope.set_extra("full_message", ctx.message.content) + + if ctx.guild is not None: + scope.set_extra( + "jump_to", + f"https://discordapp.com/channels/{ctx.guild.id}/{ctx.channel.id}/{ctx.message.id}" + ) + + log.exception(f"Unhandled command error: {str(error)}", exc_info=error) + + +def setup(bot: commands.Bot) -> None: + """Error handler Cog load.""" + bot.add_cog(CommandErrorHandler(bot)) -- cgit v1.2.3 From 598cb12f628547ce1542c6094908df48f4b757ec Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Wed, 24 Feb 2021 17:34:42 +0530 Subject: Make Flake8 happy (reorder imports) --- bot/exts/evergreen/error_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/error_handler.py b/bot/exts/evergreen/error_handler.py index 54878c08..83091ba8 100644 --- a/bot/exts/evergreen/error_handler.py +++ b/bot/exts/evergreen/error_handler.py @@ -7,7 +7,7 @@ from discord import Embed, Message from discord.ext import commands from sentry_sdk import push_scope -from bot.constants import Colours, ERROR_REPLIES, NEGATIVE_REPLIES, Channels +from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure from bot.utils.exceptions import UserNotPlayingError -- cgit v1.2.3 From 550e0e8488c77db0a0c43e2bfc948a65551f5be8 Mon Sep 17 00:00:00 2001 From: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> Date: Wed, 24 Feb 2021 19:30:21 +0530 Subject: Correct the parentheses format Co-authored-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/evergreen/error_handler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/error_handler.py b/bot/exts/evergreen/error_handler.py index 83091ba8..28902503 100644 --- a/bot/exts/evergreen/error_handler.py +++ b/bot/exts/evergreen/error_handler.py @@ -86,7 +86,8 @@ class CommandErrorHandler(commands.Cog): await ctx.send( embed=self.error_embed( f"This command can only be used in the server. Go to <#{Channels.community_bot_commands}> instead!", - NEGATIVE_REPLIES) + NEGATIVE_REPLIES + ) ) return -- cgit v1.2.3 From 439873db9749f2df7f0bfe02793aac80d3a708a6 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Thu, 25 Feb 2021 10:36:59 +0530 Subject: Don't use enums for wikipedia error messages, use brackets instead of '\' for long variable values, pass in ctx.channel instead of the full ctx --- bot/exts/evergreen/wikipedia.py | 49 ++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 27 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/wikipedia.py b/bot/exts/evergreen/wikipedia.py index 0b64136f..068c4f43 100644 --- a/bot/exts/evergreen/wikipedia.py +++ b/bot/exts/evergreen/wikipedia.py @@ -1,11 +1,10 @@ import logging import re from datetime import datetime -from enum import Enum from html import unescape from typing import List, Optional -from discord import Color, Embed +from discord import Color, Embed, TextChannel from discord.ext import commands from bot.bot import Bot @@ -13,10 +12,14 @@ from bot.utils import LinePaginator log = logging.getLogger(__name__) -SEARCH_API = "https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&inprop=url&utf8=& \ - format=json&origin=*&srlimit={number_of_results}&srsearch={string}" -WIKI_THUMBNAIL = "https://upload.wikimedia.org/wikipedia/en/thumb/8/80/Wikipedia-logo-v2.svg" \ - "/330px-Wikipedia-logo-v2.svg.png" +SEARCH_API = ( + "https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&inprop=url&utf8=&" + "format=json&origin=*&srlimit={number_of_results}&srsearch={string}" +) +WIKI_THUMBNAIL = ( + "https://upload.wikimedia.org/wikipedia/en/thumb/8/80/Wikipedia-logo-v2.svg" + "/330px-Wikipedia-logo-v2.svg.png" +) WIKI_SNIPPET_REGEX = r'(|<[^>]*>)' WIKI_SEARCH_RESULT = ( "**[{name}]({url})**\n" @@ -24,20 +27,13 @@ WIKI_SEARCH_RESULT = ( ) -class WikipediaSearchErrors(Enum): - """Errors returned in wikipedia search function.""" - - no_results = "Sorry, we could not find a wikipedia article using that search term." - api_issue = "Whoops, the Wikipedia API is having some issues right now. Try again later." - - class WikipediaSearch(commands.Cog): """Get info from wikipedia.""" def __init__(self, bot: Bot): self.bot = bot - async def wiki_request(self, ctx: commands.Context, search: str) -> Optional[List[str]]: + async def wiki_request(self, channel: TextChannel, search: str) -> Optional[List[str]]: """Search wikipedia search string and return formatted first 10 pages found.""" url = SEARCH_API.format(number_of_results=10, string=search) async with self.bot.http_session.get(url=url) as resp: @@ -50,37 +46,36 @@ class WikipediaSearch(commands.Cog): lines = [] for article in results: - formatting = { - 'name': article['title'], - 'description': unescape( + line = WIKI_SEARCH_RESULT.format( + name=article['title'], + description=unescape( re.sub( WIKI_SNIPPET_REGEX, '', article['snippet'] ) ), - 'url': f"https://en.wikipedia.org/?curid={article['pageid']}" - } - line = WIKI_SEARCH_RESULT.format(**formatting) + url=f"https://en.wikipedia.org/?curid={article['pageid']}" + ) lines.append(line) return lines else: - await ctx.send( - WikipediaSearchErrors.no_results.value + await channel.send( + "Sorry, we could not find a wikipedia article using that search term." ) - return None + return else: log.info(f"Unexpected response `{resp.status}` while searching wikipedia for `{search}`") - await ctx.send( - WikipediaSearchErrors.api_issue.value + await channel.send( + "Whoops, the Wikipedia API is having some issues right now. Try again later." ) - return None + return @commands.cooldown(1, 10, commands.BucketType.user) @commands.command(name="wikipedia", aliases=["wiki"]) async def wikipedia_search_command(self, ctx: commands.Context, *, search: str) -> None: """Sends paginated top 10 results of Wikipedia search..""" - contents = await self.wiki_request(ctx, search) + contents = await self.wiki_request(ctx.channel, search) if contents: embed = Embed( -- cgit v1.2.3 From 3766b1424d7ca37ffd7d2477b7a82f192a5fedb4 Mon Sep 17 00:00:00 2001 From: xithrius Date: Thu, 25 Feb 2021 17:55:42 -0800 Subject: Added more topics. --- bot/resources/evergreen/py_topics.yaml | 53 +++++++++++++++++++++++++++------- bot/resources/evergreen/starter.yaml | 11 +++++++ 2 files changed, 54 insertions(+), 10 deletions(-) (limited to 'bot') diff --git a/bot/resources/evergreen/py_topics.yaml b/bot/resources/evergreen/py_topics.yaml index 1e53429a..4973d25a 100644 --- a/bot/resources/evergreen/py_topics.yaml +++ b/bot/resources/evergreen/py_topics.yaml @@ -3,8 +3,6 @@ # python-general 267624335836053506: - What's your favorite PEP? - - What's your current text editor/IDE, and what functionality do you like about it the most when programming in Python? - - What functionality is your text editor/IDE missing for programming Python? - What parts of your life has Python automated, if any? - Which Python project are you the most proud of making? - What made you want to learn Python? @@ -16,23 +14,34 @@ - What feature do you think should be added to Python? - Has Python helped you in school? If so, how? - What was the first thing you created with Python? + - What is your favorite Python package? + - What standard library module is really underrated? + - Have you published any packages on PyPi? If so, what are they? + - What are you currently working on in Python? + - What's your favorite script and how has it helped you in day to day activities? + - When you were first learning, what is something that stumped you? + - When you were first learning, what is a resource you wish you had? + - What is something you know now that you wish you knew when you were starting out? + - What is something simple that you still error on today? + +# algos-and-data-structs +650401909852864553: + - # async 630504881542791169: - Are there any frameworks you wish were async? - How have coroutines changed the way you write Python? + - What is your favorite async library? # c-extensions 728390945384431688: - -# computer-science -650401909852864553: - - - # databases 342318764227821568: - Where do you get your best data? + - What is your preferred database and for what use? # data-science 366673247892275221: @@ -45,11 +54,18 @@ - What feature would you be the most interested in making? - What feature would you like to see added to the library? what feature in the library do you think is redundant? - Do you think there's a way in which Discord could handle bots better? + - What's one feature you wish more developers had in their bots? + +# editors-ides +813178633006350366: + - What's your current text editor/IDE, and what functionality do you like about it the most when programming in Python? + - What functionality is your text editor/IDE missing for programming Python? # esoteric-python 470884583684964352: - What's a common part of programming we can make harder? - What are the pros and cons of messing with __magic__()? + - What's your favorite Python hack? # game-development 660625198390837248: @@ -57,7 +73,7 @@ # microcontrollers 545603026732318730: - - + - What is your favorite version of the Raspberry Pi? # networking 716325106619777044: @@ -67,23 +83,40 @@ 366674035876167691: - If you could wish for a library involving net-sec, what would it be? -# software-testing -463035728335732738: +# software-design +782713858615017503: - # tools-and-devops 463035462760792066: - What editor would you recommend to a beginner? Why? - What editor would you recommend to be the most efficient? Why? + - How often do you use GitHub Actions and workflows to automate your repositories? + - What's your favorite app on GitHub? + +# unit-testing +463035728335732738: + - # unix 491523972836360192: - - + - What's your favorite Bash command? + - What's your most used Bash command? + - How often do you update your Unix machine? + - How often do you upgrade on production? # user-interfaces 338993628049571840: - What's the most impressive Desktop Application you've made with Python so far? + - Have you ever made your own GUI? If so, how? + - Do you perfer Command Line Interfaces (CLI) or Graphic User Interfaces (GUI)? + - What's your favorite CLI (Command Line Interface) or TLI (Terminal Line Interface)? + - What's your best GUI project? # web-development 366673702533988363: - How has Python helped you in web development? + - What tools do you use for web development? + - What is your favorite API library? + - What do you use for your frontend? + - What does your stack look like? diff --git a/bot/resources/evergreen/starter.yaml b/bot/resources/evergreen/starter.yaml index 53c89364..cacaacb6 100644 --- a/bot/resources/evergreen/starter.yaml +++ b/bot/resources/evergreen/starter.yaml @@ -20,3 +20,14 @@ - If you had $100 bill in your Easter Basket, what would you do with it? - What would you do if you know you could succeed at anything you chose to do? - If you could take only three things from your house, what would they be? +- What's the best pastry? +- What's your favourite kind of soup? +- What is the most useless talent that you have? +- Would you rather fight 100 duck sized horses or one horse sized duck? +- What is your favourite colour? +- What's your favourite type of weather? +- Tea or coffee? What about milk? +- Do you speak a language other than English? +- What is your favorite TV show? +- What is your favorite media genre? +- How many years have you spent coding? -- cgit v1.2.3 From f429ce6aaa57d680893be0cbd5a7760de947aac6 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 28 Feb 2021 19:48:13 +0000 Subject: Add issue cog to staff channels. --- bot/constants.py | 2 ++ bot/exts/evergreen/issues.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/constants.py b/bot/constants.py index 682ccf6f..9b7e37f8 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -124,6 +124,7 @@ class Channels(NamedTuple): hacktoberfest_2020 = 760857070781071431 voice_chat_0 = 412357430186344448 voice_chat_1 = 799647045886541885 + staff_voice = 541638762007101470 class Categories(NamedTuple): @@ -131,6 +132,7 @@ class Categories(NamedTuple): development = 411199786025484308 devprojects = 787641585624940544 media = 799054581991997460 + staff = 364918151625965579 class Client(NamedTuple): diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 73ebe547..03d0a86b 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -24,9 +24,11 @@ if GITHUB_TOKEN := Tokens.github: REQUEST_HEADERS["Authorization"] = f"token {GITHUB_TOKEN}" WHITELISTED_CATEGORIES = ( - Categories.devprojects, Categories.media, Categories.development + Categories.devprojects, Categories.media, Categories.development, Categories.staff +) +WHITELISTED_CHANNELS_ON_MESSAGE = ( + Channels.organisation, Channels.mod_meta, Channels.mod_tools, Channels.staff_voice ) -WHITELISTED_CHANNELS_ON_MESSAGE = (Channels.organisation, Channels.mod_meta, Channels.mod_tools) CODE_BLOCK_RE = re.compile( r"^`([^`\n]+)`" # Inline codeblock -- cgit v1.2.3 From b61aa3079d7d1bcaf4e5e6754544143ce1a156a8 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 28 Feb 2021 20:13:08 +0000 Subject: Fix ordering of categories in issues cog --- bot/exts/evergreen/issues.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 03d0a86b..bbcbf611 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -24,7 +24,7 @@ if GITHUB_TOKEN := Tokens.github: REQUEST_HEADERS["Authorization"] = f"token {GITHUB_TOKEN}" WHITELISTED_CATEGORIES = ( - Categories.devprojects, Categories.media, Categories.development, Categories.staff + Categories.development, Categories.devprojects, Categories.media, Categories.staff ) WHITELISTED_CHANNELS_ON_MESSAGE = ( Channels.organisation, Channels.mod_meta, Channels.mod_tools, Channels.staff_voice -- cgit v1.2.3 From f74a49f3e686b41a52ce097a97260b263067cd68 Mon Sep 17 00:00:00 2001 From: Xithrius <15021300+Xithrius@users.noreply.github.com> Date: Sun, 28 Feb 2021 21:49:46 -0800 Subject: Removed wordy-ness of one singular question. Co-authored-by: ChrisJL --- bot/resources/evergreen/py_topics.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/resources/evergreen/py_topics.yaml b/bot/resources/evergreen/py_topics.yaml index 4973d25a..8cf9582d 100644 --- a/bot/resources/evergreen/py_topics.yaml +++ b/bot/resources/evergreen/py_topics.yaml @@ -21,7 +21,7 @@ - What's your favorite script and how has it helped you in day to day activities? - When you were first learning, what is something that stumped you? - When you were first learning, what is a resource you wish you had? - - What is something you know now that you wish you knew when you were starting out? + - What is something you know now, that you wish you knew when starting out? - What is something simple that you still error on today? # algos-and-data-structs -- cgit v1.2.3 From f9339e6043acc2161c3723624cd6ae33dce26bca Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 28 Feb 2021 21:53:13 -0800 Subject: There's no such thing as TLI. Added TUI. --- bot/resources/evergreen/py_topics.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/resources/evergreen/py_topics.yaml b/bot/resources/evergreen/py_topics.yaml index 8cf9582d..f3b2eaa3 100644 --- a/bot/resources/evergreen/py_topics.yaml +++ b/bot/resources/evergreen/py_topics.yaml @@ -110,7 +110,7 @@ - What's the most impressive Desktop Application you've made with Python so far? - Have you ever made your own GUI? If so, how? - Do you perfer Command Line Interfaces (CLI) or Graphic User Interfaces (GUI)? - - What's your favorite CLI (Command Line Interface) or TLI (Terminal Line Interface)? + - What's your favorite CLI (Command Line Interface) or TUI (Terminal Line Interface)? - What's your best GUI project? # web-development -- cgit v1.2.3 From add46b3680d5b9570ddf464ed0674c2b5ad4474d Mon Sep 17 00:00:00 2001 From: Xithrius <15021300+Xithrius@users.noreply.github.com> Date: Sun, 28 Feb 2021 22:06:44 -0800 Subject: "colour" to "color". Co-authored-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/resources/evergreen/starter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/resources/evergreen/starter.yaml b/bot/resources/evergreen/starter.yaml index cacaacb6..949220f9 100644 --- a/bot/resources/evergreen/starter.yaml +++ b/bot/resources/evergreen/starter.yaml @@ -24,7 +24,7 @@ - What's your favourite kind of soup? - What is the most useless talent that you have? - Would you rather fight 100 duck sized horses or one horse sized duck? -- What is your favourite colour? +- What is your favourite color? - What's your favourite type of weather? - Tea or coffee? What about milk? - Do you speak a language other than English? -- cgit v1.2.3 From 167774ea84ec528845a17d41065983e3ef696d12 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 2 Mar 2021 15:51:56 +0530 Subject: Fix Channel Check to use channel ids instead of channel objects, and skip channel check if debug is true --- bot/bot.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/bot.py b/bot/bot.py index 81d59706..176422aa 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -74,11 +74,16 @@ class Bot(commands.Bot): async def check_channels(self) -> None: """Verifies that all channel constants refer to channels which exist.""" await self.wait_until_guild_available() - all_channels = set(self.get_all_channels()) + + if constants.Client.debug: + log.info("Skipping Channels Check.") + return + + all_channels_ids = [channel.id for channel in set(self.get_all_channels())] for name, channel_id in vars(constants.Channels).items(): if name.startswith('_'): continue - if channel_id not in all_channels: + if channel_id not in all_channels_ids: log.error(f'Channel "{name}" with ID {channel_id} missing') async def send_log(self, title: str, details: str = None, *, icon: str = None) -> None: -- cgit v1.2.3 From 674838787fb1916dce98b50bae78159a54833c42 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 2 Mar 2021 16:00:24 +0530 Subject: Don't use sets --- bot/bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/bot.py b/bot/bot.py index 176422aa..e9750697 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -79,7 +79,7 @@ class Bot(commands.Bot): log.info("Skipping Channels Check.") return - all_channels_ids = [channel.id for channel in set(self.get_all_channels())] + all_channels_ids = [channel.id for channel in self.get_all_channels()] for name, channel_id in vars(constants.Channels).items(): if name.startswith('_'): continue -- cgit v1.2.3 From 1e240e7fbac71b0546ef090732c7417bab4e1563 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 2 Mar 2021 14:27:58 -0600 Subject: initial commit of earth_photos --- bot/exts/easter/earth_photos.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 bot/exts/easter/earth_photos.py (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py new file mode 100644 index 00000000..ceffeb48 --- /dev/null +++ b/bot/exts/easter/earth_photos.py @@ -0,0 +1,27 @@ +import asyncio +import logging +import random +from unsplash.api import Api +from unsplash.auth import Auth + +import discord +from discord.ext import commands + +log = logging.getLogger(__name__) + +class EarthPhotos(commands.Cog): + """This cog contains the command for earth photos.""" + + def init(self, bot: commands.Bot): + self.bot = bot + self.current_channel = None + + @commands.command(aliases=["earth"]) + async def earth_photos(self, ctx: commands.Context): + """ + Returns a random photo of earth. + """ + + + + -- cgit v1.2.3 From 99a9d7a1b7651caea4cf1587c89485497c061387 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:22:39 -0600 Subject: Update earth_photos.py --- bot/exts/easter/earth_photos.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index ceffeb48..436b39a7 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,14 +1,24 @@ import asyncio import logging import random -from unsplash.api import Api -from unsplash.auth import Auth +from unsplash.api import Api as uApi +from unsplash.auth import Auth as uAuth import discord from discord.ext import commands +from bot.constants import Tokens + log = logging.getLogger(__name__) +UnClient_id = Tokens.UNSPLASH_API + +UnClient_secret = Tokens.UNSPLASH_SECRET + +redirect_uri = "urn:ietf:wg:oauth:2.0:oob" + +unsplash_auth = uAuth(client_id, + class EarthPhotos(commands.Cog): """This cog contains the command for earth photos.""" @@ -19,7 +29,7 @@ class EarthPhotos(commands.Cog): @commands.command(aliases=["earth"]) async def earth_photos(self, ctx: commands.Context): """ - Returns a random photo of earth. + Returns a random photo of earth, sourced from Unsplash. """ -- cgit v1.2.3 From 0260ad04af6e98c7fd804c58913412b6b936eb73 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 2 Mar 2021 21:39:01 -0600 Subject: finished function --- Pipfile | 1 + Pipfile.lock | 26 +++++++++++++++++--------- bot/constants.py | 1 + bot/exts/easter/earth_photos.py | 35 +++++++++++++++++++---------------- 4 files changed, 38 insertions(+), 25 deletions(-) (limited to 'bot') diff --git a/Pipfile b/Pipfile index e7e01a31..1a2d464e 100644 --- a/Pipfile +++ b/Pipfile @@ -15,6 +15,7 @@ PyYAML = "~=5.3.1" "discord.py" = {extras = ["voice"], version = "~=1.5.1"} async-rediscache = {extras = ["fakeredis"], version = "~=0.1.4"} emojis = "~=0.6.0" +requests = "~=2.25.1" [dev-packages] flake8 = "~=3.8" diff --git a/Pipfile.lock b/Pipfile.lock index ec801979..34cd08cf 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b4aaaacbab13179145e36d7b86c736db512286f6cce8e513cc30c48d68fe3810" + "sha256": "53409f1c6726e95cf348740b1dc55124b77a1f327aea273dce041b5056270b2e" }, "pipfile-spec": 6, "requires": { @@ -238,11 +238,11 @@ }, "idna": { "hashes": [ - "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16", - "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1" + "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", + "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "markers": "python_version >= '3.4'", - "version": "==3.1" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.10" }, "multidict": { "hashes": [ @@ -412,6 +412,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.5.3" }, + "requests": { + "hashes": [ + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" + ], + "index": "pypi", + "version": "==2.25.1" + }, "sentry-sdk": { "hashes": [ "sha256:4ae8d1ced6c67f1c8ea51d82a16721c166c489b76876c9f2c202b8a50334b237", @@ -585,11 +593,11 @@ }, "identify": { "hashes": [ - "sha256:de7129142a5c86d75a52b96f394d94d96d497881d2aaf8eafe320cdbe8ac4bcc", - "sha256:e0dae57c0397629ce13c289f6ddde0204edf518f557bfdb1e56474aa143e77c3" + "sha256:9cdd81e5d2b6e76c3006d5226316dd947bd6324fbeebb881bec489202fa09d3a", + "sha256:b99aa309329c4fea679463eb35d169f3fbe13e66e9dd6162ad1856cbeb03dcbd" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.14" + "markers": "python_full_version >= '3.6.1'", + "version": "==2.0.0" }, "mccabe": { "hashes": [ diff --git a/bot/constants.py b/bot/constants.py index db34b55a..f8ea5743 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -271,6 +271,7 @@ class Tokens(NamedTuple): igdb_client_id = environ.get("IGDB_CLIENT_ID") igdb_client_secret = environ.get("IGDB_CLIENT_SECRET") github = environ.get("GITHUB_TOKEN") + unsplash_key = environ.get("UNSPLASH_KEY") class Wolfram(NamedTuple): diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 436b39a7..478502eb 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,8 +1,5 @@ -import asyncio import logging -import random -from unsplash.api import Api as uApi -from unsplash.auth import Auth as uAuth +import requests import discord from discord.ext import commands @@ -11,27 +8,33 @@ from bot.constants import Tokens log = logging.getLogger(__name__) -UnClient_id = Tokens.UNSPLASH_API +UnClient_id = Tokens.unsplash_key -UnClient_secret = Tokens.UNSPLASH_SECRET - -redirect_uri = "urn:ietf:wg:oauth:2.0:oob" - -unsplash_auth = uAuth(client_id, class EarthPhotos(commands.Cog): """This cog contains the command for earth photos.""" - + def init(self, bot: commands.Bot): self.bot = bot self.current_channel = None - + @commands.command(aliases=["earth"]) async def earth_photos(self, ctx: commands.Context): """ Returns a random photo of earth, sourced from Unsplash. """ - - - - + photorequest = requests.get("https://api.unsplash.com/photos/random?query=earth&client_id=" + UnClient_id) + photojson = photorequest.json() + photourls = photojson.get('urls') + urltosend = photourls.get('regular') + userjson = photojson.get('user') + userName = userjson.get('name') + embed = discord.Embed(title="Earth Photo", description="A photo of Earth from Unsplash.", color=0x66ff00) + embed.set_image(url=urltosend) + embed.set_footer(text="Image by " + userName + " on Unsplash.") + await ctx.send(embed=embed) + + +def setup(bot: commands.Bot) -> None: + """Cog load""" + bot.add_cog(EarthPhotos(bot)) -- cgit v1.2.3 From 51f16ed0a4e1ce43d7ce4cef1701a886d1b8492d Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 2 Mar 2021 21:58:27 -0600 Subject: Update earth_photos.py --- bot/exts/easter/earth_photos.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 478502eb..2ca43e42 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,9 +1,10 @@ -import logging -import requests - import discord from discord.ext import commands +import logging + +import requests + from bot.constants import Tokens log = logging.getLogger(__name__) @@ -15,6 +16,7 @@ class EarthPhotos(commands.Cog): """This cog contains the command for earth photos.""" def init(self, bot: commands.Bot): + """Init function.""" self.bot = bot self.current_channel = None @@ -28,13 +30,13 @@ class EarthPhotos(commands.Cog): photourls = photojson.get('urls') urltosend = photourls.get('regular') userjson = photojson.get('user') - userName = userjson.get('name') + username = userjson.get('name') embed = discord.Embed(title="Earth Photo", description="A photo of Earth from Unsplash.", color=0x66ff00) embed.set_image(url=urltosend) - embed.set_footer(text="Image by " + userName + " on Unsplash.") + embed.set_footer(text="Image by " + username + " on Unsplash.") await ctx.send(embed=embed) def setup(bot: commands.Bot) -> None: - """Cog load""" + """Cog load.""" bot.add_cog(EarthPhotos(bot)) -- cgit v1.2.3 From 286d40bb887246216da23857b4eeb8364fcbf9c7 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 2 Mar 2021 22:04:47 -0600 Subject: linting changes --- bot/exts/easter/earth_photos.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 2ca43e42..e660112f 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,8 +1,10 @@ import discord -from discord.ext import commands import logging +from discord.ext import commands + + import requests from bot.constants import Tokens @@ -22,9 +24,7 @@ class EarthPhotos(commands.Cog): @commands.command(aliases=["earth"]) async def earth_photos(self, ctx: commands.Context): - """ - Returns a random photo of earth, sourced from Unsplash. - """ + """Returns a random photo of earth, sourced from Unsplash.""" photorequest = requests.get("https://api.unsplash.com/photos/random?query=earth&client_id=" + UnClient_id) photojson = photorequest.json() photourls = photojson.get('urls') -- cgit v1.2.3 From 8220661e8ef65ef4bbe92613ed2d3f273d43d76f Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 2 Mar 2021 22:09:10 -0600 Subject: more linting fixes --- bot/exts/easter/earth_photos.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index e660112f..c9cfc9c8 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,11 +1,9 @@ -import discord - import logging -from discord.ext import commands - +import discord import requests +from discord.ext import commands from bot.constants import Tokens -- cgit v1.2.3 From da54e5181cbf2ab3406be4a8ab9628e346d3c328 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 2 Mar 2021 22:15:57 -0600 Subject: lint fixes --- bot/exts/easter/earth_photos.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index c9cfc9c8..909fcbd8 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,7 +1,6 @@ import logging import discord - import requests from discord.ext import commands @@ -15,13 +14,13 @@ UnClient_id = Tokens.unsplash_key class EarthPhotos(commands.Cog): """This cog contains the command for earth photos.""" - def init(self, bot: commands.Bot): + def init(self, bot: commands.Bot) -> None: """Init function.""" self.bot = bot self.current_channel = None @commands.command(aliases=["earth"]) - async def earth_photos(self, ctx: commands.Context): + async def earth_photos(self, ctx: commands.Context) -> None: """Returns a random photo of earth, sourced from Unsplash.""" photorequest = requests.get("https://api.unsplash.com/photos/random?query=earth&client_id=" + UnClient_id) photojson = photorequest.json() -- cgit v1.2.3 From 029f5f0d6b38f70000013ca52c859a3486cdf544 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 07:14:06 -0600 Subject: Update bot/exts/easter/earth_photos.py Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 1 - 1 file changed, 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 909fcbd8..b41b277c 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -15,7 +15,6 @@ class EarthPhotos(commands.Cog): """This cog contains the command for earth photos.""" def init(self, bot: commands.Bot) -> None: - """Init function.""" self.bot = bot self.current_channel = None -- cgit v1.2.3 From 883405e6f419ebfe4799086bf4e7516fd1588c4d Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 07:43:41 -0600 Subject: init to __init__ Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index b41b277c..db295285 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -14,7 +14,7 @@ UnClient_id = Tokens.unsplash_key class EarthPhotos(commands.Cog): """This cog contains the command for earth photos.""" - def init(self, bot: commands.Bot) -> None: + def __init__(self, bot: commands.Bot) -> None: self.bot = bot self.current_channel = None -- cgit v1.2.3 From 246e5bd7109ba906162989e42c77d68402359106 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 09:26:48 -0600 Subject: Fix docstrings Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index db295285..4c319eaa 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -34,5 +34,5 @@ class EarthPhotos(commands.Cog): def setup(bot: commands.Bot) -> None: - """Cog load.""" + """Load the Earth Photos cog.""" bot.add_cog(EarthPhotos(bot)) -- cgit v1.2.3 From 4a0401ddb322fba53e2025a63fdf8d0a52e12076 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 09:32:47 -0600 Subject: Update earth_photos.py --- bot/exts/easter/earth_photos.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 4c319eaa..52bbaf36 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,13 +1,9 @@ -import logging - +import aiohttp import discord -import requests from discord.ext import commands from bot.constants import Tokens -log = logging.getLogger(__name__) - UnClient_id = Tokens.unsplash_key @@ -21,16 +17,14 @@ class EarthPhotos(commands.Cog): @commands.command(aliases=["earth"]) async def earth_photos(self, ctx: commands.Context) -> None: """Returns a random photo of earth, sourced from Unsplash.""" - photorequest = requests.get("https://api.unsplash.com/photos/random?query=earth&client_id=" + UnClient_id) - photojson = photorequest.json() - photourls = photojson.get('urls') - urltosend = photourls.get('regular') - userjson = photojson.get('user') - username = userjson.get('name') - embed = discord.Embed(title="Earth Photo", description="A photo of Earth from Unsplash.", color=0x66ff00) - embed.set_image(url=urltosend) - embed.set_footer(text="Image by " + username + " on Unsplash.") - await ctx.send(embed=embed) + async with ctx.typing(): + async with aiohttp.ClientSession as session: + async with session.get( + 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClientId + ) as r: + jsondata = await r.json() + await ctx.send("Still a placeholder") + def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From a2c68caf0e39e6947372d303dcc707f26f1a744f Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 09:57:07 -0600 Subject: Update earth_photos.py --- bot/exts/easter/earth_photos.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 52bbaf36..adae0dcd 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -20,10 +20,18 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with aiohttp.ClientSession as session: async with session.get( - 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClientId - ) as r: + 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClientId) as r: jsondata = await r.json() - await ctx.send("Still a placeholder") + linksdata = jsondata.get("urls") + downloadlinksdata = jsondata.get("links") + async with session.get( + downloadlinksdata.get("download_location") + "?client_id=" + UnClient_id) as er: + pass + await ctx.send("Still a work in progress") + + + + -- cgit v1.2.3 From 01a1624b14cc5d60b2e76871361e14f9cbfd69ce Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 09:57:49 -0600 Subject: asyncio start --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index adae0dcd..26beda79 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -27,7 +27,7 @@ class EarthPhotos(commands.Cog): async with session.get( downloadlinksdata.get("download_location") + "?client_id=" + UnClient_id) as er: pass - await ctx.send("Still a work in progress") + await ctx.send("Still a work in progress, coming soon.") -- cgit v1.2.3 From 3b0949c96926fa30aa650bfd9c9a43e4fd52521f Mon Sep 17 00:00:00 2001 From: Kronifer Date: Wed, 3 Mar 2021 16:39:05 +0000 Subject: linting --- Pipfile | 1 + Pipfile.lock | 76 ++++++++++++++++++++++++++++++++++++++--- bot/exts/easter/earth_photos.py | 14 ++++---- 3 files changed, 79 insertions(+), 12 deletions(-) (limited to 'bot') diff --git a/Pipfile b/Pipfile index 1a2d464e..1d1df3d7 100644 --- a/Pipfile +++ b/Pipfile @@ -16,6 +16,7 @@ PyYAML = "~=5.3.1" async-rediscache = {extras = ["fakeredis"], version = "~=0.1.4"} emojis = "~=0.6.0" requests = "~=2.25.1" +pre-commit = "*" [dev-packages] flake8 = "~=3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 34cd08cf..b58db761 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "53409f1c6726e95cf348740b1dc55124b77a1f327aea273dce041b5056270b2e" + "sha256": "434b76f6a372bf3ddc418d7b6bdba4d8906cbebb76553ffebf0b15d572e83487" }, "pipfile-spec": 6, "requires": { @@ -50,6 +50,13 @@ ], "version": "==1.3.1" }, + "appdirs": { + "hashes": [ + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" + ], + "version": "==1.4.4" + }, "arrow": { "hashes": [ "sha256:e098abbd9af3665aea81bdd6c869e93af4feb078e98468dd351c383af187aac5", @@ -143,6 +150,14 @@ ], "version": "==1.14.5" }, + "cfgv": { + "hashes": [ + "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d", + "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1" + ], + "markers": "python_full_version >= '3.6.1'", + "version": "==3.2.0" + }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", @@ -161,6 +176,13 @@ "index": "pypi", "version": "==1.5.1" }, + "distlib": { + "hashes": [ + "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb", + "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1" + ], + "version": "==0.3.1" + }, "emojis": { "hashes": [ "sha256:7da34c8a78ae262fd68cef9e2c78a3c1feb59784489eeea0f54ba1d4b7111c7c", @@ -176,6 +198,13 @@ ], "version": "==1.4.5" }, + "filelock": { + "hashes": [ + "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", + "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" + ], + "version": "==3.0.12" + }, "fuzzywuzzy": { "hashes": [ "sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8", @@ -236,6 +265,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.0" }, + "identify": { + "hashes": [ + "sha256:2179e7359471ab55729f201b3fdf7dc2778e221f868410fedcb0987b791ba552", + "sha256:2a5fdf2f5319cc357eda2550bea713a404392495961022cf2462624ce62f0f46" + ], + "markers": "python_full_version >= '3.6.1'", + "version": "==2.1.0" + }, "idna": { "hashes": [ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", @@ -267,6 +304,13 @@ "markers": "python_version >= '3.5'", "version": "==4.7.6" }, + "nodeenv": { + "hashes": [ + "sha256:5304d424c529c997bc888453aeaa6362d242b6b4631e90f3d4bf1b290f1c84a9", + "sha256:ab45090ae383b716c4ef89e690c41ff8c2b257b85b309f01f3654df3d084bd7c" + ], + "version": "==1.5.0" + }, "pillow": { "hashes": [ "sha256:0295442429645fa16d05bd567ef5cff178482439c9aad0411d3f0ce9b88b3a6f", @@ -301,6 +345,14 @@ "index": "pypi", "version": "==7.2.0" }, + "pre-commit": { + "hashes": [ + "sha256:16212d1fde2bed88159287da88ff03796863854b04dc9f838a55979325a3d20e", + "sha256:399baf78f13f4de82a29b649afd74bef2c4e28eb4f021661fc7f29246e8c7a3a" + ], + "index": "pypi", + "version": "==2.10.1" + }, "pycares": { "hashes": [ "sha256:050f00b39ed77ea8a4e555f09417d4b1a6b5baa24bb9531a3e15d003d2319b3f", @@ -451,6 +503,14 @@ "markers": "python_version >= '3.0'", "version": "==2.2" }, + "toml": { + "hashes": [ + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.10.2" + }, "urllib3": { "hashes": [ "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", @@ -459,6 +519,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==1.26.3" }, + "virtualenv": { + "hashes": [ + "sha256:147b43894e51dd6bba882cf9c282447f780e2251cd35172403745fc381a0a80d", + "sha256:2be72df684b74df0ea47679a7df93fd0e04e72520022c57b479d8f881485dbe3" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.4.2" + }, "yarl": { "hashes": [ "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", @@ -593,11 +661,11 @@ }, "identify": { "hashes": [ - "sha256:9cdd81e5d2b6e76c3006d5226316dd947bd6324fbeebb881bec489202fa09d3a", - "sha256:b99aa309329c4fea679463eb35d169f3fbe13e66e9dd6162ad1856cbeb03dcbd" + "sha256:2179e7359471ab55729f201b3fdf7dc2778e221f868410fedcb0987b791ba552", + "sha256:2a5fdf2f5319cc357eda2550bea713a404392495961022cf2462624ce62f0f46" ], "markers": "python_full_version >= '3.6.1'", - "version": "==2.0.0" + "version": "==2.1.0" }, "mccabe": { "hashes": [ diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 26beda79..8e90c9e7 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -20,19 +20,17 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with aiohttp.ClientSession as session: async with session.get( - 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClientId) as r: + 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClient_id) as r: jsondata = await r.json() linksdata = jsondata.get("urls") + embedlink = linksdata.get("full") downloadlinksdata = jsondata.get("links") async with session.get( downloadlinksdata.get("download_location") + "?client_id=" + UnClient_id) as er: - pass - await ctx.send("Still a work in progress, coming soon.") - - - - - + er.status() + embed = discord.Embed(title="In progress") + embed.set_photo(url=embedlink) + await ctx.send(embed=embed) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From 443c623548caf8edb82d0b9cfe41afcf594f0161 Mon Sep 17 00:00:00 2001 From: Kronifer Date: Wed, 3 Mar 2021 16:48:19 +0000 Subject: final lint fix --- bot/exts/easter/earth_photos.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 8e90c9e7..e3d5936e 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -20,13 +20,13 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with aiohttp.ClientSession as session: async with session.get( - 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClient_id) as r: + 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClient_id) as r: jsondata = await r.json() linksdata = jsondata.get("urls") embedlink = linksdata.get("full") downloadlinksdata = jsondata.get("links") async with session.get( - downloadlinksdata.get("download_location") + "?client_id=" + UnClient_id) as er: + downloadlinksdata.get("download_location") + "?client_id=" + UnClient_id) as er: er.status() embed = discord.Embed(title="In progress") embed.set_photo(url=embedlink) -- cgit v1.2.3 From f0cd29587f29731286be8c29d1ee0ca20d37d42f Mon Sep 17 00:00:00 2001 From: Kronifer Date: Wed, 3 Mar 2021 17:07:20 +0000 Subject: possible final update --- bot/exts/easter/earth_photos.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index e3d5936e..0ac470ce 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -18,19 +18,27 @@ class EarthPhotos(commands.Cog): async def earth_photos(self, ctx: commands.Context) -> None: """Returns a random photo of earth, sourced from Unsplash.""" async with ctx.typing(): - async with aiohttp.ClientSession as session: + async with aiohttp.ClientSession() as session: async with session.get( 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClient_id) as r: jsondata = await r.json() linksdata = jsondata.get("urls") embedlink = linksdata.get("full") downloadlinksdata = jsondata.get("links") + userdata = jsondata.get("user") + username = userdata.get("name") + userlinks = userdata.get("links") + profile = userlinks.get("html") async with session.get( downloadlinksdata.get("download_location") + "?client_id=" + UnClient_id) as er: - er.status() - embed = discord.Embed(title="In progress") - embed.set_photo(url=embedlink) - await ctx.send(embed=embed) + er.status + embed = discord.Embed( + title="Earth Photo", + description="A photo of earth from Unsplash.", + color=0x66ff00) + embed.set_image(url=embedlink) + embed.add_field(title="Author", value="Made by [" + username + "](" + profile + ") on Unsplash.") + await ctx.send(embed=embed) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From b2ee1b9e79766b8cfe7b45670f6c86e7166ee84f Mon Sep 17 00:00:00 2001 From: Kronifer Date: Wed, 3 Mar 2021 20:20:22 +0000 Subject: fstrings, colours, and self.bot --- Pipfile | 2 -- bot/constants.py | 1 + bot/exts/easter/earth_photos.py | 48 ++++++++++++++++++++--------------------- 3 files changed, 25 insertions(+), 26 deletions(-) (limited to 'bot') diff --git a/Pipfile b/Pipfile index 1d1df3d7..e7e01a31 100644 --- a/Pipfile +++ b/Pipfile @@ -15,8 +15,6 @@ PyYAML = "~=5.3.1" "discord.py" = {extras = ["voice"], version = "~=1.5.1"} async-rediscache = {extras = ["fakeredis"], version = "~=0.1.4"} emojis = "~=0.6.0" -requests = "~=2.25.1" -pre-commit = "*" [dev-packages] flake8 = "~=3.8" diff --git a/bot/constants.py b/bot/constants.py index f8ea5743..c570b17f 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -158,6 +158,7 @@ class Colours: soft_orange = 0xf9cb54 soft_red = 0xcd6d6d yellow = 0xf9f586 + grass_green = 0x66ff00 class Emojis: diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 0ac470ce..a49e666c 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,8 +1,8 @@ -import aiohttp import discord from discord.ext import commands from bot.constants import Tokens +from bot.constants import Colours UnClient_id = Tokens.unsplash_key @@ -10,35 +10,35 @@ UnClient_id = Tokens.unsplash_key class EarthPhotos(commands.Cog): """This cog contains the command for earth photos.""" - def __init__(self, bot: commands.Bot) -> None: + def __init__(self, bot: commands.Bot): self.bot = bot - self.current_channel = None @commands.command(aliases=["earth"]) async def earth_photos(self, ctx: commands.Context) -> None: """Returns a random photo of earth, sourced from Unsplash.""" async with ctx.typing(): - async with aiohttp.ClientSession() as session: - async with session.get( - 'https://api.unsplash.com/photos/random?query=earth&client_id=' + UnClient_id) as r: - jsondata = await r.json() - linksdata = jsondata.get("urls") - embedlink = linksdata.get("full") - downloadlinksdata = jsondata.get("links") - userdata = jsondata.get("user") - username = userdata.get("name") - userlinks = userdata.get("links") - profile = userlinks.get("html") - async with session.get( - downloadlinksdata.get("download_location") + "?client_id=" + UnClient_id) as er: - er.status - embed = discord.Embed( - title="Earth Photo", - description="A photo of earth from Unsplash.", - color=0x66ff00) - embed.set_image(url=embedlink) - embed.add_field(title="Author", value="Made by [" + username + "](" + profile + ") on Unsplash.") - await ctx.send(embed=embed) + async with self.bot.http_session.get( + 'https://api.unsplash.com/photos/random', + params={"query": "planet_earth", "client_id": UnClient_id}) as r: + jsondata = await r.json() + linksdata = jsondata.get("urls") + embedlink = linksdata.get("full") + downloadlinksdata = jsondata.get("links") + userdata = jsondata.get("user") + username = userdata.get("name") + userlinks = userdata.get("links") + profile = userlinks.get("html") + async with self.bot.http_session.get( + downloadlinksdata.get("download_location"), + params={"client_id": UnClient_id}) as er: + er.status + embed = discord.Embed( + title="Earth Photo", + description="A photo of earth from Unsplash.", + color=Colours.grass_green) + embed.set_image(url=embedlink) + embed.add_field(name="Author", value=f"Made by [{username}]({profile}) on Unsplash.") + await ctx.send(embed=embed) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From 4cf72b014efbd8141e30482984e68e65c08e312d Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 14:28:43 -0600 Subject: Fixed import --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index a49e666c..b496cbea 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,8 +1,8 @@ import discord from discord.ext import commands -from bot.constants import Tokens from bot.constants import Colours +from bot.constants import Tokens UnClient_id = Tokens.unsplash_key -- cgit v1.2.3 From 6c46dca3525758f1c1841f1dba312bb45c28531e Mon Sep 17 00:00:00 2001 From: Kronifer Date: Wed, 3 Mar 2021 22:27:37 +0000 Subject: minor change to getting image --- bot/exts/easter/earth_photos.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index a49e666c..66780f6a 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -19,10 +19,10 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with self.bot.http_session.get( 'https://api.unsplash.com/photos/random', - params={"query": "planet_earth", "client_id": UnClient_id}) as r: + params={"query": "earth", "client_id": UnClient_id}) as r: jsondata = await r.json() linksdata = jsondata.get("urls") - embedlink = linksdata.get("full") + embedlink = linksdata.get("regular") downloadlinksdata = jsondata.get("links") userdata = jsondata.get("user") username = userdata.get("name") -- cgit v1.2.3 From 01c380754e7466654924238dcee2f2077dd752a7 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 19:03:40 -0600 Subject: Format change Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index efc5081a..a544ab59 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -35,7 +35,8 @@ class EarthPhotos(commands.Cog): embed = discord.Embed( title="Earth Photo", description="A photo of earth from Unsplash.", - color=Colours.grass_green) + color=Colours.grass_green + ) embed.set_image(url=embedlink) embed.add_field(name="Author", value=f"Made by [{username}]({profile}) on Unsplash.") await ctx.send(embed=embed) -- cgit v1.2.3 From fa38d70fc16e34ff3aff58bfbc7533f586a8eb97 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 19:05:16 -0600 Subject: More formatting Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index a544ab59..f0c57fc5 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -30,7 +30,8 @@ class EarthPhotos(commands.Cog): profile = userlinks.get("html") async with self.bot.http_session.get( downloadlinksdata.get("download_location"), - params={"client_id": UnClient_id}) as er: + params={"client_id": UnClient_id} + ) as er: er.status embed = discord.Embed( title="Earth Photo", -- cgit v1.2.3 From 825080e805787afc1f36a80b4fa3f73040ebdc75 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 19:05:37 -0600 Subject: Format change Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index f0c57fc5..6bfc26b0 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -19,7 +19,8 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with self.bot.http_session.get( 'https://api.unsplash.com/photos/random', - params={"query": "earth", "client_id": UnClient_id}) as r: + params={"query": "earth", "client_id": UnClient_id} + ) as r: jsondata = await r.json() linksdata = jsondata.get("urls") embedlink = linksdata.get("regular") -- cgit v1.2.3 From 05e18c02cd076a70e3aac370e7d120a16c84aab7 Mon Sep 17 00:00:00 2001 From: Kronifer Date: Thu, 4 Mar 2021 01:31:14 +0000 Subject: Revert "Format change" This reverts commit 825080e805787afc1f36a80b4fa3f73040ebdc75. --- bot/exts/easter/earth_photos.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 6bfc26b0..f0c57fc5 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -19,8 +19,7 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with self.bot.http_session.get( 'https://api.unsplash.com/photos/random', - params={"query": "earth", "client_id": UnClient_id} - ) as r: + params={"query": "earth", "client_id": UnClient_id}) as r: jsondata = await r.json() linksdata = jsondata.get("urls") embedlink = linksdata.get("regular") -- cgit v1.2.3 From 60712f67c3e0f77023a481e5cbf0ce9816a7368e Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Wed, 3 Mar 2021 20:16:59 -0600 Subject: requested changes by @Shivansh-007 --- bot/exts/easter/earth_photos.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index f0c57fc5..001f8f41 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -31,8 +31,8 @@ class EarthPhotos(commands.Cog): async with self.bot.http_session.get( downloadlinksdata.get("download_location"), params={"client_id": UnClient_id} - ) as er: - er.status + ) as _: + pass embed = discord.Embed( title="Earth Photo", description="A photo of earth from Unsplash.", -- cgit v1.2.3 From e222ece92b4d14f4a9bb148f28acf9770da44d1b Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 10:35:38 -0600 Subject: Changes requested by @ChrisLovering --- bot/exts/easter/earth_photos.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 001f8f41..3ab8e7d9 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -1,10 +1,12 @@ +import logging + import discord from discord.ext import commands from bot.constants import Colours from bot.constants import Tokens -UnClient_id = Tokens.unsplash_key +log = logging.getLogger(__name__) class EarthPhotos(commands.Cog): @@ -19,7 +21,7 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with self.bot.http_session.get( 'https://api.unsplash.com/photos/random', - params={"query": "earth", "client_id": UnClient_id}) as r: + params={"query": "earth", "client_id": Tokens.unsplash_access_key}) as r: jsondata = await r.json() linksdata = jsondata.get("urls") embedlink = linksdata.get("regular") @@ -30,9 +32,10 @@ class EarthPhotos(commands.Cog): profile = userlinks.get("html") async with self.bot.http_session.get( downloadlinksdata.get("download_location"), - params={"client_id": UnClient_id} - ) as _: + params={"client_id": Tokens.unsplash_access_key} + ) as er: pass + embed = discord.Embed( title="Earth Photo", description="A photo of earth from Unsplash.", @@ -45,4 +48,7 @@ class EarthPhotos(commands.Cog): def setup(bot: commands.Bot) -> None: """Load the Earth Photos cog.""" + if not Tokens.unsplash_access_key: + log.warning("No Unsplash access key found. Cog not loading.") + return bot.add_cog(EarthPhotos(bot)) -- cgit v1.2.3 From 512a5b3f085510d5862589ecc21bd253cb219207 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 10:37:53 -0600 Subject: Changes requested by @ChrisLovering --- bot/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/constants.py b/bot/constants.py index c570b17f..721defc8 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -272,7 +272,7 @@ class Tokens(NamedTuple): igdb_client_id = environ.get("IGDB_CLIENT_ID") igdb_client_secret = environ.get("IGDB_CLIENT_SECRET") github = environ.get("GITHUB_TOKEN") - unsplash_key = environ.get("UNSPLASH_KEY") + unsplash_access_key = environ.get("UNSPLASH_KEY") class Wolfram(NamedTuple): -- cgit v1.2.3 From 8b05f80392174a1a8b47e872b955d59bdcd4472f Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 10:40:42 -0600 Subject: small lint fix --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 3ab8e7d9..beb16772 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -33,7 +33,7 @@ class EarthPhotos(commands.Cog): async with self.bot.http_session.get( downloadlinksdata.get("download_location"), params={"client_id": Tokens.unsplash_access_key} - ) as er: + ) as _: pass embed = discord.Embed( -- cgit v1.2.3 From f22aa5bd3f706751556def22d5660cdc8d93fde1 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 10:56:06 -0600 Subject: Format fix Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index beb16772..3abedd0c 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -21,7 +21,8 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with self.bot.http_session.get( 'https://api.unsplash.com/photos/random', - params={"query": "earth", "client_id": Tokens.unsplash_access_key}) as r: + params={"query": "earth", "client_id": Tokens.unsplash_access_key} + ) as r: jsondata = await r.json() linksdata = jsondata.get("urls") embedlink = linksdata.get("regular") -- cgit v1.2.3 From 1e1f4035f14592d7beaf93cbd3ae8e3895de588c Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 10:56:36 -0600 Subject: String upgrade Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 3abedd0c..d3b21644 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -39,7 +39,7 @@ class EarthPhotos(commands.Cog): embed = discord.Embed( title="Earth Photo", - description="A photo of earth from Unsplash.", + description="A photo of Earth 🌎 from Unsplash.", color=Colours.grass_green ) embed.set_image(url=embedlink) -- cgit v1.2.3 From 3fa4049b0c16777c7a9349dc9058d89a4a44b5c7 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 10:58:25 -0600 Subject: Update earth_photos.py --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index d3b21644..71fb1313 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -43,7 +43,7 @@ class EarthPhotos(commands.Cog): color=Colours.grass_green ) embed.set_image(url=embedlink) - embed.add_field(name="Author", value=f"Made by [{username}]({profile}) on Unsplash.") + embed.add_field(name="Author", value=f"Photo by [{username}]({profile}) on Unsplash.") await ctx.send(embed=embed) -- cgit v1.2.3 From c25381fffd3b42bd1345dd9a910218c70877d2d3 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 10:59:36 -0600 Subject: suggestion by @Shivansh-007 --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 71fb1313..1cf2d11a 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -44,7 +44,7 @@ class EarthPhotos(commands.Cog): ) embed.set_image(url=embedlink) embed.add_field(name="Author", value=f"Photo by [{username}]({profile}) on Unsplash.") - await ctx.send(embed=embed) + await ctx.send(embed=embed) def setup(bot: commands.Bot) -> None: -- cgit v1.2.3 From 68ff4f3a524e90099e6953bd601321623e789e66 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 11:04:05 -0600 Subject: clarification in some areas --- bot/exts/easter/earth_photos.py | 1 + 1 file changed, 1 insertion(+) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 1cf2d11a..c1704e12 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -31,6 +31,7 @@ class EarthPhotos(commands.Cog): username = userdata.get("name") userlinks = userdata.get("links") profile = userlinks.get("html") + # Extra request as per Unsplash Guidelines async with self.bot.http_session.get( downloadlinksdata.get("download_location"), params={"client_id": Tokens.unsplash_access_key} -- cgit v1.2.3 From 55e33789830c00fc970c74be142857f90678cda7 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Thu, 4 Mar 2021 11:20:37 -0800 Subject: Add link to discussion for suggesting facts in Embed --- bot/exts/evergreen/pythonfacts.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index 11b258f9..fb96a19d 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -20,7 +20,12 @@ class PythonFacts(commands.Cog): @commands.command(name='pythonfact', aliases=['pyfact']) async def get_python_fact(self, ctx: commands.Context) -> None: """Sends a Random fun fact about Python.""" - embed = discord.Embed(title='Python Facts', description=next(FACTS), colour=next(COLORS)) + embed = discord.Embed(title='Python Facts', + description=next(FACTS), + colour=next(COLORS)) + embed.add_field(name='Suggestions', + value="Want to suggest more facts? " + "Suggest more facts [here!](https://github.com/python-discord/meta/discussions/93)") await ctx.send(embed=embed) -- cgit v1.2.3 From cce1b2cb25b572ac3e976b190d7eae417240ae76 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 13:26:42 -0600 Subject: API guideline fix for Unsplash --- bot/exts/easter/earth_photos.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index c1704e12..39bb627e 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -31,7 +31,6 @@ class EarthPhotos(commands.Cog): username = userdata.get("name") userlinks = userdata.get("links") profile = userlinks.get("html") - # Extra request as per Unsplash Guidelines async with self.bot.http_session.get( downloadlinksdata.get("download_location"), params={"client_id": Tokens.unsplash_access_key} @@ -44,7 +43,9 @@ class EarthPhotos(commands.Cog): color=Colours.grass_green ) embed.set_image(url=embedlink) - embed.add_field(name="Author", value=f"Photo by [{username}]({profile}) on Unsplash.") + embed.add_field(name="Author", + value=f"Photo by [{username}]({profile}?utm_source=sir_lancebot&utm_medium=referral)\ + on [Unsplash](https://unsplash.com?utm_source=sir_lancebot&utm_medium=referral).") await ctx.send(embed=embed) -- cgit v1.2.3 From 6b8a81e7a698eb362b4bea7bb73ef369d589cbfc Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 13:30:17 -0600 Subject: whitespace fix --- bot/exts/easter/earth_photos.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 39bb627e..9bcca583 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -39,11 +39,11 @@ class EarthPhotos(commands.Cog): embed = discord.Embed( title="Earth Photo", - description="A photo of Earth 🌎 from Unsplash.", + description="A photo of Earth 🌎 from Unsplash.", color=Colours.grass_green ) embed.set_image(url=embedlink) - embed.add_field(name="Author", + embed.add_field(name="Author", value=f"Photo by [{username}]({profile}?utm_source=sir_lancebot&utm_medium=referral)\ on [Unsplash](https://unsplash.com?utm_source=sir_lancebot&utm_medium=referral).") await ctx.send(embed=embed) -- cgit v1.2.3 From 43d42c9fc254e79ecb8e98e42ff4ea9aa43c707a Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 13:44:31 -0600 Subject: linting fix --- bot/exts/easter/earth_photos.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 9bcca583..26f3d115 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -21,7 +21,7 @@ class EarthPhotos(commands.Cog): async with ctx.typing(): async with self.bot.http_session.get( 'https://api.unsplash.com/photos/random', - params={"query": "earth", "client_id": Tokens.unsplash_access_key} + params={"query": "planet_earth", "client_id": Tokens.unsplash_access_key} ) as r: jsondata = await r.json() linksdata = jsondata.get("urls") @@ -31,6 +31,8 @@ class EarthPhotos(commands.Cog): username = userdata.get("name") userlinks = userdata.get("links") profile = userlinks.get("html") + # Referral flags + rf = "?utm_source=sir_lancebot&utm_medium=referral" async with self.bot.http_session.get( downloadlinksdata.get("download_location"), params={"client_id": Tokens.unsplash_access_key} @@ -39,13 +41,13 @@ class EarthPhotos(commands.Cog): embed = discord.Embed( title="Earth Photo", - description="A photo of Earth 🌎 from Unsplash.", + description="A photo of Earth 🌎 from Unsplash.", color=Colours.grass_green ) embed.set_image(url=embedlink) embed.add_field(name="Author", - value=f"Photo by [{username}]({profile}?utm_source=sir_lancebot&utm_medium=referral)\ - on [Unsplash](https://unsplash.com?utm_source=sir_lancebot&utm_medium=referral).") + value=f"Photo by [{username}]({profile}" + rf + ") \ +on [Unsplash](https://unsplash.com?" + rf + ").") await ctx.send(embed=embed) -- cgit v1.2.3 From e6f2d51cfc35ae8bafc160fb3449911457442252 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 13:53:45 -0600 Subject: style guidelines --- bot/exts/easter/earth_photos.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 26f3d115..96282d24 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -45,9 +45,11 @@ class EarthPhotos(commands.Cog): color=Colours.grass_green ) embed.set_image(url=embedlink) - embed.add_field(name="Author", - value=f"Photo by [{username}]({profile}" + rf + ") \ -on [Unsplash](https://unsplash.com?" + rf + ").") + embed.add_field( + name="Author", + value=f"Photo by [{username}]({profile}{rf}) \ + on [Unsplash](https://unsplash.com{rf})." + ) await ctx.send(embed=embed) -- cgit v1.2.3 From 1ae9948c04257c27fb2e71e5ae03a05bcd1db60e Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 13:57:26 -0600 Subject: single space fix --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 96282d24..12fe6f1c 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -41,7 +41,7 @@ class EarthPhotos(commands.Cog): embed = discord.Embed( title="Earth Photo", - description="A photo of Earth 🌎 from Unsplash.", + description="A photo of Earth 🌎 from Unsplash.", color=Colours.grass_green ) embed.set_image(url=embedlink) -- cgit v1.2.3 From 1669b50e026678fd8e9fe6f72677e1de5943dd66 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon Date: Thu, 4 Mar 2021 12:18:25 -0800 Subject: Remove "Want to suggest a fact?" for consistency --- bot/exts/evergreen/pythonfacts.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/pythonfacts.py b/bot/exts/evergreen/pythonfacts.py index fb96a19d..457c2fd3 100644 --- a/bot/exts/evergreen/pythonfacts.py +++ b/bot/exts/evergreen/pythonfacts.py @@ -24,8 +24,7 @@ class PythonFacts(commands.Cog): description=next(FACTS), colour=next(COLORS)) embed.add_field(name='Suggestions', - value="Want to suggest more facts? " - "Suggest more facts [here!](https://github.com/python-discord/meta/discussions/93)") + value="Suggest more facts [here!](https://github.com/python-discord/meta/discussions/93)") await ctx.send(embed=embed) -- cgit v1.2.3 From 334885c1b98ac4dcd475baac358eb8981a65b9c5 Mon Sep 17 00:00:00 2001 From: Dillon Runke <44979306+Kronifer@users.noreply.github.com> Date: Thu, 4 Mar 2021 16:17:42 -0600 Subject: Update earth_photos.py --- bot/exts/easter/earth_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 12fe6f1c..60e34b15 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -32,7 +32,7 @@ class EarthPhotos(commands.Cog): userlinks = userdata.get("links") profile = userlinks.get("html") # Referral flags - rf = "?utm_source=sir_lancebot&utm_medium=referral" + rf = "?utm_source=Sir%20Lancebot&utm_medium=referral" async with self.bot.http_session.get( downloadlinksdata.get("download_location"), params={"client_id": Tokens.unsplash_access_key} -- cgit v1.2.3 From bd49374ca6efad79b97d891882b05b8568f10fb4 Mon Sep 17 00:00:00 2001 From: MrKomodoDragon <74436682+MrKomodoDragon@users.noreply.github.com> Date: Thu, 4 Mar 2021 14:39:47 -0800 Subject: Remove arrows (whoopsies)! --- bot/constants.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'bot') diff --git a/bot/constants.py b/bot/constants.py index f6e09ae7..b8e30a7c 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -158,12 +158,9 @@ class Colours: soft_orange = 0xf9cb54 soft_red = 0xcd6d6d yellow = 0xf9f586 -<<<<<<< master python_blue = 0x4B8BBE python_yellow = 0xFFD43B -======= grass_green = 0x66ff00 ->>>>>>> master class Emojis: -- cgit v1.2.3 From bb8820c9df9a01f39e3d97f76ca25007dd9f4c9e Mon Sep 17 00:00:00 2001 From: kosayoda Date: Sun, 7 Mar 2021 01:35:49 +0800 Subject: Unify emoji count and emoji information to a cog. --- bot/exts/evergreen/emoji.py | 122 ++++++++++++++++++++++++++++++++++++++ bot/exts/evergreen/emoji_count.py | 97 ------------------------------ bot/exts/evergreen/emojis.py | 39 ------------ 3 files changed, 122 insertions(+), 136 deletions(-) create mode 100644 bot/exts/evergreen/emoji.py delete mode 100644 bot/exts/evergreen/emoji_count.py delete mode 100644 bot/exts/evergreen/emojis.py (limited to 'bot') diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py new file mode 100644 index 00000000..a24d420c --- /dev/null +++ b/bot/exts/evergreen/emoji.py @@ -0,0 +1,122 @@ +import datetime +import logging +import random +import textwrap +from collections import defaultdict +from typing import List, Tuple + +from discord import Color, Embed, Emoji +from discord.ext import commands + +from bot.constants import Colours, ERROR_REPLIES +from bot.utils.pagination import LinePaginator +from bot.utils.time import time_since + +log = logging.getLogger(__name__) + + +class Emoji(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[Embed, List[str]]: + """Generates an embed with the emoji names and count.""" + embed = Embed( + color=Colours.orange, + title="Emoji Count", + timestamp=datetime.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") + else: + msg.append(f"There are **{len(category_emojis)}** emojis in **{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" + else: + emoji_info = f"There is **{len(category_emojis)}** emoji in **{category_name}** category" + if emoji_choice.animated: + msg.append(f' {emoji_info}') + else: + msg.append(f'<:{emoji_choice.name}:{emoji_choice.id}> {emoji_info}') + return embed, msg + + @staticmethod + def generate_invalid_embed(emojis: list) -> Tuple[Embed, List[str]]: + """Generates error embed.""" + embed = Embed( + color=Colours.soft_red, + title=random.choice(ERROR_REPLIES) + ) + msg = [] + + emoji_dict = defaultdict(list) + for emoji in emojis: + emoji_dict[emoji.name.split("_")[0]].append(emoji) + + error_comp = ', '.join(emoji_dict) + msg.append(f"These are the valid categories\n```{error_comp}```") + return embed, msg + + @commands.group(name="emoji", invoke_without_command=True) + async def emoji_group(self, ctx: commands.Context) -> None: + """A group of commands related to emojis.""" + await ctx.send_help(ctx.command) + + @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) + + if not ctx.guild.emojis: + await ctx.send("No emojis found.") + return + log.trace(f"Emoji Category {'' if category_query else 'not '}provided by the user") + for emoji in ctx.guild.emojis: + emoji_category = emoji.name.split("_")[0] + + if category_query is not None and emoji_category not in category_query: + continue + + emoji_dict[emoji_category].append(emoji) + + if not emoji_dict: + log.trace("Invalid name provided by the user") + embed, msg = self.generate_invalid_embed(ctx.guild.emojis) + else: + 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'Information about "{emoji.name}"', + description=textwrap.dedent(f""" + Name: {emoji.name} + Created: {time_since(emoji.created_at, precision="hours")} + ID: {emoji.id} + [Emoji source image]({emoji.url}) + """), + color=Color.blurple() + ) + emoji_information.set_thumbnail( + url=emoji.url + ) + await ctx.send(embed=emoji_information) + + +def setup(bot: commands.Bot) -> None: + """Add the Emoji cog into the bot.""" + bot.add_cog(Emoji(bot)) diff --git a/bot/exts/evergreen/emoji_count.py b/bot/exts/evergreen/emoji_count.py deleted file mode 100644 index cc43e9ab..00000000 --- a/bot/exts/evergreen/emoji_count.py +++ /dev/null @@ -1,97 +0,0 @@ -import datetime -import logging -import random -from collections import defaultdict -from typing import List, Tuple - -import discord -from discord.ext import commands - -from bot.constants import Colours, ERROR_REPLIES -from bot.utils.pagination import LinePaginator - -log = logging.getLogger(__name__) - - -class EmojiCount(commands.Cog): - """Command that give random emoji based on category.""" - - def __init__(self, bot: commands.Bot): - self.bot = bot - - @staticmethod - def embed_builder(emoji: dict) -> Tuple[discord.Embed, List[str]]: - """Generates an embed with the emoji names and count.""" - embed = discord.Embed( - color=Colours.orange, - title="Emoji Count", - timestamp=datetime.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") - else: - msg.append(f"There are **{len(category_emojis)}** emojis in **{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" - else: - emoji_info = f"There is **{len(category_emojis)}** emoji in **{category_name}** category" - if emoji_choice.animated: - msg.append(f' {emoji_info}') - else: - msg.append(f'<:{emoji_choice.name}:{emoji_choice.id}> {emoji_info}') - return embed, msg - - @staticmethod - def generate_invalid_embed(emojis: list) -> Tuple[discord.Embed, List[str]]: - """Generates error embed.""" - embed = discord.Embed( - color=Colours.soft_red, - title=random.choice(ERROR_REPLIES) - ) - msg = [] - - emoji_dict = defaultdict(list) - for emoji in emojis: - emoji_dict[emoji.name.split("_")[0]].append(emoji) - - error_comp = ', '.join(emoji_dict) - msg.append(f"These are the valid 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: - """Returns embed with emoji category and info given by the user.""" - emoji_dict = defaultdict(list) - - if not ctx.guild.emojis: - await ctx.send("No emojis found.") - return - log.trace(f"Emoji Category {'' if category_query else 'not '}provided by the user") - for emoji in ctx.guild.emojis: - emoji_category = emoji.name.split("_")[0] - - if category_query is not None and emoji_category not in category_query: - continue - - emoji_dict[emoji_category].append(emoji) - - if not emoji_dict: - log.trace("Invalid name provided by the user") - embed, msg = self.generate_invalid_embed(ctx.guild.emojis) - else: - embed, msg = self.embed_builder(emoji_dict) - await LinePaginator.paginate(lines=msg, ctx=ctx, embed=embed) - - -def setup(bot: commands.Bot) -> None: - """Emoji Count Cog load.""" - bot.add_cog(EmojiCount(bot)) diff --git a/bot/exts/evergreen/emojis.py b/bot/exts/evergreen/emojis.py deleted file mode 100644 index 9f825e6d..00000000 --- a/bot/exts/evergreen/emojis.py +++ /dev/null @@ -1,39 +0,0 @@ -import textwrap - -from discord import Color, Embed, Emoji -from discord.ext import commands - -from bot.utils.time import time_since - - -class Emojis(commands.Cog): - """Has commands related to emojis.""" - - @commands.group(name="emoji", invoke_without_command=True) - async def emojis_group(self, ctx: commands.Context, emoji: Emoji) -> None: - """A group of commands related to emojis.""" - # No parameters = same as invoking info subcommand - await ctx.invoke(self.info_command, emoji) - - @emojis_group.command(name="info") - async def info_command(self, ctx: commands.Context, emoji: Emoji) -> None: - """Returns relevant information about a Discord Emoji.""" - emoji_information = Embed( - title=f'Information about "{emoji.name}"', - description=textwrap.dedent(f""" - Name: {emoji.name} - Created: {time_since(emoji.created_at, precision="hours")} - ID: {emoji.id} - [Emoji source image]({emoji.url}) - """), - color=Color.blurple() - ) - emoji_information.set_thumbnail( - url=emoji.url - ) - await ctx.send(embed=emoji_information) - - -def setup(bot: commands.Bot) -> None: - """Add the Emojis cog into the bot.""" - bot.add_cog(Emojis()) -- cgit v1.2.3 From af22fe556a3b1ab8a98245cc8f96e1d81d0f4289 Mon Sep 17 00:00:00 2001 From: kosayoda Date: Sun, 7 Mar 2021 11:49:58 +0800 Subject: Improve emoji information embed visuals. --- bot/exts/evergreen/emoji.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py index a24d420c..8e5279f3 100644 --- a/bot/exts/evergreen/emoji.py +++ b/bot/exts/evergreen/emoji.py @@ -1,9 +1,9 @@ -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 from discord import Color, Embed, Emoji from discord.ext import commands @@ -27,7 +27,7 @@ class Emoji(commands.Cog): embed = Embed( color=Colours.orange, title="Emoji Count", - timestamp=datetime.datetime.utcnow() + timestamp=datetime.utcnow() ) msg = [] @@ -54,7 +54,7 @@ class Emoji(commands.Cog): @staticmethod def generate_invalid_embed(emojis: list) -> Tuple[Embed, List[str]]: - """Generates error embed.""" + """Generates error embed for invalid emoji categories.""" embed = Embed( color=Colours.soft_red, title=random.choice(ERROR_REPLIES) @@ -70,9 +70,12 @@ class Emoji(commands.Cog): return embed, msg @commands.group(name="emoji", invoke_without_command=True) - async def emoji_group(self, ctx: commands.Context) -> None: + async def emoji_group(self, ctx: commands.Context, emoji: Optional[Emoji]) -> None: """A group of commands related to emojis.""" - await ctx.send_help(ctx.command) + if emoji is not None: + await ctx.invoke(self.info_command, emoji) + else: + await ctx.send_help(ctx.command) @emoji_group.command(name="count", aliases=("c",)) async def count_command(self, ctx: commands.Context, *, category_query: str = None) -> None: @@ -102,18 +105,17 @@ class Emoji(commands.Cog): async def info_command(self, ctx: commands.Context, emoji: Emoji) -> None: """Returns relevant information about a Discord Emoji.""" emoji_information = Embed( - title=f'Information about "{emoji.name}"', + title=f"Emoji Information: {emoji.name}", description=textwrap.dedent(f""" - Name: {emoji.name} - Created: {time_since(emoji.created_at, precision="hours")} - ID: {emoji.id} - [Emoji source image]({emoji.url}) + **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() - ) - emoji_information.set_thumbnail( - url=emoji.url - ) + color=Color.blurple(), + url=str(emoji.url), + ).set_thumbnail(url=emoji.url) + await ctx.send(embed=emoji_information) -- cgit v1.2.3 From 5c46abf4b88b4d45f672082c829b1ec6cec12296 Mon Sep 17 00:00:00 2001 From: kosayoda Date: Mon, 8 Mar 2021 16:44:21 +0800 Subject: Rename cog to avoid name conflict with discordpy. --- bot/exts/evergreen/emoji.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py index 8e5279f3..e07b1505 100644 --- a/bot/exts/evergreen/emoji.py +++ b/bot/exts/evergreen/emoji.py @@ -15,7 +15,7 @@ from bot.utils.time import time_since log = logging.getLogger(__name__) -class Emoji(commands.Cog): +class Emojis(commands.Cog): """A collection of commands related to emojis in the server.""" def __init__(self, bot: commands.Bot): @@ -120,5 +120,5 @@ class Emoji(commands.Cog): def setup(bot: commands.Bot) -> None: - """Add the Emoji cog into the bot.""" - bot.add_cog(Emoji(bot)) + """Add the Emojis cog into the bot.""" + bot.add_cog(Emojis(bot)) -- cgit v1.2.3 From cfd59aed903c2ed2d57f4fc804bd978e07090ae1 Mon Sep 17 00:00:00 2001 From: kosayoda Date: Mon, 8 Mar 2021 16:51:27 +0800 Subject: Improve punctuation and wording of .emoji count. --- bot/exts/evergreen/emoji.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py index e07b1505..99f71218 100644 --- a/bot/exts/evergreen/emoji.py +++ b/bot/exts/evergreen/emoji.py @@ -34,18 +34,18 @@ class Emojis(commands.Cog): 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' {emoji_info}') else: @@ -66,7 +66,7 @@ class Emojis(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.group(name="emoji", invoke_without_command=True) -- cgit v1.2.3 From 6c89267f2ce07a3a55dff933f5d76aba2a695f48 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Mon, 8 Mar 2021 19:33:41 +0100 Subject: Properly rename countdown_task -> notification_task The old name was still in use in the cog_unload, making it fail --- bot/exts/christmas/advent_of_code/_cog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index 466edd48..2203bf00 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -36,7 +36,7 @@ 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.notification_task = None self.status_task = None notification_coro = _helpers.new_puzzle_notification(self.bot) @@ -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: -- cgit v1.2.3 From e6e12c3d3b8a9233cdd92c380c720aa461ab4565 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Mon, 8 Mar 2021 19:39:09 +0100 Subject: Restrict the aoc leaderboard commands to december --- bot/exts/christmas/advent_of_code/_cog.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'bot') diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index 2203bf00..c86ce18a 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -173,6 +173,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 +199,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"), -- cgit v1.2.3 From 8b0c1cd3b6729558218bd85aeb660d1975877345 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Tue, 9 Mar 2021 10:21:47 +0100 Subject: Remove useless initialization in the AoC cog --- bot/exts/christmas/advent_of_code/_cog.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index c86ce18a..29902306 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -36,9 +36,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.notification_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") -- cgit v1.2.3 From ccfb8a7deea064b3b1e02d233d033cec20891eba Mon Sep 17 00:00:00 2001 From: Dillon Runke <44979306+Kronifer@users.noreply.github.com> Date: Tue, 9 Mar 2021 16:54:57 -0600 Subject: small style fix --- bot/exts/easter/earth_photos.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 60e34b15..58d7de61 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -46,10 +46,9 @@ 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) -- cgit v1.2.3 From abc41bde93fb51eeac6d7a80286fde184a665ba0 Mon Sep 17 00:00:00 2001 From: Kronifer <44979306+Kronifer@users.noreply.github.com> Date: Tue, 9 Mar 2021 17:06:17 -0600 Subject: embed fix --- bot/exts/easter/earth_photos.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 58d7de61..89d37e11 100644 --- a/bot/exts/easter/earth_photos.py +++ b/bot/exts/easter/earth_photos.py @@ -46,9 +46,10 @@ class EarthPhotos(commands.Cog): ) embed.set_image(url=embedlink) embed.add_field( - value=f"Photo by [{username}]({profile}{rf}) " - f"on [Unsplash](https://unsplash.com{rf})." - ) + name="Author", + value=f"Photo by [{username}]({profile}{rf}) " + f"on [Unsplash](https://unsplash.com{rf})." + ) await ctx.send(embed=embed) -- cgit v1.2.3 From 3939fa7e065a0ccab7e4aa0ece866ec99c016139 Mon Sep 17 00:00:00 2001 From: Dillon Runke <44979306+Kronifer@users.noreply.github.com> Date: Wed, 10 Mar 2021 07:50:44 -0600 Subject: suggestion by @Xithrius Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/easter/earth_photos.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py index 89d37e11..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}) " - f"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) -- cgit v1.2.3 From 11bf3700c10c29b27ddd14c5282b239bb6f1f191 Mon Sep 17 00:00:00 2001 From: JagTheFriend Date: Tue, 9 Mar 2021 22:03:55 +0200 Subject: Removed requesting to bots. Added grammer. --- bot/exts/evergreen/tic_tac_toe.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'bot') 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: -- cgit v1.2.3 From 1cd9c7a4f74834d799bfc706f5f28cb4147fa0ff Mon Sep 17 00:00:00 2001 From: ToxicKidz <78174417+ToxicKidz@users.noreply.github.com> Date: Thu, 11 Mar 2021 12:24:49 -0500 Subject: change ctx.send_help to ctx.invoke(help_command) ; --- bot/exts/christmas/advent_of_code/_cog.py | 3 ++- bot/exts/evergreen/emoji.py | 3 ++- bot/exts/evergreen/game.py | 3 ++- bot/exts/evergreen/minesweeper.py | 3 ++- bot/exts/evergreen/movie.py | 3 ++- bot/exts/evergreen/snakes/_snakes_cog.py | 3 ++- bot/exts/evergreen/space.py | 3 ++- bot/exts/evergreen/status_codes.py | 3 ++- bot/exts/utils/extensions.py | 12 ++++++++---- bot/exts/valentines/be_my_valentine.py | 3 ++- 10 files changed, 26 insertions(+), 13 deletions(-) (limited to 'bot') diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index 29902306..bf008ee9 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -51,7 +51,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @adventofcode_group.command( name="subscribe", diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py index 99f71218..40bf83e8 100644 --- a/bot/exts/evergreen/emoji.py +++ b/bot/exts/evergreen/emoji.py @@ -75,7 +75,8 @@ class Emojis(commands.Cog): if emoji is not None: await ctx.invoke(self.info_command, emoji) else: - await ctx.send_help(ctx.command) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @emoji_group.command(name="count", aliases=("c",)) async def count_command(self, ctx: commands.Context, *, category_query: str = None) -> None: diff --git a/bot/exts/evergreen/game.py b/bot/exts/evergreen/game.py index d37be0e2..d49a8858 100644 --- a/bot/exts/evergreen/game.py +++ b/bot/exts/evergreen/game.py @@ -234,7 +234,8 @@ class Games(Cog): """ # When user didn't specified genre, send help message if genre is None: - await ctx.send_help("games") + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) return # Capitalize genre for check diff --git a/bot/exts/evergreen/minesweeper.py b/bot/exts/evergreen/minesweeper.py index 286ac7a5..06a75c2b 100644 --- a/bot/exts/evergreen/minesweeper.py +++ b/bot/exts/evergreen/minesweeper.py @@ -83,7 +83,8 @@ 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) + help_command = ctx.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @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..238ab038 100644 --- a/bot/exts/evergreen/movie.py +++ b/bot/exts/evergreen/movie.py @@ -73,7 +73,8 @@ class Movie(Cog): try: result = await self.get_movies_list(self.http_session, MovieGenres[genre].value, 1) except KeyError: - await ctx.send_help('movies') + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) 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..819a98b2 100644 --- a/bot/exts/evergreen/snakes/_snakes_cog.py +++ b/bot/exts/evergreen/snakes/_snakes_cog.py @@ -440,7 +440,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @bot_has_permissions(manage_messages=True) @snakes_group.command(name='antidote') diff --git a/bot/exts/evergreen/space.py b/bot/exts/evergreen/space.py index bc8e3118..e388e13f 100644 --- a/bot/exts/evergreen/space.py +++ b/bot/exts/evergreen/space.py @@ -63,7 +63,8 @@ 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") + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @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..d06724eb 100644 --- a/bot/exts/evergreen/status_codes.py +++ b/bot/exts/evergreen/status_codes.py @@ -17,7 +17,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @http_status_group.command(name='cat') async def http_cat(self, ctx: commands.Context, code: int) -> None: diff --git a/bot/exts/utils/extensions.py b/bot/exts/utils/extensions.py index bb22c353..f7ff2396 100644 --- a/bot/exts/utils/extensions.py +++ b/bot/exts/utils/extensions.py @@ -77,7 +77,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @extensions_group.command(name="load", aliases=("l",)) async def load_command(self, ctx: Context, *extensions: Extension) -> None: @@ -87,7 +88,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, "extensions", ctx.command.name) return if "*" in extensions or "**" in extensions: @@ -104,7 +106,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, "extensions", ctx.command.name) return blacklisted = "\n".join(UNLOAD_BLACKLIST & set(extensions)) @@ -130,7 +133,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, "extensions", ctx.command.name) return if "**" in extensions: diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index f3392bcb..59bd42d3 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -43,7 +43,8 @@ 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) + help_command = self.bot.get_command("help") + await ctx.invoke(help_command, ctx.command.name) @lovefest_role.command(name="sub") async def add_role(self, ctx: commands.Context) -> None: -- cgit v1.2.3 From cc72d484115a8acebf0fafe8bb332817168d3acd Mon Sep 17 00:00:00 2001 From: ToxicKidz <78174417+ToxicKidz@users.noreply.github.com> Date: Fri, 12 Mar 2021 19:17:39 -0500 Subject: make utility invoke_help_command function --- bot/exts/christmas/advent_of_code/_cog.py | 4 ++-- bot/exts/evergreen/emoji.py | 4 ++-- bot/exts/evergreen/game.py | 4 ++-- bot/exts/evergreen/minesweeper.py | 4 ++-- bot/exts/evergreen/movie.py | 4 ++-- bot/exts/evergreen/snakes/_snakes_cog.py | 4 ++-- bot/exts/evergreen/space.py | 4 ++-- bot/exts/evergreen/status_codes.py | 4 ++-- bot/exts/utils/extensions.py | 14 +++++--------- bot/exts/valentines/be_my_valentine.py | 4 ++-- bot/utils/extensions.py | 12 ++++++++++++ 11 files changed, 35 insertions(+), 27 deletions(-) (limited to 'bot') diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index bf008ee9..6ba5c2af 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__) @@ -51,8 +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: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @adventofcode_group.command( name="subscribe", diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py index 40bf83e8..042e539d 100644 --- a/bot/exts/evergreen/emoji.py +++ b/bot/exts/evergreen/emoji.py @@ -11,6 +11,7 @@ from discord.ext import commands from bot.constants import Colours, ERROR_REPLIES from bot.utils.pagination import LinePaginator from bot.utils.time import time_since +from bot.utils.extensions import invoke_help_command log = logging.getLogger(__name__) @@ -75,8 +76,7 @@ class Emojis(commands.Cog): if emoji is not None: await ctx.invoke(self.info_command, emoji) else: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @emoji_group.command(name="count", aliases=("c",)) async def count_command(self, ctx: commands.Context, *, category_query: str = None) -> None: diff --git a/bot/exts/evergreen/game.py b/bot/exts/evergreen/game.py index d49a8858..ab4cae77 100644 --- a/bot/exts/evergreen/game.py +++ b/bot/exts/evergreen/game.py @@ -16,6 +16,7 @@ from bot.bot import Bot from bot.constants import STAFF_ROLES, Tokens from bot.utils.decorators import with_role from bot.utils.pagination import ImagePaginator, LinePaginator +from bot.utils.extensions import invoke_help_command # Base URL of IGDB API BASE_URL = "https://api.igdb.com/v4" @@ -234,8 +235,7 @@ class Games(Cog): """ # When user didn't specified genre, send help message if genre is None: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) return # Capitalize genre for check diff --git a/bot/exts/evergreen/minesweeper.py b/bot/exts/evergreen/minesweeper.py index 06a75c2b..cfe7150e 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,8 +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.""" - help_command = ctx.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @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 238ab038..9aa3aea7 100644 --- a/bot/exts/evergreen/movie.py +++ b/bot/exts/evergreen/movie.py @@ -10,6 +10,7 @@ from discord.ext.commands import Bot, Cog, Context, group from bot.constants import Tokens from bot.utils.pagination import ImagePaginator +from bot.utils.extensions import invoke_help_command # Define base URL of TMDB BASE_URL = "https://api.themoviedb.org/3/" @@ -73,8 +74,7 @@ class Movie(Cog): try: result = await self.get_movies_list(self.http_session, MovieGenres[genre].value, 1) except KeyError: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) 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 819a98b2..d0e60819 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,8 +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.""" - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @bot_has_permissions(manage_messages=True) @snakes_group.command(name='antidote') diff --git a/bot/exts/evergreen/space.py b/bot/exts/evergreen/space.py index e388e13f..305d6721 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,8 +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.""" - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @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 d06724eb..a037e117 100644 --- a/bot/exts/evergreen/status_codes.py +++ b/bot/exts/evergreen/status_codes.py @@ -2,6 +2,7 @@ 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,8 +18,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: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @http_status_group.command(name='cat') async def http_cat(self, ctx: commands.Context, code: int) -> None: diff --git a/bot/exts/utils/extensions.py b/bot/exts/utils/extensions.py index f7ff2396..9c126a7b 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, unqualify, invoke_help_command from bot.utils.pagination import LinePaginator log = logging.getLogger(__name__) @@ -77,8 +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.""" - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @extensions_group.command(name="load", aliases=("l",)) async def load_command(self, ctx: Context, *extensions: Extension) -> None: @@ -88,8 +87,7 @@ class Extensions(commands.Cog): If '\*' or '\*\*' is given as the name, all unloaded extensions will be loaded. """ # noqa: W605 if not extensions: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, "extensions", ctx.command.name) + await invoke_help_command(ctx, "extensions", ctx.command.name) return if "*" in extensions or "**" in extensions: @@ -106,8 +104,7 @@ class Extensions(commands.Cog): If '\*' or '\*\*' is given as the name, all loaded extensions will be unloaded. """ # noqa: W605 if not extensions: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, "extensions", ctx.command.name) + await invoke_help_command(ctx, "extensions", ctx.command.name) return blacklisted = "\n".join(UNLOAD_BLACKLIST & set(extensions)) @@ -133,8 +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: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, "extensions", ctx.command.name) + await invoke_help_command(ctx, "extensions", ctx.command.name) return if "**" in extensions: diff --git a/bot/exts/valentines/be_my_valentine.py b/bot/exts/valentines/be_my_valentine.py index 59bd42d3..d5cc8644 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,8 +44,7 @@ class BeMyValentine(commands.Cog): 2) use the command \".lovefest unsub\" to get rid of the lovefest role. """ if not ctx.invoked_subcommand: - help_command = self.bot.get_command("help") - await ctx.invoke(help_command, ctx.command.name) + await invoke_help_command(ctx, ctx.command.name) @lovefest_role.command(name="sub") async def add_role(self, ctx: commands.Context) -> None: diff --git a/bot/utils/extensions.py b/bot/utils/extensions.py index 50350ea8..56f6dd00 100644 --- a/bot/utils/extensions.py +++ b/bot/utils/extensions.py @@ -4,6 +4,7 @@ import pkgutil from typing import Iterator, NoReturn from bot import exts +from discord.ext.commands import Context def unqualify(name: str) -> str: @@ -31,4 +32,15 @@ def walk_extensions() -> Iterator[str]: yield module.name +async def invoke_help_command(ctx: Context, *commands: str) -> None: + """Invoke the help command, and will use the default help command + if the help exten is not loaded. + """ + + if 'bot.exts.evergreen.help' in ctx.bot.extensions: + help_command = ctx.bot.get_command('help') + await ctx.invoke(help_command, *commands) + return + await ctx.send_help(''.join(commands)) + EXTENSIONS = frozenset(walk_extensions()) -- cgit v1.2.3 From ccf7d118eb2dea996b10bf0a4cfca977c452f636 Mon Sep 17 00:00:00 2001 From: ToxicKidz <78174417+ToxicKidz@users.noreply.github.com> Date: Fri, 12 Mar 2021 20:01:24 -0500 Subject: Make flake8 happy. --- bot/exts/evergreen/game.py | 2 +- bot/exts/evergreen/status_codes.py | 1 + bot/exts/utils/extensions.py | 2 +- bot/utils/extensions.py | 7 ++----- 4 files changed, 5 insertions(+), 7 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/game.py b/bot/exts/evergreen/game.py index ab4cae77..a6bfecaa 100644 --- a/bot/exts/evergreen/game.py +++ b/bot/exts/evergreen/game.py @@ -15,8 +15,8 @@ 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.pagination import ImagePaginator, LinePaginator from bot.utils.extensions import invoke_help_command +from bot.utils.pagination import ImagePaginator, LinePaginator # Base URL of IGDB API BASE_URL = "https://api.igdb.com/v4" diff --git a/bot/exts/evergreen/status_codes.py b/bot/exts/evergreen/status_codes.py index a037e117..127f3424 100644 --- a/bot/exts/evergreen/status_codes.py +++ b/bot/exts/evergreen/status_codes.py @@ -2,6 +2,7 @@ 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" diff --git a/bot/exts/utils/extensions.py b/bot/exts/utils/extensions.py index 9c126a7b..4bd606b0 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, invoke_help_command +from bot.utils.extensions import EXTENSIONS, invoke_help_command, unqualify from bot.utils.pagination import LinePaginator log = logging.getLogger(__name__) diff --git a/bot/utils/extensions.py b/bot/utils/extensions.py index 56f6dd00..afc57383 100644 --- a/bot/utils/extensions.py +++ b/bot/utils/extensions.py @@ -1,10 +1,10 @@ +from discord.ext.commands import Context import importlib import inspect import pkgutil from typing import Iterator, NoReturn from bot import exts -from discord.ext.commands import Context def unqualify(name: str) -> str: @@ -33,10 +33,7 @@ def walk_extensions() -> Iterator[str]: async def invoke_help_command(ctx: Context, *commands: str) -> None: - """Invoke the help command, and will use the default help command - if the help exten is not loaded. - """ - + """Invoke the help command or default help command if help extensions is not loaded.""" if 'bot.exts.evergreen.help' in ctx.bot.extensions: help_command = ctx.bot.get_command('help') await ctx.invoke(help_command, *commands) -- cgit v1.2.3 From b395c05cc0885c427afab80e914d098dd9edc742 Mon Sep 17 00:00:00 2001 From: ToxicKidz <78174417+ToxicKidz@users.noreply.github.com> Date: Fri, 12 Mar 2021 20:06:56 -0500 Subject: Make flake8 happy again. --- bot/exts/evergreen/emoji.py | 2 +- bot/exts/evergreen/movie.py | 2 +- bot/utils/extensions.py | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py index 042e539d..e55a11ad 100644 --- a/bot/exts/evergreen/emoji.py +++ b/bot/exts/evergreen/emoji.py @@ -9,9 +9,9 @@ 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 -from bot.utils.extensions import invoke_help_command log = logging.getLogger(__name__) diff --git a/bot/exts/evergreen/movie.py b/bot/exts/evergreen/movie.py index 9aa3aea7..63ce81da 100644 --- a/bot/exts/evergreen/movie.py +++ b/bot/exts/evergreen/movie.py @@ -9,8 +9,8 @@ from discord import Embed from discord.ext.commands import Bot, Cog, Context, group from bot.constants import Tokens -from bot.utils.pagination import ImagePaginator from bot.utils.extensions import invoke_help_command +from bot.utils.pagination import ImagePaginator # Define base URL of TMDB BASE_URL = "https://api.themoviedb.org/3/" diff --git a/bot/utils/extensions.py b/bot/utils/extensions.py index afc57383..ffa8a936 100644 --- a/bot/utils/extensions.py +++ b/bot/utils/extensions.py @@ -1,9 +1,10 @@ -from discord.ext.commands import Context import importlib import inspect import pkgutil from typing import Iterator, NoReturn +from discord.ext.commands import Context + from bot import exts -- cgit v1.2.3 From 9ec1cf9b983a69c381507f82c317e0465eecdc35 Mon Sep 17 00:00:00 2001 From: ToxicKidz <78174417+ToxicKidz@users.noreply.github.com> Date: Sat, 13 Mar 2021 10:16:31 -0500 Subject: make invoke_help_command only take ctx --- bot/exts/christmas/advent_of_code/_cog.py | 2 +- bot/exts/evergreen/emoji.py | 2 +- bot/exts/evergreen/game.py | 2 +- bot/exts/evergreen/minesweeper.py | 2 +- bot/exts/evergreen/movie.py | 2 +- bot/exts/evergreen/snakes/_snakes_cog.py | 2 +- bot/exts/evergreen/space.py | 2 +- bot/exts/evergreen/status_codes.py | 2 +- bot/exts/utils/extensions.py | 8 ++++---- bot/exts/valentines/be_my_valentine.py | 2 +- bot/utils/extensions.py | 6 +++--- 11 files changed, 16 insertions(+), 16 deletions(-) (limited to 'bot') diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index 6ba5c2af..dc3d7616 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -52,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 invoke_help_command(ctx, ctx.command.name) + await invoke_help_command(ctx) @adventofcode_group.command( name="subscribe", diff --git a/bot/exts/evergreen/emoji.py b/bot/exts/evergreen/emoji.py index e55a11ad..fa3044e3 100644 --- a/bot/exts/evergreen/emoji.py +++ b/bot/exts/evergreen/emoji.py @@ -76,7 +76,7 @@ class Emojis(commands.Cog): if emoji is not None: await ctx.invoke(self.info_command, emoji) else: - await invoke_help_command(ctx, ctx.command.name) + 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: diff --git a/bot/exts/evergreen/game.py b/bot/exts/evergreen/game.py index a6bfecaa..068d3f68 100644 --- a/bot/exts/evergreen/game.py +++ b/bot/exts/evergreen/game.py @@ -235,7 +235,7 @@ class Games(Cog): """ # When user didn't specified genre, send help message if genre is None: - await invoke_help_command(ctx, ctx.command.name) + 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 cfe7150e..3031debc 100644 --- a/bot/exts/evergreen/minesweeper.py +++ b/bot/exts/evergreen/minesweeper.py @@ -84,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 invoke_help_command(ctx, ctx.command.name) + 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 63ce81da..b3bfe998 100644 --- a/bot/exts/evergreen/movie.py +++ b/bot/exts/evergreen/movie.py @@ -74,7 +74,7 @@ class Movie(Cog): try: result = await self.get_movies_list(self.http_session, MovieGenres[genre].value, 1) except KeyError: - await invoke_help_command(ctx, ctx.command.name) + 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 d0e60819..3732b559 100644 --- a/bot/exts/evergreen/snakes/_snakes_cog.py +++ b/bot/exts/evergreen/snakes/_snakes_cog.py @@ -441,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 invoke_help_command(ctx, ctx.command.name) + await invoke_help_command(ctx) @bot_has_permissions(manage_messages=True) @snakes_group.command(name='antidote') diff --git a/bot/exts/evergreen/space.py b/bot/exts/evergreen/space.py index 305d6721..323ff659 100644 --- a/bot/exts/evergreen/space.py +++ b/bot/exts/evergreen/space.py @@ -64,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 invoke_help_command(ctx, ctx.command.name) + 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 127f3424..7c00fe20 100644 --- a/bot/exts/evergreen/status_codes.py +++ b/bot/exts/evergreen/status_codes.py @@ -19,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 invoke_help_command(ctx, ctx.command.name) + 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/utils/extensions.py b/bot/exts/utils/extensions.py index 4bd606b0..64e404d2 100644 --- a/bot/exts/utils/extensions.py +++ b/bot/exts/utils/extensions.py @@ -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 invoke_help_command(ctx, ctx.command.name) + 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 invoke_help_command(ctx, "extensions", ctx.command.name) + 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 invoke_help_command(ctx, "extensions", ctx.command.name) + 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 invoke_help_command(ctx, "extensions", ctx.command.name) + 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 d5cc8644..09591cf8 100644 --- a/bot/exts/valentines/be_my_valentine.py +++ b/bot/exts/valentines/be_my_valentine.py @@ -44,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 invoke_help_command(ctx, ctx.command.name) + await invoke_help_command(ctx) @lovefest_role.command(name="sub") async def add_role(self, ctx: commands.Context) -> None: diff --git a/bot/utils/extensions.py b/bot/utils/extensions.py index ffa8a936..459588a1 100644 --- a/bot/utils/extensions.py +++ b/bot/utils/extensions.py @@ -33,12 +33,12 @@ def walk_extensions() -> Iterator[str]: yield module.name -async def invoke_help_command(ctx: Context, *commands: str) -> None: +async def invoke_help_command(ctx: Context) -> None: """Invoke the help command or default help command if help extensions is not loaded.""" if 'bot.exts.evergreen.help' in ctx.bot.extensions: help_command = ctx.bot.get_command('help') - await ctx.invoke(help_command, *commands) + await ctx.invoke(help_command, ctx.command.qualified_name) return - await ctx.send_help(''.join(commands)) + await ctx.send_help(ctx.command) EXTENSIONS = frozenset(walk_extensions()) -- cgit v1.2.3 From 87219f3a0c299d62a95341a90237715f1cff64d8 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 13 Mar 2021 20:13:12 +0000 Subject: master => main --- .github/workflows/build.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/sentry_release.yaml | 4 ++-- CONTRIBUTING.md | 8 ++++---- README.md | 10 +++++----- bot/exts/christmas/advent_of_code/_helpers.py | 2 +- bot/exts/evergreen/source.py | 2 +- bot/resources/halloween/spooky_rating.json | 18 +++++++++--------- bot/utils/time.py | 2 +- 9 files changed, 25 insertions(+), 25 deletions(-) (limited to 'bot') diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9d12cd10..08721dfd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -4,7 +4,7 @@ on: workflow_run: workflows: ["Lint"] branches: - - master + - main types: - completed diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a5f45255..7f157da3 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -3,7 +3,7 @@ name: Lint on: push: branches: - - master + - main pull_request: diff --git a/.github/workflows/sentry_release.yaml b/.github/workflows/sentry_release.yaml index 0e02dd0c..3d15e01e 100644 --- a/.github/workflows/sentry_release.yaml +++ b/.github/workflows/sentry_release.yaml @@ -3,14 +3,14 @@ name: Create Sentry release on: push: branches: - - master + - main jobs: create_sentry_release: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@master + uses: actions/checkout@main - name: Create a Sentry.io release uses: tclindner/sentry-releases-action@v1.2.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7cf83db5..3a1803e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Sir Lancebot is a community project for the Python Discord community over at https://discord.gg/python. We will be providing support for those of you who are new to Git, and this project is to be considered educational. -Our projects are open-source and are automatically deployed whenever commits are pushed to the `master` branch on each repository, so we've created a set of guidelines in order to keep everything clean and in working order. +Our projects are open-source and are automatically deployed whenever commits are pushed to the `main` branch on each repository, so we've created a set of guidelines in order to keep everything clean and in working order. Note that contributions may be rejected on the basis of a contributor failing to follow these guidelines. @@ -12,7 +12,7 @@ Note that contributions may be rejected on the basis of a contributor failing to 2. Your pull request must solve an issue created or approved by a staff member. These will be labeled with the `approved` label. Feel free to suggest issues of your own, which staff can review for approval. 3. **No force-pushes** or modifying the Git history in any way. 4. If you have direct access to the repository, **create a branch for your changes** and create a pull request for that branch. If not, create a branch on a fork of the repository and create a pull request from there. - * It's common practice for a repository to reject direct pushes to `master`, so make branching a habit! + * It's common practice for a repository to reject direct pushes to `main`, so make branching a habit! * If PRing from your own fork, **ensure that "Allow edits from maintainers" is checked**. This gives permission for maintainers to commit changes directly to your fork, speeding up the review process. 5. **Adhere to the prevailing code style**, which we enforce using [`flake8`](http://flake8.pycqa.org/en/latest/index.html) and [`pre-commit`](https://pre-commit.com/). * Run `flake8` and `pre-commit` against your code [**before** you push it](https://soundcloud.com/lemonsaurusrex/lint-before-you-push). Your commit will be rejected by the build server if it fails to lint. @@ -22,7 +22,7 @@ Note that contributions may be rejected on the basis of a contributor failing to * Avoid making minor commits for fixing typos or linting errors. Since you've already set up a `pre-commit` hook to run the linting pipeline before a commit, you shouldn't be committing linting issues anyway. * A more in-depth guide to writing great commit messages can be found in Chris Beam's [*How to Write a Git Commit Message*](https://chris.beams.io/posts/git-commit/) 7. **Avoid frequent pushes to the main repository**. This goes for PRs opened against your fork as well. Our test build pipelines are triggered every time a push to the repository (or PR) is made. Try to batch your commits until you've finished working for that session, or you've reached a point where collaborators need your commits to continue their own work. This also provides you the opportunity to amend commits for minor changes rather than having to commit them on their own because you've already pushed. - * This includes merging master into your branch. Try to leave merging from master for after your PR passes review; a maintainer will bring your PR up to date before merging. Exceptions to this include: resolving merge conflicts, needing something that was pushed to master for your branch, or something was pushed to master that could potentionally affect the functionality of what you're writing. + * This includes merging main into your branch. Try to leave merging from main for after your PR passes review; a maintainer will bring your PR up to date before merging. Exceptions to this include: resolving merge conflicts, needing something that was pushed to main for your branch, or something was pushed to main that could potentionally affect the functionality of what you're writing. 8. **Don't fight the framework**. Every framework has its flaws, but the frameworks we've picked out have been carefully chosen for their particular merits. If you can avoid it, please resist reimplementing swathes of framework logic - the work has already been done for you! 9. If someone is working on an issue or pull request, **do not open your own pull request for the same task**. Instead, collaborate with the author(s) of the existing pull request. Duplicate PRs opened without communicating with the other author(s) and/or PyDis staff will be closed. Communication is key, and there's no point in two separate implementations of the same thing. * One option is to fork the other contributor's repository and submit your changes to their branch with your own pull request. We suggest following these guidelines when interacting with their repository as well. @@ -39,7 +39,7 @@ All projects evolve over time, and this contribution guide is no different. This ## Supplemental Information ### Developer Environment -Sir Lancebot utilizes [Pipenv](https://pipenv.readthedocs.io/en/latest/) for installation and dependency management. For users unfamiliar with the Pipenv workflow, Pipenv's documentation provides a [Basic Usage](https://pipenv.readthedocs.io/en/latest/basics/) tutorial, along with some of the more advanced workflows. A project-specific installation guide can be found in [Sir Lancebot's README](https://github.com/python-discord/sir-lancebot/blob/master/README.md). +Sir Lancebot utilizes [Pipenv](https://pipenv.readthedocs.io/en/latest/) for installation and dependency management. For users unfamiliar with the Pipenv workflow, Pipenv's documentation provides a [Basic Usage](https://pipenv.readthedocs.io/en/latest/basics/) tutorial, along with some of the more advanced workflows. A project-specific installation guide can be found in [Sir Lancebot's README](https://github.com/python-discord/sir-lancebot/blob/main/README.md). When pulling down changes from GitHub, remember to sync your environment using `pipenv sync --dev` to ensure you're using the most up-to-date versions the project's dependencies. diff --git a/README.md b/README.md index 6b453879..11b46aac 100755 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ Before you start, please take some time to read through our [contributing guidel See [Sir Lancebot's Wiki](https://pythondiscord.com/pages/contributing/sir-lancebot/) for in-depth guides on getting started with the project! -[1]:https://github.com/python-discord/sir-lancebot/workflows/Lint/badge.svg?branch=master -[2]:https://github.com/python-discord/sir-lancebot/actions?query=workflow%3ALint+branch%3Amaster -[3]:https://github.com/python-discord/sir-lancebot/workflows/Build/badge.svg?branch=master -[4]:https://github.com/python-discord/sir-lancebot/actions?query=workflow%3ABuild+branch%3Amaster -[5]: https://raw.githubusercontent.com/python-discord/branding/master/logos/badge/badge_github.svg +[1]:https://github.com/python-discord/sir-lancebot/workflows/Lint/badge.svg?branch=main +[2]:https://github.com/python-discord/sir-lancebot/actions?query=workflow%3ALint+branch%3Amain +[3]:https://github.com/python-discord/sir-lancebot/workflows/Build/badge.svg?branch=main +[4]:https://github.com/python-discord/sir-lancebot/actions?query=workflow%3ABuild+branch%3Amain +[5]: https://raw.githubusercontent.com/python-discord/branding/main/logos/badge/badge_github.svg [6]: https://discord.gg/python 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/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/resources/halloween/spooky_rating.json b/bot/resources/halloween/spooky_rating.json index 533e7107..8e3e66bb 100644 --- a/bot/resources/halloween/spooky_rating.json +++ b/bot/resources/halloween/spooky_rating.json @@ -2,46 +2,46 @@ "-1": { "title": "\uD83D\uDD6F You're not scarin' anyone \uD83D\uDD6F", "text": "No matter what you say or do, nobody even flinches when you try to scare them. Was your costume this year only a white sheet with holes for eyes? Or did you even bother with a costume at all? Either way, don't expect too many treats when going from door-to-door.", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/candle.jpeg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/candle.jpeg" }, "5": { "title": "\uD83D\uDC76 Like taking candy from a baby \uD83D\uDC76", "text": "Your scaring will probably make a baby cry... but that's the limit on your frightening powers. Be careful not to get to the point where everyone's running away from you because they don't like you, not because they're scared of you.", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/baby.jpeg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/baby.jpeg" }, "20": { "title": "\uD83C\uDFDA You're skills are forming... \uD83C\uDFDA", "text": "As you become the Devil's apprentice, you begin to make people jump every time you sneak up on them. A good start, but you have to learn not to wear the same costume every year until it doesn't fit you. People will notice you and your prowess will decrease.", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/tiger.jpeg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/tiger.jpeg" }, "30": { "title": "\uD83D\uDC80 Picture Perfect... \uD83D\uDC80", "text": "You've nailed the costume this year! You look suuuper scary! Now make sure to play the part and act out your costume and you'll be sure to give a few people a massive fright!", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/costume.jpeg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/costume.jpeg" }, "50": { "title": "\uD83D\uDC7B Uhm... are you human \uD83D\uDC7B", "text": "Uhm... you're too good to be human and now you're beginning to sound like a ghost. You're almost invisible when haunting and nobody truly knows where you are at any given time. But they will always scream at the sound of a ghost...", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/ghost.jpeg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/ghost.jpeg" }, "65": { "title": "\uD83C\uDF83 That potion can't be real \uD83C\uDF83", "text": "You're carrying... some... unknown liquids and no one knows who they are but yourself. Be careful on who you use these powerful spells on, because no Mage has the power to do any irreversible enchantments because even you won't know what will happen to these mortals.", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/necromancer.jepg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/necromancer.jepg" }, "80": { "title": "\uD83E\uDD21 The most sinister face \uD83E\uDD21", "text": "Who knew something intended to be playful could be so menacing... Especially other people seeing you in their nightmares, continuing to haunt them day by day, stuck in their head throughout the entire year. Make sure to pull a face they will never forget.", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/clown.jpeg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/clown.jpeg" }, "95": { "title": "\uD83D\uDE08 The Devil's Accomplice \uD83D\uDE08", "text": "Imagine being allies with the most evil character with an aim to scare people to death. Force people to suffer as they proceed straight to hell to meet your boss and best friend. Not even you know the power He has...", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/jackolantern.jpg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/jackolantern.jpg" }, "100": { "title":"\uD83D\uDC7F The Devil Himself \uD83D\uDC7F", "text": "You are the evillest creature in existence to scare anyone and everyone humanly possible. The reason your underlings are called mortals is that they die. With your help, they die a lot quicker. With all the evil power in the universe, you know what to do.", - "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/master/bot/resources/halloween/spookyrating/devil.jpeg" + "image": "https://raw.githubusercontent.com/python-discord/sir-lancebot/main/bot/resources/halloween/spookyrating/devil.jpeg" } } diff --git a/bot/utils/time.py b/bot/utils/time.py index 3c57e126..fbf2fd21 100644 --- a/bot/utils/time.py +++ b/bot/utils/time.py @@ -3,7 +3,7 @@ import datetime from dateutil.relativedelta import relativedelta -# All these functions are from https://github.com/python-discord/bot/blob/master/bot/utils/time.py +# All these functions are from https://github.com/python-discord/bot/blob/main/bot/utils/time.py def _stringify_time_unit(value: int, unit: str) -> str: """ Returns a string to represent a value and time unit, ensuring that it uses the right plural form of the unit. -- cgit v1.2.3 From 0e074b798dd8b47c86043f85b8fac71b76cb8d1b Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Sat, 13 Mar 2021 23:26:24 +0300 Subject: Removes Unused Roles & Channels Removes roles and channels from constants.py that are not used anywhere in the project. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/constants.py | 25 ------------------------- bot/exts/christmas/advent_of_code/_cog.py | 2 +- 2 files changed, 1 insertion(+), 26 deletions(-) (limited to 'bot') diff --git a/bot/constants.py b/bot/constants.py index b8e30a7c..416dd0e7 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -94,33 +94,18 @@ class Branding: class Channels(NamedTuple): - admins = 365960823622991872 advent_of_code = int(environ.get("AOC_CHANNEL_ID", 782715290437943306)) advent_of_code_commands = int(environ.get("AOC_COMMANDS_CHANNEL_ID", 607247579608121354)) - announcements = int(environ.get("CHANNEL_ANNOUNCEMENTS", 354619224620138496)) - big_brother_logs = 468507907357409333 bot = 267659945086812160 - checkpoint_test = 422077681434099723 organisation = 551789653284356126 - devalerts = 460181980097675264 devlog = int(environ.get("CHANNEL_DEVLOG", 622895325144940554)) dev_contrib = 635950537262759947 - dev_branding = 753252897059373066 - helpers = 385474242440986624 - message_log = 467752170159079424 - mod_alerts = 473092532147060736 - modlog = 282638479504965634 mod_meta = 775412552795947058 mod_tools = 775413915391098921 off_topic_0 = 291284109232308226 off_topic_1 = 463035241142026251 off_topic_2 = 463035268514185226 - python = 267624335836053506 - reddit = 458224812528238616 community_bot_commands = int(environ.get("CHANNEL_COMMUNITY_BOT_COMMANDS", 607247579608121354)) - staff_lounge = 464905259261755392 - verification = 352442727016693763 - python_discussion = 267624335836053506 hacktoberfest_2020 = 760857070781071431 voice_chat_0 = 412357430186344448 voice_chat_1 = 799647045886541885 @@ -248,20 +233,10 @@ if Client.month_override is not None: class Roles(NamedTuple): admin = int(environ.get("BOT_ADMIN_ROLE_ID", 267628507062992896)) - announcements = 463658397560995840 - champion = 430492892331769857 - contributor = 295488872404484098 - devops = 409416496733880320 - jammer = 423054537079783434 moderator = 267629731250176001 - muted = 277914926603829249 owner = 267627879762755584 - verified = 352427296948486144 helpers = int(environ.get("ROLE_HELPERS", 267630620367257601)) - rockstars = 458226413825294336 core_developers = 587606783669829632 - events_lead = 778361735739998228 - everyone_role = 267624335836053506 class Tokens(NamedTuple): diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index dc3d7616..8376987d 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -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",), -- cgit v1.2.3