From 2360f21d6631f9282e8107e61736f2971cc7ebc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Fri, 27 Apr 2018 15:08:31 +0200 Subject: [PATCH 01/27] Added the random_snake_name feature, created by Iceman --- bot/__main__.py | 1 + bot/cogs/snakes.py | 105 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 bot/cogs/snakes.py diff --git a/bot/__main__.py b/bot/__main__.py index 100350d489..3d722545e0 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -40,6 +40,7 @@ bot.load_extension("bot.cogs.fun") bot.load_extension("bot.cogs.hiphopify") # bot.load_extension("bot.cogs.math") +bot.load_extension("bot.cogs.snakes") bot.load_extension("bot.cogs.tags") bot.load_extension("bot.cogs.verification") diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py new file mode 100644 index 0000000000..ed514fbea8 --- /dev/null +++ b/bot/cogs/snakes.py @@ -0,0 +1,105 @@ +import logging +import random +import string + +from discord import Colour, Embed +from discord.ext.commands import AutoShardedBot, Context, command + +log = logging.getLogger(__name__) + + +class Snakes: + """ + Commands related to snakes. These were created by our + community during the first code jam. + + More information can be found in the code-jam-1 repo. + + https://github.com/discord-python/code-jam-1 + """ + + def __init__(self, bot: AutoShardedBot): + self.bot = bot + self.SNAKES = ['black cobra', 'children\'s python'] # temporary + + def get_snake_name(self) -> str: + """ + Gets a random snake name. + :return: A random snake name, as a string. + """ + return random.choice(self.SNAKES) + + @command(name="snakes.name_gen()", aliases=["snakes.name_gen"]) + async def random_snake_name(self, ctx: Context, name: str = None): + """ + Slices the users name at the last vowel (or second last if the name + ends with a vowel), and then combines it with a random snake name, + which is sliced at the first vowel (or second if the name starts with + a vowel). + + If the name contains no vowels, it just appends the snakename + to the end of the name. + + Examples: + lemon + anaconda = lemoconda + krzsn + anaconda = krzsnconda + gdude + anaconda = gduconda + aperture + anaconda = apertuconda + lucy + python = luthon + joseph + taipan = joseipan + + This was written by Iceman, and modified for inclusion into the bot by lemon. + """ + + snake_name = self.get_snake_name() + snake_prefix = "" + + # Set aside every word in the snake name except the last. + if " " in snake_name: + snake_prefix = " ".join(snake_name.split()[:-1]) + snake_name = snake_name.split()[-1] + + # If no name is provided, use whoever called the command. + if name: + user_name = name + else: + user_name = ctx.author.display_name + + # Get the index of the vowel to slice the username at + user_slice_index = len(user_name) + for index, char in enumerate(reversed(user_name)): + if index == 0: + continue + if char.lower() in "aeiouy": + user_slice_index -= index + break + log.trace(f"name is {user_name}, index is {user_slice_index}") + + # Now, get the index of the vowel to slice the snake_name at + snake_slice_index = 0 + for index, char in enumerate(snake_name): + if index == 0: + continue + if char.lower() in "aeiouy": + snake_slice_index = index + 1 + break + log.trace(f"snake name is {snake_name}, index is {snake_slice_index}") + + # Combine! + snake_name = snake_name[snake_slice_index:] + user_name = user_name[:user_slice_index] + result = f"{snake_prefix} {user_name}{snake_name}" + result = string.capwords(result) + + # Embed and send + embed = Embed( + description=f"Your snake-name is **{result}**", + color=Colour.blurple() + ) + + return await ctx.send(embed=embed) + + +def setup(bot): + bot.add_cog(Snakes(bot)) + log.info("Cog loaded: Snakes") From c8c5ccaa0e4ff13b19de2d70214d323c4ced5e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Sat, 28 Apr 2018 19:57:01 +0200 Subject: [PATCH 02/27] Added Antidote to the snake_cog. --- bot/cogs/snakes.py | 164 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index ed514fbea8..d2484469b5 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,12 +1,26 @@ +import asyncio import logging import random import string -from discord import Colour, Embed +from discord import Colour, Embed, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command log = logging.getLogger(__name__) +# Antidote constants +FIRST_EMOJI = "\U0001F489" +SECOND_EMOJI = "\U0001F48A" +THIRD_EMOJI = "\u231B" +FOURTH_EMOJI = "\u2620" +FIFTH_EMOJI = "\u2697" +EMPTY = u'\u200b' +TICK_EMOJI = "\u2705" # Correct peg, correct hole +CROSS_EMOJI = "\u274C" # Wrong +BLANK_EMOJI = "\u26AA" # Correct peg, wrong hle +HOLE_EMOJI = "\u2B1C" +ANTIDOTE_EMOJI = [FIRST_EMOJI, SECOND_EMOJI, THIRD_EMOJI, FOURTH_EMOJI, FIFTH_EMOJI] + class Snakes: """ @@ -99,6 +113,154 @@ async def random_snake_name(self, ctx: Context, name: str = None): return await ctx.send(embed=embed) + @command(name="snakes.antidote()", alias=["snakes.antidote"]) + async def antidote(self, ctx: Context): + """ + Antidote - Can you create the antivenom before the patient dies? + + Rules: You have 4 ingredients for each antidote, you only have 10 attempts + Once you synthesize the antidote, you will be presented with 4 markers + Tick: This means you have a CORRECT ingredient in the CORRECT position + Circle: This means you have a CORRECT ingredient in the WRONG position + Cross: This means you have a WRONG ingredient in the WRONG position + + Info: The game automatically ends after 5 minutes inactivity. + You should only use each ingredient once. + + This game was created by Bisk and Runew0lf for the first PythonDiscord codejam. + """ + + # Check to see if the bot can remove reactions + if not ctx.channel.permissions_for(ctx.guild.me).manage_messages: + await ctx.send("Unable to start game as I dont have manage_messages permissions") + return + + # Initialize variables + antidote_tries = 0 + antidote_guess_count = 0 + antidote_guess_list = [] + guess_result = [] + board = [] + page_guess_list = [] + page_result_list = [] + win = False + + antidote_embed = Embed(color=ctx.me.color, title="Antidote") + antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) + + # Generate answer + antidote_answer = list(ANTIDOTE_EMOJI) # Duplicate list, not reference it + random.shuffle(antidote_answer) + antidote_answer.pop() + log.info(antidote_answer) + + # Begin initial board building + for i in range(0, 10): + page_guess_list.append(f"{HOLE_EMOJI} {HOLE_EMOJI} {HOLE_EMOJI} {HOLE_EMOJI}") + page_result_list.append(f"{CROSS_EMOJI} {CROSS_EMOJI} {CROSS_EMOJI} {CROSS_EMOJI}") + board.append(f"`{i+1:02d}` " + f"{page_guess_list[i]} - " + f"{page_result_list[i]}") + board.append(EMPTY) + antidote_embed.add_field(name="10 guesses remaining", value="\n".join(board)) + board_id = await ctx.send(embed=antidote_embed) # Display board + + # Add our player reactions + for emoji in ANTIDOTE_EMOJI: + await board_id.add_reaction(emoji) + + def event_check(reaction_: Reaction, user_: Member): + """ + Make sure that this reaction is what we want to operate on + """ + return ( + # Conditions for a successful pagination: + all(( + reaction_.message.id == board_id.id, # Reaction is on this message + reaction_.emoji in ANTIDOTE_EMOJI, # Reaction is one of the pagination emotes + user_.id != self.bot.user.id, # Reaction was not made by the Bot + user_.id == ctx.author.id # There were no restrictions + )) + ) + + # Begin main game loop + while not win and antidote_tries < 10: + try: + reaction, user = await ctx.bot.wait_for("reaction_add", timeout=300, check=event_check) + except asyncio.TimeoutError: + log.debug("Timed out waiting for a reaction") + break # We're done, no reactions for the last 5 minutes + + if antidote_tries < 10: + if antidote_guess_count < 4: + if reaction.emoji in ANTIDOTE_EMOJI: + antidote_guess_list.append(reaction.emoji) + antidote_guess_count += 1 + + if antidote_guess_count == 4: # Guesses complete + antidote_guess_count = 0 + page_guess_list[antidote_tries] = " ".join(antidote_guess_list) + log.info(f"Guess: {' '.join(antidote_guess_list)}") + + # Now check guess + for i in range(0, len(antidote_answer)): + if antidote_guess_list[i] == antidote_answer[i]: + guess_result.append(TICK_EMOJI) + elif antidote_guess_list[i] in antidote_answer: + guess_result.append(BLANK_EMOJI) + else: + guess_result.append(CROSS_EMOJI) + guess_result.sort() + page_result_list[antidote_tries] = " ".join(guess_result) + log.info(f"Guess Result: {' '.join(guess_result)}") + + # Rebuild the board + board = [] + for i in range(0, 10): + board.append(f"`{i+1:02d}` " + f"{page_guess_list[i]} - " + f"{page_result_list[i]}") + board.append(EMPTY) + + # Remove Reactions + for emoji in antidote_guess_list: + await board_id.remove_reaction(emoji, user) + + if antidote_guess_list == antidote_answer: + win = True + + antidote_tries += 1 + guess_result = [] + antidote_guess_list = [] + + antidote_embed.clear_fields() + antidote_embed.add_field(name=f"{10 - antidote_tries} " + f"guesses remaining", + value="\n".join(board)) + # Redisplay the board + await board_id.edit(embed=antidote_embed) + + # Winning / Ending Screen + if win is True: + antidote_embed = Embed(color=ctx.me.color, title="Antidote") + antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) + antidote_embed.set_image(url="https://i.makeagif.com/media/7-12-2015/Cj1pts.gif") + antidote_embed.add_field(name=f"You have created the snake antidote!", + value=f"The solution was: {' '.join(antidote_answer)}\n" + f"You had {10 - antidote_tries} tries remaining.") + await board_id.edit(embed=antidote_embed) + else: + antidote_embed = Embed(color=ctx.me.color, title="Antidote") + antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) + antidote_embed.set_image(url="https://media.giphy.com/media/ceeN6U57leAhi/giphy.gif") + antidote_embed.add_field(name=EMPTY, + value=f"Sorry you didnt make the antidote in time.\n" + f"The formula was {' '.join(antidote_answer)}") + await board_id.edit(embed=antidote_embed) + + log.debug("Ending pagination and removing all reactions...") + await board_id.clear_reactions() + def setup(bot): bot.add_cog(Snakes(bot)) From a9293e9f9de030712547fb44e240e8c3c65975a3 Mon Sep 17 00:00:00 2001 From: Wim-De-Clercq Date: Thu, 10 May 2018 17:51:14 +0200 Subject: [PATCH 03/27] Add the snake quiz from Team 7 - Mushy and Cardium - to the snakes cog. (#74) Original PR: https://github.com/discord-python/code-jam-1/pull/2 Completes task: https://app.clickup.com/754996/757069/t/2ww7u --- bot/cogs/snakes.py | 51 ++++++++++++++++++++- bot/constants.py | 4 ++ snake_questions.json | 104 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 snake_questions.json diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index d2484469b5..1a2cbeffc2 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,11 +1,16 @@ import asyncio +import json import logging import random import string +from typing import Dict -from discord import Colour, Embed, Member, Reaction +from discord import Colour, Embed, Member, Message, Reaction +from discord.abc import Messageable from discord.ext.commands import AutoShardedBot, Context, command +from bot import constants + log = logging.getLogger(__name__) # Antidote constants @@ -261,6 +266,50 @@ def event_check(reaction_: Reaction, user_: Member): log.debug("Ending pagination and removing all reactions...") await board_id.clear_reactions() + @command(name="snakes.quiz()", alias=["snakes.quiz"]) + async def quiz(self, ctx: Context): + """Asks a snake-related question in the chat and validates the user's guess.""" + channel = ctx.channel + answers_emoji = { + "a": "🇦", + "b": "🇧", + "c": "🇨", + "d": "🇩" + } + question, message = await self._post_quiz_question(answers_emoji, channel) + await self._validate_quiz_answer(answers_emoji, channel, ctx, question, message) + + async def _post_quiz_question(self, answers_emoji:Dict[str,str], channel:Messageable): + """Ask a random question from the snake_questions.json in the chat.""" + with open(f"{constants.PROJECT_ROOT}/snake_questions.json") as quizson: + questions = json.load(quizson) + question = questions["questions"][random.randint(0, 10)] + em = Embed(title=question["question"], + description="\n\n".join(f"{value}: {question[key]}" + for key, value in answers_emoji.items())) + quiz = await channel.send("", embed=em) + for emoji in answers_emoji.values(): + await quiz.add_reaction(emoji) + return question, quiz + + async def _validate_quiz_answer(self, answers_emoji:Dict[str,str], channel:Messageable, ctx:Context, + question:Dict[str,str], message:Message): + """Validates the author's guess to the given question.""" + def my_check(reaction, user): + return reaction.message.id == message.id and user == ctx.author and str(reaction.emoji) + + try: + reaction, user = await ctx.bot.wait_for("reaction_add", timeout=20.0, check=my_check) + except asyncio.TimeoutError: + await channel.send("Bah! You took too long.") + else: + answer = question["answerkey"] + if str(reaction.emoji) == answers_emoji[answer]: + await channel.send("That was correct! Well done!") + else: + await channel.send(f"That was incorrect! " + f"The correct answer was {answer}, unfortunately.") + def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/constants.py b/bot/constants.py index 6641a89bb7..49ec729daf 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -60,6 +60,10 @@ PAPERTRAIL_ADDRESS = os.environ.get("PAPERTRAIL_ADDRESS") or None PAPERTRAIL_PORT = int(os.environ.get("PAPERTRAIL_PORT") or 0) +# Paths +BOT_DIR = os.path.dirname(__file__) +PROJECT_ROOT = os.path.abspath(os.path.join(BOT_DIR, os.pardir)) + # Bot replies NEGATIVE_REPLIES = [ "Noooooo!!", diff --git a/snake_questions.json b/snake_questions.json new file mode 100644 index 0000000000..d3841da6d5 --- /dev/null +++ b/snake_questions.json @@ -0,0 +1,104 @@ +{ + "questions":[ + { + "id": 0, + "question": "How long have snakes been roaming the Earth?", + "a":"3 million years", + "b":"30 million years", + "c":"130 million years", + "d":"200 million years", + "answerkey":"c" + }, + { + "id": 1, + "question": "What characteristics do all snakes share?", + "a":"They are carnivoes", + "b":"They are all programming languages", + "c":"Cold-blooded", + "d":"They are both carnivores and cold-blooded", + "answerkey":"c" + }, + { + "id": 2, + "question": "How snakes hear?", + "a":"With small ears", + "b":"Through their skin", + "c":"Through their tail", + "d":"They don't use their ears at all", + "answerkey":"b" + }, + { + "id": 3, + "question": "What don't snakes see?", + "a":"Colour", + "b":"Light", + "c":"Both of the above", + "d":"Other snakes", + "answerkey":"a" + }, + { + "id": 4, + "question": "What unique vision ability do boas and pythons possess?", + "a":"Night vision", + "b":"Infared vision", + "c":"See through walls", + "d":"They don't have vision", + "answerkey":"b" + }, + { + "id": 5, + "question": "How does a snake smell?", + "a":"Through its nose", + "b":"Through its tongue", + "c":"Through its ears", + "d":"Both through its nose and its tongues", + "answerkey":"d" + }, + { + "id": 6, + "question": "Where are Jacobson's organs located in snakes?", + "a":"Mouth", + "b":"Tail", + "c":"Stomach", + "d":"Liver", + "answerkey":"a" + }, + { + "id": 7, + "question": "Snakes have very similar internal organs compared to humans. Snakes, however; lack the following:", + "a":"A diaphragm", + "b":"Intestines", + "c":"Lungs", + "d":"Kidney", + "answerkey":"a" + }, + { + "id": 8, + "question": "Snakes have different shaped lungs than humans. What do snakes have?", + "a":"An elongated right lung", + "b":"A small left lung", + "c":"Both of the above", + "d":"None of the above", + "answerkey":"c" + }, + { + "id": 9, + "question": "What's true about two-headed snakes?", + "a":"They're a myth!", + "b":"Rarely survive in the wild", + "c":"They're very dangerous", + "d":"They can kiss each other", + "answerkey":"b" + }, + { + "id": 10, + "question": "What substance covers a snake's skin?", + "a":"Calcium", + "b":"Keratin", + "c":"Copper", + "d":"Iron", + "answerkey":"b" + } + ] + +} \ No newline at end of file From 514a17f0f9237aec08dd3ee57874b9b32a412701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Thu, 10 May 2018 19:20:36 +0200 Subject: [PATCH 04/27] Cleaned up the snake quiz --- bot/cogs/snakes.py | 122 ++++++++++++++++++++++++------------------- snake_questions.json | 73 ++++++++++++++++++++++++-- 2 files changed, 137 insertions(+), 58 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 1a2cbeffc2..5825ead59c 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -3,10 +3,8 @@ import logging import random import string -from typing import Dict -from discord import Colour, Embed, Member, Message, Reaction -from discord.abc import Messageable +from discord import Colour, Embed, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command from bot import constants @@ -14,17 +12,32 @@ log = logging.getLogger(__name__) # Antidote constants -FIRST_EMOJI = "\U0001F489" -SECOND_EMOJI = "\U0001F48A" -THIRD_EMOJI = "\u231B" -FOURTH_EMOJI = "\u2620" -FIFTH_EMOJI = "\u2697" -EMPTY = u'\u200b' -TICK_EMOJI = "\u2705" # Correct peg, correct hole -CROSS_EMOJI = "\u274C" # Wrong -BLANK_EMOJI = "\u26AA" # Correct peg, wrong hle -HOLE_EMOJI = "\u2B1C" -ANTIDOTE_EMOJI = [FIRST_EMOJI, SECOND_EMOJI, THIRD_EMOJI, FOURTH_EMOJI, FIFTH_EMOJI] +SYRINGE_EMOJI = "\U0001F489" # :syringe: +PILL_EMOJI = "\U0001F48A" # :pill: +HOURGLASS_EMOJI = "\u231B" # :hourglass: +CROSSBONES_EMOJI = "\u2620" # :skull_crossbones: +ALEMBIC_EMOJI = "\u2697" # :alembic: +TICK_EMOJI = "\u2705" # :white_check_mark: - Correct peg, correct hole +CROSS_EMOJI = "\u274C" # :x: - Wrong peg, wrong hole +BLANK_EMOJI = "\u26AA" # :white_circle: - Correct peg, wrong hole +HOLE_EMOJI = "\u2B1C" # :white_square: - Used in guesses +EMPTY_UNICODE = "\u200b" # literally just an empty space + +ANTIDOTE_EMOJI = [ + SYRINGE_EMOJI, + PILL_EMOJI, + HOURGLASS_EMOJI, + CROSSBONES_EMOJI, + ALEMBIC_EMOJI, +] + +# Quiz constants +ANSWERS_EMOJI = { + "a": "\U0001F1E6", # :regional_indicator_a: 🇦 + "b": "\U0001F1E7", # :regional_indicator_b: 🇧 + "c": "\U0001F1E8", # :regional_indicator_c: 🇨 + "d": "\U0001F1E9", # :regional_indicator_d: 🇩 +} class Snakes: @@ -166,7 +179,7 @@ async def antidote(self, ctx: Context): board.append(f"`{i+1:02d}` " f"{page_guess_list[i]} - " f"{page_result_list[i]}") - board.append(EMPTY) + board.append(EMPTY_UNICODE) antidote_embed.add_field(name="10 guesses remaining", value="\n".join(board)) board_id = await ctx.send(embed=antidote_embed) # Display board @@ -225,7 +238,7 @@ def event_check(reaction_: Reaction, user_: Member): board.append(f"`{i+1:02d}` " f"{page_guess_list[i]} - " f"{page_result_list[i]}") - board.append(EMPTY) + board.append(EMPTY_UNICODE) # Remove Reactions for emoji in antidote_guess_list: @@ -258,7 +271,7 @@ def event_check(reaction_: Reaction, user_: Member): antidote_embed = Embed(color=ctx.me.color, title="Antidote") antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) antidote_embed.set_image(url="https://media.giphy.com/media/ceeN6U57leAhi/giphy.gif") - antidote_embed.add_field(name=EMPTY, + antidote_embed.add_field(name=EMPTY_UNICODE, value=f"Sorry you didnt make the antidote in time.\n" f"The formula was {' '.join(antidote_answer)}") await board_id.edit(embed=antidote_embed) @@ -268,47 +281,50 @@ def event_check(reaction_: Reaction, user_: Member): @command(name="snakes.quiz()", alias=["snakes.quiz"]) async def quiz(self, ctx: Context): - """Asks a snake-related question in the chat and validates the user's guess.""" - channel = ctx.channel - answers_emoji = { - "a": "🇦", - "b": "🇧", - "c": "🇨", - "d": "🇩" - } - question, message = await self._post_quiz_question(answers_emoji, channel) - await self._validate_quiz_answer(answers_emoji, channel, ctx, question, message) - - async def _post_quiz_question(self, answers_emoji:Dict[str,str], channel:Messageable): - """Ask a random question from the snake_questions.json in the chat.""" - with open(f"{constants.PROJECT_ROOT}/snake_questions.json") as quizson: - questions = json.load(quizson) - question = questions["questions"][random.randint(0, 10)] - em = Embed(title=question["question"], - description="\n\n".join(f"{value}: {question[key]}" - for key, value in answers_emoji.items())) - quiz = await channel.send("", embed=em) - for emoji in answers_emoji.values(): - await quiz.add_reaction(emoji) - return question, quiz + """ + Asks a snake-related question in the chat and validates the user's guess. + """ + + def valid_answer(reaction, user): + """ + Test if the the answer is valid and can be evaluated. + """ + return ( + reaction.message.id == quiz.id # The reaction is attached to the question we asked. + and user == ctx.author # It's the user who triggered the quiz. + and str(reaction.emoji) in ANSWERS_EMOJI.values() # The reaction is one of the options. + ) - async def _validate_quiz_answer(self, answers_emoji:Dict[str,str], channel:Messageable, ctx:Context, - question:Dict[str,str], message:Message): - """Validates the author's guess to the given question.""" - def my_check(reaction, user): - return reaction.message.id == message.id and user == ctx.author and str(reaction.emoji) + # Prepare a question. + with open(f"{constants.PROJECT_ROOT}/snake_questions.json") as all_questions: + questions = json.load(all_questions) + question = random.choice(questions["questions"]) + answer = question["answerkey"] + options = [f"**{key.upper()}**. {question[key]}" for key in ANSWERS_EMOJI.keys()] + + # Build and send the embed. + embed = Embed( + title=question["question"], + description="\n".join(options) + ) + quiz = await ctx.channel.send("", embed=embed) + for emoji in ANSWERS_EMOJI.values(): + await quiz.add_reaction(emoji) + + # Validate the answer try: - reaction, user = await ctx.bot.wait_for("reaction_add", timeout=20.0, check=my_check) + reaction, user = await ctx.bot.wait_for("reaction_add", timeout=20.0, check=valid_answer) except asyncio.TimeoutError: - await channel.send("Bah! You took too long.") + await ctx.channel.send("Bah! You took too long.") + return + + if str(reaction.emoji) == ANSWERS_EMOJI[answer]: + await ctx.channel.send("You got it! Well done!") else: - answer = question["answerkey"] - if str(reaction.emoji) == answers_emoji[answer]: - await channel.send("That was correct! Well done!") - else: - await channel.send(f"That was incorrect! " - f"The correct answer was {answer}, unfortunately.") + await ctx.channel.send( + f"Sorry, that's incorrect. The correct answer was **{answer.upper()}**." + ) def setup(bot): diff --git a/snake_questions.json b/snake_questions.json index d3841da6d5..46cd751a7b 100644 --- a/snake_questions.json +++ b/snake_questions.json @@ -14,7 +14,7 @@ "question": "What characteristics do all snakes share?", "a":"They are carnivoes", "b":"They are all programming languages", - "c":"Cold-blooded", + "c":"They're all cold-blooded", "d":"They are both carnivores and cold-blooded", "answerkey":"c" }, @@ -48,9 +48,9 @@ { "id": 5, "question": "How does a snake smell?", - "a":"Through its nose", - "b":"Through its tongue", - "c":"Through its ears", + "a":"Quite pleasant", + "b":"Through its nose", + "c":"Through its tongues", "d":"Both through its nose and its tongues", "answerkey":"d" }, @@ -85,7 +85,7 @@ "id": 9, "question": "What's true about two-headed snakes?", "a":"They're a myth!", - "b":"Rarely survive in the wild", + "b":"They rarely survive in the wild", "c":"They're very dangerous", "d":"They can kiss each other", "answerkey":"b" @@ -98,6 +98,69 @@ "c":"Copper", "d":"Iron", "answerkey":"b" + }, + { + "id": 11, + "question": "What snake doesn't have to have a mate to lay eggs?", + "a":"Copperhead", + "b":"Cornsnake", + "c":"Kingsnake", + "d":"Flower pot snake", + "answerkey":"d" + }, + { + "id": 12, + "question": "What snake is the longest?", + "a":"Green anaconda", + "b":"Reticulated python", + "c":"King cobra", + "d":"Kingsnake", + "answerkey":"b" + }, + { + "id": 13, + "question": "Though invasive species can now be found in the Everglades, in which three continents are pythons (members of the family Pythonidae) found in the wild?", + "a":"Africa, Asia and Australia", + "b":"Africa, Australia and Europe", + "c":"Africa, Australia and South America", + "d":"Africa, Asia and South America", + "answerkey":"a" + }, + { + "id": 14, + "question": "Pythons are held as some of the most dangerous snakes on earth, but are often confused with anacondas. Which of these is *not* a difference between pythons and anacondas?", + "a":"Pythons suffocate their prey, anacondas crush them", + "b":"Pythons lay eggs, anacondas give birth to live young", + "c":"Pythons grow longer, anacondas grow heavier", + "d":"Pythons generally spend less time in water than anacondas do", + "answerkey":"a" + }, + { + "id": 15, + "question": "Pythons are unable to chew their food, and so swallow prey whole. Which of these methods is most commonly demonstrated to help a python to swallow large prey?", + "a":"The python's stomach pressure is reduced, so prey is sucked in", + "b":"An extra set of upper teeth 'walk' along the prey", + "c":"The python holds its head up, so prey falls into its stomach", + "d":"Prey is pushed against a barrier and is forced down the python's throat", + "answerkey":"b" + }, + { + "id": 16, + "question": "Pythons, like many large constrictors, possess vestigial hind limbs. Whilst these 'spurs' serve no purpose in locomotion, how are they put to use by some male pythons? ", + "a":"To store sperm", + "b":"To release pheromones", + "c":"To grip females during mating", + "d":"To fight off rival males", + "answerkey":"c" + }, + { + "id": 17, + "question": "Pythons tend to travel by the rectilinear method (in straight lines) when on land, as opposed to the concertina method (s-shaped movement). Why do large pythons tend not to use the concertina method? ", + "a":"Their spine is too inflexible", + "b":"They move too slowly", + "c":"The scales on their backs are too rigid", + "d":"They are too heavy", + "answerkey":"d" } ] From 237529001916080751df6a5988c4dcf42592286a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Thu, 10 May 2018 21:27:39 +0200 Subject: [PATCH 05/27] Cleaning up snake_quiz further and integrating it towards the new API for snake questions. --- bot/cogs/snakes.py | 18 ++--- bot/constants.py | 1 + snake_questions.json | 167 ------------------------------------------- 3 files changed, 10 insertions(+), 176 deletions(-) delete mode 100644 snake_questions.json diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 5825ead59c..e5cca90240 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,5 +1,4 @@ import asyncio -import json import logging import random import string @@ -7,7 +6,7 @@ from discord import Colour, Embed, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command -from bot import constants +from bot.constants import SITE_API_KEY, SITE_API_SNAKE_QUIZ_URL log = logging.getLogger(__name__) @@ -53,6 +52,7 @@ class Snakes: def __init__(self, bot: AutoShardedBot): self.bot = bot self.SNAKES = ['black cobra', 'children\'s python'] # temporary + self.headers = {"X-API-KEY": SITE_API_KEY} def get_snake_name(self) -> str: """ @@ -296,17 +296,17 @@ def valid_answer(reaction, user): ) # Prepare a question. - with open(f"{constants.PROJECT_ROOT}/snake_questions.json") as all_questions: - questions = json.load(all_questions) - - question = random.choice(questions["questions"]) + response = await self.bot.http_session.get(SITE_API_SNAKE_QUIZ_URL, headers=self.headers) + question = await response.json() answer = question["answerkey"] - options = [f"**{key.upper()}**. {question[key]}" for key in ANSWERS_EMOJI.keys()] + options = {key: question[key] for key in ANSWERS_EMOJI.keys()} # Build and send the embed. embed = Embed( title=question["question"], - description="\n".join(options) + description="\n".join( + [f"**{key.upper()}**: {answer}" for key, answer in options.items()] + ) ) quiz = await ctx.channel.send("", embed=embed) for emoji in ANSWERS_EMOJI.values(): @@ -323,7 +323,7 @@ def valid_answer(reaction, user): await ctx.channel.send("You got it! Well done!") else: await ctx.channel.send( - f"Sorry, that's incorrect. The correct answer was **{answer.upper()}**." + f"Sorry, that's incorrect. The correct answer was **{answer}**." ) diff --git a/bot/constants.py b/bot/constants.py index 49ec729daf..02bb47edb5 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -38,6 +38,7 @@ SITE_API_USER_URL = f"{SITE_API_URL}/user" SITE_API_TAGS_URL = f"{SITE_API_URL}/tags" SITE_API_HIPHOPIFY_URL = f"{SITE_API_URL}/hiphopify" +SITE_API_SNAKE_QUIZ_URL = f"{SITE_API_URL}/snake_quiz" GITHUB_URL_BOT = "https://github.com/discord-python/bot" BOT_AVATAR_URL = "https://raw.githubusercontent.com/discord-python/branding/master/logos/logo_circle/logo_circle.png" diff --git a/snake_questions.json b/snake_questions.json deleted file mode 100644 index 46cd751a7b..0000000000 --- a/snake_questions.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "questions":[ - { - "id": 0, - "question": "How long have snakes been roaming the Earth?", - "a":"3 million years", - "b":"30 million years", - "c":"130 million years", - "d":"200 million years", - "answerkey":"c" - }, - { - "id": 1, - "question": "What characteristics do all snakes share?", - "a":"They are carnivoes", - "b":"They are all programming languages", - "c":"They're all cold-blooded", - "d":"They are both carnivores and cold-blooded", - "answerkey":"c" - }, - { - "id": 2, - "question": "How snakes hear?", - "a":"With small ears", - "b":"Through their skin", - "c":"Through their tail", - "d":"They don't use their ears at all", - "answerkey":"b" - }, - { - "id": 3, - "question": "What don't snakes see?", - "a":"Colour", - "b":"Light", - "c":"Both of the above", - "d":"Other snakes", - "answerkey":"a" - }, - { - "id": 4, - "question": "What unique vision ability do boas and pythons possess?", - "a":"Night vision", - "b":"Infared vision", - "c":"See through walls", - "d":"They don't have vision", - "answerkey":"b" - }, - { - "id": 5, - "question": "How does a snake smell?", - "a":"Quite pleasant", - "b":"Through its nose", - "c":"Through its tongues", - "d":"Both through its nose and its tongues", - "answerkey":"d" - }, - { - "id": 6, - "question": "Where are Jacobson's organs located in snakes?", - "a":"Mouth", - "b":"Tail", - "c":"Stomach", - "d":"Liver", - "answerkey":"a" - }, - { - "id": 7, - "question": "Snakes have very similar internal organs compared to humans. Snakes, however; lack the following:", - "a":"A diaphragm", - "b":"Intestines", - "c":"Lungs", - "d":"Kidney", - "answerkey":"a" - }, - { - "id": 8, - "question": "Snakes have different shaped lungs than humans. What do snakes have?", - "a":"An elongated right lung", - "b":"A small left lung", - "c":"Both of the above", - "d":"None of the above", - "answerkey":"c" - }, - { - "id": 9, - "question": "What's true about two-headed snakes?", - "a":"They're a myth!", - "b":"They rarely survive in the wild", - "c":"They're very dangerous", - "d":"They can kiss each other", - "answerkey":"b" - }, - { - "id": 10, - "question": "What substance covers a snake's skin?", - "a":"Calcium", - "b":"Keratin", - "c":"Copper", - "d":"Iron", - "answerkey":"b" - }, - { - "id": 11, - "question": "What snake doesn't have to have a mate to lay eggs?", - "a":"Copperhead", - "b":"Cornsnake", - "c":"Kingsnake", - "d":"Flower pot snake", - "answerkey":"d" - }, - { - "id": 12, - "question": "What snake is the longest?", - "a":"Green anaconda", - "b":"Reticulated python", - "c":"King cobra", - "d":"Kingsnake", - "answerkey":"b" - }, - { - "id": 13, - "question": "Though invasive species can now be found in the Everglades, in which three continents are pythons (members of the family Pythonidae) found in the wild?", - "a":"Africa, Asia and Australia", - "b":"Africa, Australia and Europe", - "c":"Africa, Australia and South America", - "d":"Africa, Asia and South America", - "answerkey":"a" - }, - { - "id": 14, - "question": "Pythons are held as some of the most dangerous snakes on earth, but are often confused with anacondas. Which of these is *not* a difference between pythons and anacondas?", - "a":"Pythons suffocate their prey, anacondas crush them", - "b":"Pythons lay eggs, anacondas give birth to live young", - "c":"Pythons grow longer, anacondas grow heavier", - "d":"Pythons generally spend less time in water than anacondas do", - "answerkey":"a" - }, - { - "id": 15, - "question": "Pythons are unable to chew their food, and so swallow prey whole. Which of these methods is most commonly demonstrated to help a python to swallow large prey?", - "a":"The python's stomach pressure is reduced, so prey is sucked in", - "b":"An extra set of upper teeth 'walk' along the prey", - "c":"The python holds its head up, so prey falls into its stomach", - "d":"Prey is pushed against a barrier and is forced down the python's throat", - "answerkey":"b" - }, - { - "id": 16, - "question": "Pythons, like many large constrictors, possess vestigial hind limbs. Whilst these 'spurs' serve no purpose in locomotion, how are they put to use by some male pythons? ", - "a":"To store sperm", - "b":"To release pheromones", - "c":"To grip females during mating", - "d":"To fight off rival males", - "answerkey":"c" - }, - { - "id": 17, - "question": "Pythons tend to travel by the rectilinear method (in straight lines) when on land, as opposed to the concertina method (s-shaped movement). Why do large pythons tend not to use the concertina method? ", - "a":"Their spine is too inflexible", - "b":"They move too slowly", - "c":"The scales on their backs are too rigid", - "d":"They are too heavy", - "answerkey":"d" - } - ] - -} \ No newline at end of file From 55eec4e33ff71014ba573b3546e8ba01d4c606d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Thu, 10 May 2018 23:05:39 +0200 Subject: [PATCH 06/27] Bugfixes for Antidote and Quiz --- bot/__init__.py | 2 +- bot/cogs/snakes.py | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/bot/__init__.py b/bot/__init__.py index 070bff585e..555ca5d423 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -172,7 +172,7 @@ def _get_word(self) -> str: elif current == "(" and next == ")": # Move the cursor to capture the ()'s - log.debug("User called command without providing arguments.") + log.trace("User called command without providing arguments.") pos += 2 result = self.buffer[self.previous:self.index + (pos+2)] self.index += 2 diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index e5cca90240..bd072c1d30 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -38,6 +38,13 @@ "d": "\U0001F1E9", # :regional_indicator_d: 🇩 } +ANSWERS_EMOJI_REVERSE = { + "\U0001F1E6": "A", # :regional_indicator_a: 🇦 + "\U0001F1E7": "B", # :regional_indicator_b: 🇧 + "\U0001F1E8": "C", # :regional_indicator_c: 🇨 + "\U0001F1E9": "D", # :regional_indicator_d: 🇩 +} + class Snakes: """ @@ -150,7 +157,7 @@ async def antidote(self, ctx: Context): # Check to see if the bot can remove reactions if not ctx.channel.permissions_for(ctx.guild.me).manage_messages: - await ctx.send("Unable to start game as I dont have manage_messages permissions") + log.warning(f"Unable to start Antidote game - Missing manage_messages permissions in {ctx.channel}") return # Initialize variables @@ -170,7 +177,6 @@ async def antidote(self, ctx: Context): antidote_answer = list(ANTIDOTE_EMOJI) # Duplicate list, not reference it random.shuffle(antidote_answer) antidote_answer.pop() - log.info(antidote_answer) # Begin initial board building for i in range(0, 10): @@ -206,7 +212,7 @@ def event_check(reaction_: Reaction, user_: Member): try: reaction, user = await ctx.bot.wait_for("reaction_add", timeout=300, check=event_check) except asyncio.TimeoutError: - log.debug("Timed out waiting for a reaction") + log.debug("Antidote timed out waiting for a reaction") break # We're done, no reactions for the last 5 minutes if antidote_tries < 10: @@ -218,7 +224,6 @@ def event_check(reaction_: Reaction, user_: Member): if antidote_guess_count == 4: # Guesses complete antidote_guess_count = 0 page_guess_list[antidote_tries] = " ".join(antidote_guess_list) - log.info(f"Guess: {' '.join(antidote_guess_list)}") # Now check guess for i in range(0, len(antidote_answer)): @@ -230,7 +235,6 @@ def event_check(reaction_: Reaction, user_: Member): guess_result.append(CROSS_EMOJI) guess_result.sort() page_result_list[antidote_tries] = " ".join(guess_result) - log.info(f"Guess Result: {' '.join(guess_result)}") # Rebuild the board board = [] @@ -320,10 +324,11 @@ def valid_answer(reaction, user): return if str(reaction.emoji) == ANSWERS_EMOJI[answer]: - await ctx.channel.send("You got it! Well done!") + await ctx.channel.send(f"You selected **{options[answer]}**, which is correct! Well done!") else: + wrong_answer = ANSWERS_EMOJI_REVERSE[str(reaction.emoji)] await ctx.channel.send( - f"Sorry, that's incorrect. The correct answer was **{answer}**." + f"Sorry, **{wrong_answer}** is incorrect. The correct answer was \"**{options[answer]}**\"." ) From 01e04af85e42e5a324d03e7a12edb04fa76ef2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Sat, 12 May 2018 03:03:14 +0200 Subject: [PATCH 07/27] Implemented the zzzen of pythhhon, by prithaj and andrew. --- bot/cogs/snakes.py | 77 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index bd072c1d30..aedd5da9e9 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -3,7 +3,7 @@ import random import string -from discord import Colour, Embed, Member, Reaction +from discord import Embed, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command from bot.constants import SITE_API_KEY, SITE_API_SNAKE_QUIZ_URL @@ -45,6 +45,27 @@ "\U0001F1E9": "D", # :regional_indicator_d: 🇩 } +# Zzzen of pythhhon constant +ZEN = """ +Beautiful is better than ugly. +Explicit is better than implicit. +Simple is better than complex. +Complex is better than complicated. +Flat is better than nested. +Sparse is better than dense. +Readability counts. +Special cases aren't special enough to break the rules. +Although practicality beats purity. +Errors should never pass silently. +Unless explicitly silenced. +In the face of ambiguity, refuse the temptation to guess. +There should be one-- and preferably only one --obvious way to do it. +Now is better than never. +Although never is often better than *right* now. +If the implementation is hard to explain, it's a bad idea. +If the implementation is easy to explain, it may be a good idea. +""" + class Snakes: """ @@ -133,12 +154,12 @@ async def random_snake_name(self, ctx: Context, name: str = None): # Embed and send embed = Embed( description=f"Your snake-name is **{result}**", - color=Colour.blurple() + color=0x399600 ) return await ctx.send(embed=embed) - @command(name="snakes.antidote()", alias=["snakes.antidote"]) + @command(name="snakes.antidote()", aliases=["snakes.antidote"]) async def antidote(self, ctx: Context): """ Antidote - Can you create the antivenom before the patient dies? @@ -170,7 +191,7 @@ async def antidote(self, ctx: Context): page_result_list = [] win = False - antidote_embed = Embed(color=ctx.me.color, title="Antidote") + antidote_embed = Embed(color=0x399600, title="Antidote") antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) # Generate answer @@ -264,7 +285,7 @@ def event_check(reaction_: Reaction, user_: Member): # Winning / Ending Screen if win is True: - antidote_embed = Embed(color=ctx.me.color, title="Antidote") + antidote_embed = Embed(color=0x399600, title="Antidote") antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) antidote_embed.set_image(url="https://i.makeagif.com/media/7-12-2015/Cj1pts.gif") antidote_embed.add_field(name=f"You have created the snake antidote!", @@ -272,7 +293,7 @@ def event_check(reaction_: Reaction, user_: Member): f"You had {10 - antidote_tries} tries remaining.") await board_id.edit(embed=antidote_embed) else: - antidote_embed = Embed(color=ctx.me.color, title="Antidote") + antidote_embed = Embed(color=0x399600, title="Antidote") antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) antidote_embed.set_image(url="https://media.giphy.com/media/ceeN6U57leAhi/giphy.gif") antidote_embed.add_field(name=EMPTY_UNICODE, @@ -283,10 +304,13 @@ def event_check(reaction_: Reaction, user_: Member): log.debug("Ending pagination and removing all reactions...") await board_id.clear_reactions() - @command(name="snakes.quiz()", alias=["snakes.quiz"]) + @command(name="snakes.quiz()", aliases=["snakes.quiz"]) async def quiz(self, ctx: Context): """ Asks a snake-related question in the chat and validates the user's guess. + + This was created by Mushy and Cardium for the code jam, + and modified by lemon for inclusion in this bot. """ def valid_answer(reaction, user): @@ -307,6 +331,7 @@ def valid_answer(reaction, user): # Build and send the embed. embed = Embed( + color=0x399600, title=question["question"], description="\n".join( [f"**{key.upper()}**: {answer}" for key, answer in options.items()] @@ -331,6 +356,44 @@ def valid_answer(reaction, user): f"Sorry, **{wrong_answer}** is incorrect. The correct answer was \"**{options[answer]}**\"." ) + @command(name="snakes.zen()", aliases=["zen"]) + async def zen(self, ctx: Context): + """ + Gets a random quote from the Zen of Python. + + Written by Prithaj and Andrew during the very first code jam. + Modified by lemon for inclusion in the bot. + """ + + embed = Embed(color=0x399600) + + # Get the zen quote + zen_quote = random.choice(ZEN.splitlines()) + + # Replace fricatives with exaggerated snake fricatives. + simple_fricatives = [ + "f", "s", "z", "h", + "F", "S", "Z", "H", + ] + complex_fricatives = [ + "th", "sh", "Th", "Sh" + ] + + for letter in simple_fricatives: + if letter.islower(): + zen_quote = zen_quote.replace(letter, letter * random.randint(1, 3)) + else: + zen_quote = zen_quote.replace(letter, (letter * random.randint(1, 3)).title()) + + for fricative in complex_fricatives: + zen_quote = zen_quote.replace(fricative, fricative[0] + fricative[1] * random.randint(1, 3)) + + # Embed and send + embed.description = zen_quote + await ctx.channel.send( + embed=embed + ) + def setup(bot): bot.add_cog(Snakes(bot)) From 36f2de7c8c0c0ceda18db5beb1eaed993ddc3be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Sat, 12 May 2018 03:34:49 +0200 Subject: [PATCH 08/27] Added the snake facts feature by Andrew and Prithaj. Also cleaned up some code smell. --- bot/cogs/events.py | 4 ++-- bot/cogs/hiphopify.py | 9 +++++---- bot/cogs/snakes.py | 35 +++++++++++++++++++++++++++++++---- bot/cogs/tags.py | 9 +++++---- bot/constants.py | 4 ---- 5 files changed, 43 insertions(+), 18 deletions(-) diff --git a/bot/cogs/events.py b/bot/cogs/events.py index 975b39ed9f..accceb7bf7 100644 --- a/bot/cogs/events.py +++ b/bot/cogs/events.py @@ -8,7 +8,7 @@ NoPrivateMessage, UserInputError ) -from bot.constants import DEVLOG_CHANNEL, PYTHON_GUILD, SITE_API_KEY, SITE_API_USER_URL +from bot.constants import DEVLOG_CHANNEL, PYTHON_GUILD, SITE_API_KEY, SITE_API_URL from bot.exceptions import CogBadArgument from bot.utils import chunks @@ -26,7 +26,7 @@ def __init__(self, bot: AutoShardedBot): async def send_updated_users(self, *users): try: response = await self.bot.http_session.post( - url=SITE_API_USER_URL, + url=f"{SITE_API_URL}/user", json=list(users), headers={"X-API-Key": SITE_API_KEY} ) diff --git a/bot/cogs/hiphopify.py b/bot/cogs/hiphopify.py index 9c494651ca..1e00b1746b 100644 --- a/bot/cogs/hiphopify.py +++ b/bot/cogs/hiphopify.py @@ -8,7 +8,7 @@ from bot.constants import ( ADMIN_ROLE, MODERATOR_ROLE, MOD_LOG_CHANNEL, NEGATIVE_REPLIES, OWNER_ROLE, POSITIVE_REPLIES, - SITE_API_HIPHOPIFY_URL, SITE_API_KEY + SITE_API_KEY, SITE_API_URL ) from bot.decorators import with_role @@ -23,6 +23,7 @@ class Hiphopify: def __init__(self, bot: AutoShardedBot): self.bot = bot self.headers = {"X-API-KEY": SITE_API_KEY} + self.url = f"{SITE_API_URL}/hiphopify" async def on_member_update(self, before, after): """ @@ -42,7 +43,7 @@ async def on_member_update(self, before, after): ) response = await self.bot.http_session.get( - SITE_API_HIPHOPIFY_URL, + self.url, headers=self.headers, params={"user_id": str(before.id)} ) @@ -104,7 +105,7 @@ async def hiphopify(self, ctx: Context, member: Member, duration: str, forced_ni params["forced_nick"] = forced_nick response = await self.bot.http_session.post( - SITE_API_HIPHOPIFY_URL, + self.url, headers=self.headers, json=params ) @@ -165,7 +166,7 @@ async def unhiphopify(self, ctx: Context, member: Member): embed.colour = Colour.blurple() response = await self.bot.http_session.delete( - SITE_API_HIPHOPIFY_URL, + self.url, headers=self.headers, json={"user_id": str(member.id)} ) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index aedd5da9e9..161e16cf15 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -6,7 +6,7 @@ from discord import Embed, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command -from bot.constants import SITE_API_KEY, SITE_API_SNAKE_QUIZ_URL +from bot.constants import SITE_API_KEY, SITE_API_URL log = logging.getLogger(__name__) @@ -81,6 +81,8 @@ def __init__(self, bot: AutoShardedBot): self.bot = bot self.SNAKES = ['black cobra', 'children\'s python'] # temporary self.headers = {"X-API-KEY": SITE_API_KEY} + self.quiz_url = f"{SITE_API_URL}/snake_quiz" + self.fact_url = f"{SITE_API_URL}/snake_fact" def get_snake_name(self) -> str: """ @@ -89,7 +91,7 @@ def get_snake_name(self) -> str: """ return random.choice(self.SNAKES) - @command(name="snakes.name_gen()", aliases=["snakes.name_gen"]) + @command(name="snakes.name()", aliases=["snakes.name", "snakes.name_gen", "snakes.name_gen()"]) async def random_snake_name(self, ctx: Context, name: str = None): """ Slices the users name at the last vowel (or second last if the name @@ -153,6 +155,7 @@ async def random_snake_name(self, ctx: Context, name: str = None): # Embed and send embed = Embed( + title="Snake name", description=f"Your snake-name is **{result}**", color=0x399600 ) @@ -324,7 +327,7 @@ def valid_answer(reaction, user): ) # Prepare a question. - response = await self.bot.http_session.get(SITE_API_SNAKE_QUIZ_URL, headers=self.headers) + response = await self.bot.http_session.get(self.quiz_url, headers=self.headers) question = await response.json() answer = question["answerkey"] options = {key: question[key] for key in ANSWERS_EMOJI.keys()} @@ -365,7 +368,10 @@ async def zen(self, ctx: Context): Modified by lemon for inclusion in the bot. """ - embed = Embed(color=0x399600) + embed = Embed( + title="Zzzen of Pythhon", + color=0x399600 + ) # Get the zen quote zen_quote = random.choice(ZEN.splitlines()) @@ -394,6 +400,27 @@ async def zen(self, ctx: Context): embed=embed ) + @command(name="snakes.fact()", aliases=["snakes.fact"]) + async def snake_fact(self, ctx: Context): + """ + Gets a snake-related fact + + This was created by Prithaj and Andrew for code jam 1, + and modified by lemon for inclusion in this bot. + """ + + # Get a fact from the API. + response = await self.bot.http_session.get(self.fact_url, headers=self.headers) + question = await response.json() + + # Build and send the embed. + embed = Embed( + title="Snake fact", + color=0x399600, + description=question + ) + await ctx.channel.send(embed=embed) + def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py index 24ace01c72..c51e57b5a6 100644 --- a/bot/cogs/tags.py +++ b/bot/cogs/tags.py @@ -10,7 +10,7 @@ from bot.constants import ( ADMIN_ROLE, MODERATOR_ROLE, OWNER_ROLE, - SITE_API_KEY, SITE_API_TAGS_URL, TAG_COOLDOWN, + SITE_API_KEY, SITE_API_URL, TAG_COOLDOWN, ) from bot.decorators import with_role from bot.exceptions import CogBadArgument @@ -81,6 +81,7 @@ def __init__(self, bot: AutoShardedBot): self.bot = bot self.tag_cooldowns = {} self.headers = {"X-API-KEY": SITE_API_KEY} + self.url = f"{SITE_API_URL}/tags" async def get_tag_data(self, tag_name=None) -> dict: """ @@ -97,7 +98,7 @@ async def get_tag_data(self, tag_name=None) -> dict: if tag_name: params["tag_name"] = tag_name - response = await self.bot.http_session.get(SITE_API_TAGS_URL, headers=self.headers, params=params) + response = await self.bot.http_session.get(self.url, headers=self.headers, params=params) tag_data = await response.json() return tag_data @@ -119,7 +120,7 @@ async def post_tag_data(self, tag_name: str, tag_content: str) -> dict: 'tag_content': tag_content } - response = await self.bot.http_session.post(SITE_API_TAGS_URL, headers=self.headers, json=params) + response = await self.bot.http_session.post(self.url, headers=self.headers, json=params) tag_data = await response.json() return tag_data @@ -140,7 +141,7 @@ async def delete_tag_data(self, tag_name: str) -> dict: if tag_name: params['tag_name'] = tag_name - response = await self.bot.http_session.delete(SITE_API_TAGS_URL, headers=self.headers, json=params) + response = await self.bot.http_session.delete(self.url, headers=self.headers, json=params) tag_data = await response.json() return tag_data diff --git a/bot/constants.py b/bot/constants.py index 02bb47edb5..0a87db5d71 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -35,10 +35,6 @@ SITE_URL = os.environ.get("SITE_URL", "pythondiscord.local:8080") SITE_PROTOCOL = 'http' if 'local' in SITE_URL else 'https' SITE_API_URL = f"{SITE_PROTOCOL}://api.{SITE_URL}" -SITE_API_USER_URL = f"{SITE_API_URL}/user" -SITE_API_TAGS_URL = f"{SITE_API_URL}/tags" -SITE_API_HIPHOPIFY_URL = f"{SITE_API_URL}/hiphopify" -SITE_API_SNAKE_QUIZ_URL = f"{SITE_API_URL}/snake_quiz" GITHUB_URL_BOT = "https://github.com/discord-python/bot" BOT_AVATAR_URL = "https://raw.githubusercontent.com/discord-python/branding/master/logos/logo_circle/logo_circle.png" From 5bcb3054a97fd3b49d47f9e64d9bf5bf850e3074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Sat, 12 May 2018 11:06:29 +0200 Subject: [PATCH 09/27] Implemented the snake_videos feature. Also made a fix for a bug with https sessions on local aiohttp --- bot/__main__.py | 14 +++++++++++++- bot/cogs/snakes.py | 39 ++++++++++++++++++++++++++++++++++++++- bot/constants.py | 6 +++++- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/bot/__main__.py b/bot/__main__.py index 3d722545e0..42657a04fd 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -1,12 +1,15 @@ # coding=utf-8 import os +import socket from aiohttp import AsyncResolver, ClientSession, TCPConnector from discord import Game from discord.ext.commands import AutoShardedBot, when_mentioned_or +from bot.constants import DEBUG_MODE from bot.formatter import Formatter + bot = AutoShardedBot( command_prefix=when_mentioned_or( "self.", "bot." @@ -23,7 +26,16 @@ ) # Global aiohttp session for all cogs - uses asyncio for DNS resolution instead of threads, so we don't *spam threads* -bot.http_session = ClientSession(connector=TCPConnector(resolver=AsyncResolver())) +if DEBUG_MODE: + bot.http_session = ClientSession( + connector=TCPConnector( + resolver=AsyncResolver(), + family=socket.AF_INET, + verify_ssl=False, + ) + ) +else: + bot.http_session = ClientSession(connector=TCPConnector(resolver=AsyncResolver())) # Internal/debug bot.load_extension("bot.cogs.logging") diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 161e16cf15..22bd23945f 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -2,11 +2,12 @@ import logging import random import string +import urllib from discord import Embed, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command -from bot.constants import SITE_API_KEY, SITE_API_URL +from bot.constants import SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY log = logging.getLogger(__name__) @@ -421,6 +422,42 @@ async def snake_fact(self, ctx: Context): ) await ctx.channel.send(embed=embed) + @command(name="snakes.video()", aliases=["snakes.video", "snakes.get_video()", "snakes.get_video"]) + async def video(self, ctx: Context, search: str = None): + """ + Gets a YouTube video about snakes + :param name: Optional, a name of a snake. Used to search for videos with that name + :param ctx: Context object passed from discord.py + :return: + """ + + # Are we searching for anything specific? + if search: + query = search + ' snake' + else: + query = 'snake' + + # Build the URL and make the request + url = f'https://www.googleapis.com/youtube/v3/search' + response = await self.bot.http_session.get( + url, + params={ + "part": "snippet", + "q": urllib.parse.quote(query), + "type": "video", + "key": YOUTUBE_API_KEY + } + ) + response = await response.json() + data = response['items'] + + # Send the user a video + num = random.randint(0, 5) # 5 videos are returned from the api + youtube_base_url = 'https://www.youtube.com/watch?v=' + await ctx.channel.send( + content=f"{youtube_base_url}{data[num]['id']['videoId']}" + ) + def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/constants.py b/bot/constants.py index 0a87db5d71..a2666c1484 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -1,6 +1,9 @@ # coding=utf-8 import os +# Debug mode +DEBUG_MODE = True if 'local' in os.environ.get("SITE_URL", "local") else False + # Server PYTHON_GUILD = 267624335836053506 @@ -33,7 +36,7 @@ DEPLOY_URL = os.environ.get("DEPLOY_URL") STATUS_URL = os.environ.get("STATUS_URL") SITE_URL = os.environ.get("SITE_URL", "pythondiscord.local:8080") -SITE_PROTOCOL = 'http' if 'local' in SITE_URL else 'https' +SITE_PROTOCOL = 'http' if DEBUG_MODE else 'https' SITE_API_URL = f"{SITE_PROTOCOL}://api.{SITE_URL}" GITHUB_URL_BOT = "https://github.com/discord-python/bot" BOT_AVATAR_URL = "https://raw.githubusercontent.com/discord-python/branding/master/logos/logo_circle/logo_circle.png" @@ -42,6 +45,7 @@ DEPLOY_BOT_KEY = os.environ.get("DEPLOY_BOT_KEY") DEPLOY_SITE_KEY = os.environ.get("DEPLOY_SITE_KEY") SITE_API_KEY = os.environ.get("BOT_API_KEY") +YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY') # Bot internals HELP_PREFIX = "bot." From c5cf21e164ef97151f869baa44b207a3f85db1d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Mon, 14 May 2018 00:46:54 +0200 Subject: [PATCH 10/27] Implemented Momo and kel's snake perlin noise gen draw feature --- bot/cogs/events.py | 4 +- bot/cogs/snakes.py | 83 ++++++++++++++- bot/cogs/tags.py | 3 +- bot/{utils.py => utils/__init__.py} | 0 bot/utils/snakes/__init__.py | 0 bot/utils/snakes/perlin.py | 158 ++++++++++++++++++++++++++++ 6 files changed, 243 insertions(+), 5 deletions(-) rename bot/{utils.py => utils/__init__.py} (100%) create mode 100644 bot/utils/snakes/__init__.py create mode 100644 bot/utils/snakes/perlin.py diff --git a/bot/cogs/events.py b/bot/cogs/events.py index 62579d0fec..3d89dc4b55 100644 --- a/bot/cogs/events.py +++ b/bot/cogs/events.py @@ -48,8 +48,8 @@ async def on_command_error(self, ctx: Context, e: CommandError): else: help_command = (self.bot.get_command("help"),) - if hasattr(command, "error"): - log.debug(f"Command {command} has a local error handler, ignoring.") + if hasattr(command, "on_error"): + log.debug(f"Command {command} has a local error handler, ignoring. ") return if isinstance(e, BadArgument): diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 22bd23945f..b470cdbaca 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,13 +1,18 @@ import asyncio +import io import logging +import math import random import string import urllib -from discord import Embed, Member, Reaction +from discord import Embed, File, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command +from PIL import Image +from PIL.ImageDraw import ImageDraw from bot.constants import SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY +from bot.utils.snakes import perlin log = logging.getLogger(__name__) @@ -422,13 +427,87 @@ async def snake_fact(self, ctx: Context): ) await ctx.channel.send(embed=embed) + @command(name="snakes.draw()", aliases=["snakes.draw"]) + async def draw(self, ctx: Context): + """ + Draws a random snek using Perlin noise + + Made by Momo and kel during the first code jam. + """ + + def generate_snake_image(self) -> bytes: + """ + Generate a CGI snek using perlin noise + :return: the binary data of the PNG image + """ + fac = perlin.PerlinNoiseFactory(dimension=1, octaves=2) + img_size = 200 + margins = 50 + start_x = random.randint(margins, img_size - margins) + start_y = random.randint(margins, img_size - margins) + points = [(start_x, start_y)] + snake_length = 12 + snake_color = 0x15c7ea + text_color = 0xf2ea15 + background_color = 0x0 + + for i in range(0, snake_length): + angle = math.radians(fac.get_plain_noise((1 / (snake_length + 1)) * (i + 1)) * 360) + curr_point = points[i] + segment_length = random.randint(15, 20) + next_x = curr_point[0] + segment_length * math.cos(angle) + next_y = curr_point[1] + segment_length * math.sin(angle) + points.append((next_x, next_y)) + + # normalize bounds + min_dimensions = [start_x, start_y] + max_dimensions = [start_x, start_y] + for p in points: + if p[0] < min_dimensions[0]: + min_dimensions[0] = p[0] + if p[0] > max_dimensions[0]: + max_dimensions[0] = p[0] + if p[1] < min_dimensions[1]: + min_dimensions[1] = p[1] + if p[1] > max_dimensions[1]: + max_dimensions[1] = p[1] + + # shift towards middle + dimension_range = (max_dimensions[0] - min_dimensions[0], max_dimensions[1] - min_dimensions[1]) + shift = ( + img_size / 2 - (dimension_range[0] / 2 + min_dimensions[0]), + img_size / 2 - (dimension_range[1] / 2 + min_dimensions[1]) + ) + + img = Image.new(mode='RGB', size=(img_size, img_size), color=background_color) + draw = ImageDraw(img) + for i in range(1, len(points)): + p = points[i] + prev = points[i - 1] + draw.line( + (shift[0] + prev[0], shift[1] + prev[1], shift[0] + p[0], shift[1] + p[1]), + width=8, + fill=snake_color + ) + draw.multiline_text((img_size - margins, img_size - margins), text="snek\nit\nup", fill=text_color) + del draw + stream = io.BytesIO() + img.save(stream, format='PNG') + + return stream.getvalue() + + stream = generate_snake_image() + file = File(stream, filename='snek.png') + await ctx.send(file=file) + @command(name="snakes.video()", aliases=["snakes.video", "snakes.get_video()", "snakes.get_video"]) async def video(self, ctx: Context, search: str = None): """ Gets a YouTube video about snakes :param name: Optional, a name of a snake. Used to search for videos with that name :param ctx: Context object passed from discord.py - :return: + + Created by Andrew and Prithaj for the first code jam. """ # Are we searching for anything specific? diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py index 6e1f58aead..593c2f929c 100644 --- a/bot/cogs/tags.py +++ b/bot/cogs/tags.py @@ -9,7 +9,8 @@ ) from bot.constants import ( - ADMIN_ROLE, MODERATOR_ROLE, OWNER_ROLE, + ADMIN_ROLE, BOT_COMMANDS_CHANNEL, DEVTEST_CHANNEL, + HELPERS_CHANNEL, MODERATOR_ROLE, OWNER_ROLE, SITE_API_KEY, SITE_API_URL, TAG_COOLDOWN, ) from bot.decorators import with_role diff --git a/bot/utils.py b/bot/utils/__init__.py similarity index 100% rename from bot/utils.py rename to bot/utils/__init__.py diff --git a/bot/utils/snakes/__init__.py b/bot/utils/snakes/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/bot/utils/snakes/perlin.py b/bot/utils/snakes/perlin.py new file mode 100644 index 0000000000..19eafe6a05 --- /dev/null +++ b/bot/utils/snakes/perlin.py @@ -0,0 +1,158 @@ +""" +Perlin noise implementation. +Taken from: https://gist.github.com/eevee/26f547457522755cb1fb8739d0ea89a1 +Licensed under ISC +""" +import math +import random +# Licensed under ISC +from itertools import product + + +def smoothstep(t): + """Smooth curve with a zero derivative at 0 and 1, making it useful for + interpolating. + """ + return t * t * (3. - 2. * t) + + +def lerp(t, a, b): + """Linear interpolation between a and b, given a fraction t.""" + return a + t * (b - a) + + +class PerlinNoiseFactory(object): + """Callable that produces Perlin noise for an arbitrary point in an + arbitrary number of dimensions. The underlying grid is aligned with the + integers. + There is no limit to the coordinates used; new gradients are generated on + the fly as necessary. + """ + + def __init__(self, dimension, octaves=1, tile=(), unbias=False): + """Create a new Perlin noise factory in the given number of dimensions, + which should be an integer and at least 1. + More octaves create a foggier and more-detailed noise pattern. More + than 4 octaves is rather excessive. + ``tile`` can be used to make a seamlessly tiling pattern. For example: + pnf = PerlinNoiseFactory(2, tile=(0, 3)) + This will produce noise that tiles every 3 units vertically, but never + tiles horizontally. + If ``unbias`` is true, the smoothstep function will be applied to the + output before returning it, to counteract some of Perlin noise's + significant bias towards the center of its output range. + """ + self.dimension = dimension + self.octaves = octaves + self.tile = tile + (0,) * dimension + self.unbias = unbias + + # For n dimensions, the range of Perlin noise is ±sqrt(n)/2; multiply + # by this to scale to ±1 + self.scale_factor = 2 * dimension ** -0.5 + + self.gradient = {} + + def _generate_gradient(self): + # Generate a random unit vector at each grid point -- this is the + # "gradient" vector, in that the grid tile slopes towards it + + # 1 dimension is special, since the only unit vector is trivial; + # instead, use a slope between -1 and 1 + if self.dimension == 1: + return (random.uniform(-1, 1),) + + # Generate a random point on the surface of the unit n-hypersphere; + # this is the same as a random unit vector in n dimensions. Thanks + # to: http://mathworld.wolfram.com/SpherePointPicking.html + # Pick n normal random variables with stddev 1 + random_point = [random.gauss(0, 1) for _ in range(self.dimension)] + # Then scale the result to a unit vector + scale = sum(n * n for n in random_point) ** -0.5 + return tuple(coord * scale for coord in random_point) + + def get_plain_noise(self, *point): + """Get plain noise for a single point, without taking into account + either octaves or tiling. + """ + if len(point) != self.dimension: + raise ValueError("Expected {0} values, got {1}".format( + self.dimension, len(point))) + + # Build a list of the (min, max) bounds in each dimension + grid_coords = [] + for coord in point: + min_coord = math.floor(coord) + max_coord = min_coord + 1 + grid_coords.append((min_coord, max_coord)) + + # Compute the dot product of each gradient vector and the point's + # distance from the corresponding grid point. This gives you each + # gradient's "influence" on the chosen point. + dots = [] + for grid_point in product(*grid_coords): + if grid_point not in self.gradient: + self.gradient[grid_point] = self._generate_gradient() + gradient = self.gradient[grid_point] + + dot = 0 + for i in range(self.dimension): + dot += gradient[i] * (point[i] - grid_point[i]) + dots.append(dot) + + # Interpolate all those dot products together. The interpolation is + # done with smoothstep to smooth out the slope as you pass from one + # grid cell into the next. + # Due to the way product() works, dot products are ordered such that + # the last dimension alternates: (..., min), (..., max), etc. So we + # can interpolate adjacent pairs to "collapse" that last dimension. Then + # the results will alternate in their second-to-last dimension, and so + # forth, until we only have a single value left. + dim = self.dimension + while len(dots) > 1: + dim -= 1 + s = smoothstep(point[dim] - grid_coords[dim][0]) + + next_dots = [] + while dots: + next_dots.append(lerp(s, dots.pop(0), dots.pop(0))) + + dots = next_dots + + return dots[0] * self.scale_factor + + def __call__(self, *point): + """Get the value of this Perlin noise function at the given point. The + number of values given should match the number of dimensions. + """ + ret = 0 + for o in range(self.octaves): + o2 = 1 << o + new_point = [] + for i, coord in enumerate(point): + coord *= o2 + if self.tile[i]: + coord %= self.tile[i] * o2 + new_point.append(coord) + ret += self.get_plain_noise(*new_point) / o2 + + # Need to scale n back down since adding all those extra octaves has + # probably expanded it beyond ±1 + # 1 octave: ±1 + # 2 octaves: ±1½ + # 3 octaves: ±1¾ + ret /= 2 - 2 ** (1 - self.octaves) + + if self.unbias: + # The output of the plain Perlin noise algorithm has a fairly + # strong bias towards the center due to the central limit theorem + # -- in fact the top and bottom 1/8 virtually never happen. That's + # a quarter of our entire output range! If only we had a function + # in [0..1] that could introduce a bias towards the endpoints... + r = (ret + 1) / 2 + # Doing it this many times is a completely made-up heuristic. + for _ in range(int(self.octaves / 2 + 0.5)): + r = smoothstep(r) + ret = r * 2 - 1 + + return ret From 5b3535f9f1750dc9ba9d024cf8e759eab5131b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Mon, 14 May 2018 01:16:55 +0200 Subject: [PATCH 11/27] Implemented the hatch feature from Momo and Kels PR --- bot/cogs/snakes.py | 34 +++++++++++++++++++++++++++- bot/utils/snakes/hatching.py | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 bot/utils/snakes/hatching.py diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index b470cdbaca..9847d4cf3c 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -12,7 +12,7 @@ from PIL.ImageDraw import ImageDraw from bot.constants import SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY -from bot.utils.snakes import perlin +from bot.utils.snakes import hatching, perlin log = logging.getLogger(__name__) @@ -500,6 +500,38 @@ def generate_snake_image(self) -> bytes: file = File(stream, filename='snek.png') await ctx.send(file=file) + @command(name="snakes.hatch()", aliases=["snakes.hatch", "hatch"]) + async def hatch(self, ctx: Context): + """ + Hatches your personal snake + :param ctx: context + :return: baby snake + """ + + # Pick a random snake to hatch. + snake_name = random.choice(list(hatching.snakes.keys())) + snake_image = hatching.snakes[snake_name] + + # Hatch the snake + message = await ctx.channel.send(embed=Embed(description="Hatching your snake :snake:...")) + await asyncio.sleep(1) + + for stage in hatching.stages: + hatch_embed = Embed(description=stage) + await message.edit(embed=hatch_embed) + await asyncio.sleep(1) + await asyncio.sleep(1) + await message.delete() + + # Build and send the embed. + my_snake_embed = Embed(description=":tada: Congrats! You hatched: **{0}**".format(snake_name)) + my_snake_embed.set_thumbnail(url=snake_image) + my_snake_embed.set_footer( + text=" Owner: {0}#{1}".format(ctx.message.author.name, ctx.message.author.discriminator) + ) + + await ctx.channel.send(embed=my_snake_embed) + @command(name="snakes.video()", aliases=["snakes.video", "snakes.get_video()", "snakes.get_video"]) async def video(self, ctx: Context, search: str = None): """ diff --git a/bot/utils/snakes/hatching.py b/bot/utils/snakes/hatching.py new file mode 100644 index 0000000000..c37ac0f502 --- /dev/null +++ b/bot/utils/snakes/hatching.py @@ -0,0 +1,44 @@ +h1 = '''``` + ---- + ------ + /--------\\ + |--------| + |--------| + \------/ + ----```''' + +h2 = '''``` + ---- + ------ + /---\\-/--\\ + |-----\\--| + |--------| + \------/ + ----```''' + +h3 = '''``` + ---- + ------ + /---\\-/--\\ + |-----\\--| + |-----/--| + \----\\-/ + ----```''' + +h4 = '''``` + ----- + ----- \\ + /--| /---\\ + |--\\ -\\---| + |--\\--/-- / + \------- / + ------```''' + +stages = [h1, h2, h3, h4] +snakes = { + "Baby Python": "https://i.imgur.com/SYOcmSa.png", + "Baby Rattle Snake": "https://i.imgur.com/i5jYA8f.png", + "Baby Dragon Snake": "https://i.imgur.com/SuMKM4m.png", + "Baby Garden Snake": "https://i.imgur.com/5vYx3ah.png", + "Baby Cobra": "https://i.imgur.com/jk14ryt.png" +} From 9c14d52d6380ee3b6280b361fe4174f039dbf0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Mon, 14 May 2018 03:23:01 +0200 Subject: [PATCH 12/27] Implemented the snakemefeature from the momo and kel PR, with big modifications. It no longer uses markov, it was just too slow to get it to do something interesting. It can also be passed a message to snakify that instead. --- bot/cogs/snakes.py | 108 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 19 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 9847d4cf3c..f0e732d2e3 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -72,6 +72,9 @@ If the implementation is easy to explain, it may be a good idea. """ +# Max messages to train snake_chat on +MSG_MAX = 100 + class Snakes: """ @@ -90,6 +93,32 @@ def __init__(self, bot: AutoShardedBot): self.quiz_url = f"{SITE_API_URL}/snake_quiz" self.fact_url = f"{SITE_API_URL}/snake_fact" + @staticmethod + def _snakify(message): + """ + Sssnakifffiesss a sstring. + """ + + # Replace fricatives with exaggerated snake fricatives. + simple_fricatives = [ + "f", "s", "z", "h", + "F", "S", "Z", "H", + ] + complex_fricatives = [ + "th", "sh", "Th", "Sh" + ] + + for letter in simple_fricatives: + if letter.islower(): + message = message.replace(letter, letter * random.randint(2, 4)) + else: + message = message.replace(letter, (letter * random.randint(2, 4)).title()) + + for fricative in complex_fricatives: + message = message.replace(fricative, fricative[0] + fricative[1] * random.randint(2, 4)) + + return message + def get_snake_name(self) -> str: """ Gets a random snake name. @@ -379,26 +408,9 @@ async def zen(self, ctx: Context): color=0x399600 ) - # Get the zen quote + # Get the zen quote and snakify it zen_quote = random.choice(ZEN.splitlines()) - - # Replace fricatives with exaggerated snake fricatives. - simple_fricatives = [ - "f", "s", "z", "h", - "F", "S", "Z", "H", - ] - complex_fricatives = [ - "th", "sh", "Th", "Sh" - ] - - for letter in simple_fricatives: - if letter.islower(): - zen_quote = zen_quote.replace(letter, letter * random.randint(1, 3)) - else: - zen_quote = zen_quote.replace(letter, (letter * random.randint(1, 3)).title()) - - for fricative in complex_fricatives: - zen_quote = zen_quote.replace(fricative, fricative[0] + fricative[1] * random.randint(1, 3)) + zen_quote = self._snakify(zen_quote) # Embed and send embed.description = zen_quote @@ -406,6 +418,64 @@ async def zen(self, ctx: Context): embed=embed ) + @command(name="snakes.snakify()", aliases=["snakes.snakify"]) + async def snake_chat(self, ctx: Context, message: str = None): + """ + How would I talk if I were a snake? + :param ctx: context + :param message: If this is passed, it will snakify the message. + If not, it will snakify a random message from + the users history. + """ + + def predicate(message): + """ + Check if the message was sent by the author. + """ + return message.author == ctx.message.author + + def get_random_long_message(messages, retries=10): + """ + Fetch a message that's at least 3 words long, + but only if it is possible to do so in retries + attempts. Else, just return whatever the last + message is. + """ + long_message = random.choice(messages) + if len(long_message.split()) < 3 or retries <= 0: + return get_random_long_message(messages, retries - 1) + return long_message + + embed = Embed() + user = ctx.message.author + + if not message: + + # Get a random message from the users history + messages = [] + async for message in ctx.channel.history(limit=500).filter(predicate): + messages.append(message.content) + + message = get_random_long_message(messages) + + # Set the avatar + if user.avatar is not None: + avatar = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}" + else: + avatar = ( + "https://img00.deviantart.net/eee3/i/2017/168/3/4/" + "discord__app__avatar_rev1_by_nodeviantarthere-dbd2tp9.png" + ) + + # Build and send the embed + embed.set_author( + name=f"{user.name}#{user.discriminator}", + icon_url=avatar, + ) + embed.description = f"*{self._snakify(message)}*" + + await ctx.channel.send(embed=embed) + @command(name="snakes.fact()", aliases=["snakes.fact"]) async def snake_fact(self, ctx: Context): """ From 4f4f45f18c3e6a2c1b9f5d50a26e8cf33ae8ac69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Mon, 14 May 2018 11:32:59 +0200 Subject: [PATCH 13/27] Started on Snakes and Ladders, but want to refactor it to use reactions. Fixed up the perlin noise gen to generate random snake attributes. --- bot/__init__.py | 3 +- bot/cogs/snakes.py | 201 +++++++++++++------- bot/resources/snakes_and_ladders/banner.jpg | Bin 0 -> 17928 bytes bot/resources/snakes_and_ladders/board.jpg | Bin 0 -> 80264 bytes bot/utils/snakes/perlinsneks.py | 149 +++++++++++++++ bot/utils/snakes/sal.py | 183 ++++++++++++++++++ bot/utils/snakes/sal_board.py | 33 ++++ 7 files changed, 498 insertions(+), 71 deletions(-) create mode 100644 bot/resources/snakes_and_ladders/banner.jpg create mode 100644 bot/resources/snakes_and_ladders/board.jpg create mode 100644 bot/utils/snakes/perlinsneks.py create mode 100644 bot/utils/snakes/sal.py create mode 100644 bot/utils/snakes/sal_board.py diff --git a/bot/__init__.py b/bot/__init__.py index 0bc7e3c7a9..173ea87880 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -228,6 +228,7 @@ def parse_python(buffer_pos): # Iterate through the buffer and determine pos = 0 + current = None while not self.eof: try: current = self.buffer[self.index + pos] @@ -242,7 +243,7 @@ def parse_python(buffer_pos): self.index += pos # If the command looks like a python syntax command, try to parse it. - if current == "(" or current == "[": + if current and current == "(" or current == "[": try: result = parse_python(pos) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index f0e732d2e3..f7029d0068 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,18 +1,14 @@ import asyncio -import io import logging -import math import random import string import urllib from discord import Embed, File, Member, Reaction -from discord.ext.commands import AutoShardedBot, Context, command -from PIL import Image -from PIL.ImageDraw import ImageDraw +from discord.ext.commands import AutoShardedBot, Context, command, group from bot.constants import SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY -from bot.utils.snakes import hatching, perlin +from bot.utils.snakes import hatching, perlin, perlinsneks, sal log = logging.getLogger(__name__) @@ -75,6 +71,14 @@ # Max messages to train snake_chat on MSG_MAX = 100 +# Rattlesnake mp3s +RATTLES = [ + 'rattle1.mp3', + 'rattle2.mp3', + 'rattle3.mp3', + 'rattle4.mp3' +] + class Snakes: """ @@ -505,77 +509,34 @@ async def draw(self, ctx: Context): Made by Momo and kel during the first code jam. """ - def generate_snake_image(self) -> bytes: - """ - Generate a CGI snek using perlin noise - :return: the binary data of the PNG image - """ - fac = perlin.PerlinNoiseFactory(dimension=1, octaves=2) - img_size = 200 - margins = 50 - start_x = random.randint(margins, img_size - margins) - start_y = random.randint(margins, img_size - margins) - points = [(start_x, start_y)] - snake_length = 12 - snake_color = 0x15c7ea - text_color = 0xf2ea15 - background_color = 0x0 - - for i in range(0, snake_length): - angle = math.radians(fac.get_plain_noise((1 / (snake_length + 1)) * (i + 1)) * 360) - curr_point = points[i] - segment_length = random.randint(15, 20) - next_x = curr_point[0] + segment_length * math.cos(angle) - next_y = curr_point[1] + segment_length * math.sin(angle) - points.append((next_x, next_y)) - - # normalize bounds - min_dimensions = [start_x, start_y] - max_dimensions = [start_x, start_y] - for p in points: - if p[0] < min_dimensions[0]: - min_dimensions[0] = p[0] - if p[0] > max_dimensions[0]: - max_dimensions[0] = p[0] - if p[1] < min_dimensions[1]: - min_dimensions[1] = p[1] - if p[1] > max_dimensions[1]: - max_dimensions[1] = p[1] - - # shift towards middle - dimension_range = (max_dimensions[0] - min_dimensions[0], max_dimensions[1] - min_dimensions[1]) - shift = ( - img_size / 2 - (dimension_range[0] / 2 + min_dimensions[0]), - img_size / 2 - (dimension_range[1] / 2 + min_dimensions[1]) - ) + # Generate random snake attributes + width = random.randint(8, 12) + length = random.randint(15, 22) + snek_color, text_color = random.sample(perlinsneks.SNAKE_COLORS, 2) + text = random.choice(perlinsneks.SNAKE_TEXTS) + + # Build and send the snek + factory = perlin.PerlinNoiseFactory(dimension=1, octaves=2) + image_frame = perlinsneks.create_snek_frame( + factory, + snake_width=width, + snake_length=length, + snake_color=snek_color, + text=text, + text_color=text_color, + ) + png_bytes = perlinsneks.frame_to_png_bytes(image_frame) + + file = File(png_bytes, filename='snek.png') - img = Image.new(mode='RGB', size=(img_size, img_size), color=background_color) - draw = ImageDraw(img) - for i in range(1, len(points)): - p = points[i] - prev = points[i - 1] - draw.line( - (shift[0] + prev[0], shift[1] + prev[1], shift[0] + p[0], shift[1] + p[1]), - width=8, - fill=snake_color - ) - draw.multiline_text((img_size - margins, img_size - margins), text="snek\nit\nup", fill=text_color) - del draw - stream = io.BytesIO() - img.save(stream, format='PNG') - - return stream.getvalue() - - stream = generate_snake_image() - file = File(stream, filename='snek.png') await ctx.send(file=file) @command(name="snakes.hatch()", aliases=["snakes.hatch", "hatch"]) async def hatch(self, ctx: Context): """ Hatches your personal snake - :param ctx: context - :return: baby snake + + Made by Momo and kel during the first code jam. """ # Pick a random snake to hatch. @@ -639,6 +600,106 @@ async def video(self, ctx: Context, search: str = None): content=f"{youtube_base_url}{data[num]['id']['videoId']}" ) + # region: Snakes and Ladders group + @group(name="snakes.sal()", aliases=["snakes.sal"]) + async def sal(self, ctx: Context): + """ + Command group for Snakes and Ladders + - Create a S&L game: sal create + - Join a S&L game: sal join + - Leave a S&L game: sal leave + - Cancel a S&L game (author): sal cancel + - Start a S&L game (author): sal start + - Roll the dice: sal roll OR roll + """ + if ctx.invoked_subcommand is None: + # alias for 'sal roll' -> roll() + if ctx.subcommand_passed is not None and ctx.subcommand_passed.lower() == "roll": + await self.bot.get_command("roll()").invoke(ctx) + return + await ctx.send("{0} Unknown S&L command".format(ctx.author.mention)) + + @sal.command(name="snakes.sal.create()", aliases=["snakes.sal.create"]) + async def create_sal(self, ctx: Context): + """ + Create a Snakes and Ladders in the channel. + """ + # check if there is already a game in this channel + channel = ctx.channel + if channel in self.active_sal: + await ctx.send("{0} A game is already in progress in this channel.".format(ctx.author.mention)) + return + game = sal.SnakeAndLaddersGame(snakes=self, channel=channel, author=ctx.author) + self.active_sal[channel] = game + await game.open_game() + + @sal.command(name="join()", aliases=["join"]) + async def join_sal(self, ctx: Context): + """ + Join a Snakes and Ladders game in the channel. + """ + channel = ctx.channel + if channel not in self.active_sal: + await ctx.send( + "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) + return + game = self.active_sal[channel] + await game.player_join(ctx.author) + + @sal.command(name="leave()", aliases=["leave", "quit"]) + async def leave_sal(self, ctx: Context): + """ + Leave the Snakes and Ladders game. + """ + channel = ctx.channel + if channel not in self.active_sal: + await ctx.send( + "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) + return + game = self.active_sal[channel] + await game.player_leave(ctx.author) + + @sal.command(name="cancel()", aliases=["cancel"]) + async def cancel_sal(self, ctx: Context): + """ + Cancel the Snakes and Ladders game (author only). + """ + channel = ctx.channel + if channel not in self.active_sal: + await ctx.send( + "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) + return + game = self.active_sal[channel] + await game.cancel_game(ctx.author) + + @sal.command(name="start()", aliases=["start"]) + async def start_sal(self, ctx: Context): + """ + Start the Snakes and Ladders game (author only). + """ + channel = ctx.channel + if channel not in self.active_sal: + await ctx.send( + "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) + return + game = self.active_sal[channel] + await game.start_game(ctx.author) + + @command(name="roll()", aliases=["sal roll", "roll"]) + async def roll_sal(self, ctx: Context): + """ + Roll the dice in Snakes and Ladders. + """ + channel = ctx.channel + if channel not in self.active_sal: + await ctx.send( + "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) + return + game = self.active_sal[channel] + + await game.player_roll(ctx.author) + # endregion + def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/resources/snakes_and_ladders/banner.jpg b/bot/resources/snakes_and_ladders/banner.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69eaaf129e66d8d6cfa03a5af18acf66de284ef8 GIT binary patch literal 17928 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

`r literal 0 HcmV?d00001 diff --git a/bot/resources/snakes_and_ladders/board.jpg b/bot/resources/snakes_and_ladders/board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..20032e3915a3d690221ce79005f277d0421cb3be GIT binary patch literal 80264 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 Image: + """ + Creates a single random snek frame using Perlin noise. + :param perlin_factory: the perlin noise factory used. Required. + :param perlin_lookup_vertical_shift: the Perlin noise shift in the Y-dimension for this frame + :param image_dimensions: the size of the output image. + :param image_margins: the margins to respect inside of the image. + :param snake_length: the length of the snake, in segments. + :param snake_color: the color of the snake. + :param bg_color: the background color. + :param segment_length_range: the range of the segment length. Values will be generated inside this range, including + the bounds. + :param snake_width: the width of the snek, in pixels. + :param text: the text to display with the snek. Set to None for no text. + :param text_position: the position of the text. + :param text_color: the color of the text. + :return: a PIL image, representing a single frame. + """ + start_x = random.randint(image_margins[X], image_dimensions[X] - image_margins[X]) + start_y = random.randint(image_margins[Y], image_dimensions[Y] - image_margins[Y]) + points = [(start_x, start_y)] + + for index in range(0, snake_length): + angle = perlin_factory.get_plain_noise( + ((1 / (snake_length + 1)) * (index + 1)) + perlin_lookup_vertical_shift + ) * ANGLE_RANGE + current_point = points[index] + segment_length = random.randint(segment_length_range[0], segment_length_range[1]) + points.append(( + current_point[X] + segment_length * math.cos(angle), + current_point[Y] + segment_length * math.sin(angle) + )) + + # normalize bounds + min_dimensions = [start_x, start_y] + max_dimensions = [start_x, start_y] + for point in points: + min_dimensions[X] = min(point[X], min_dimensions[X]) + min_dimensions[Y] = min(point[Y], min_dimensions[Y]) + max_dimensions[X] = max(point[X], max_dimensions[X]) + max_dimensions[Y] = max(point[Y], max_dimensions[Y]) + + # shift towards middle + dimension_range = (max_dimensions[X] - min_dimensions[X], max_dimensions[Y] - min_dimensions[Y]) + shift = ( + image_dimensions[X] / 2 - (dimension_range[X] / 2 + min_dimensions[X]), + image_dimensions[Y] / 2 - (dimension_range[Y] / 2 + min_dimensions[Y]) + ) + + image = Image.new(mode='RGB', size=image_dimensions, color=bg_color) + draw = ImageDraw(image) + for index in range(1, len(points)): + point = points[index] + previous = points[index - 1] + draw.line( + ( + shift[X] + previous[X], + shift[Y] + previous[Y], + shift[X] + point[X], + shift[Y] + point[Y] + ), + width=snake_width, + fill=snake_color + ) + if text is not None: + draw.multiline_text(text_position, text, fill=text_color) + del draw + return image + + +def frame_to_png_bytes(image: Image): + stream = io.BytesIO() + image.save(stream, format='PNG') + return stream.getvalue() diff --git a/bot/utils/snakes/sal.py b/bot/utils/snakes/sal.py new file mode 100644 index 0000000000..62e33e85de --- /dev/null +++ b/bot/utils/snakes/sal.py @@ -0,0 +1,183 @@ +import io +import math +import os +import random + +import aiohttp +import discord +from PIL import Image + +from bot.utils.snakes.sal_board import ( + BOARD, BOARD_MARGIN, BOARD_PLAYER_SIZE, + BOARD_TILE_SIZE, MAX_PLAYERS, PLAYER_ICON_IMAGE_SIZE +) + + +class SnakeAndLaddersGame: + def __init__(self, snakes, channel: discord.TextChannel, author: discord.Member): + self.snakes = snakes + self.channel = channel + self.state = 'booting' + self.author = author + self.players = [] + self.player_tiles = {} + self.round_has_rolled = {} + self.avatar_images = {} + + async def open_game(self): + await self._add_player(self.author) + await self.channel.send( + '**Snakes and Ladders**: A new game is about to start!\nMention me and type **sal join** to participate.', + file=discord.File(os.path.join('res', 'ladders', 'banner.jpg'), filename='Snakes and Ladders.jpg')) + self.state = 'waiting' + + async def _add_player(self, user: discord.Member): + self.players.append(user) + self.player_tiles[user.id] = 1 + avatar_url = user.avatar_url_as(format='jpeg', size=PLAYER_ICON_IMAGE_SIZE) + async with aiohttp.ClientSession() as session: + async with session.get(avatar_url) as res: + avatar_bytes = await res.read() + im = Image.open(io.BytesIO(avatar_bytes)).resize((BOARD_PLAYER_SIZE, BOARD_PLAYER_SIZE)) + self.avatar_images[user.id] = im + + async def player_join(self, user: discord.Member): + for p in self.players: + if user == p: + await self.channel.send(user.mention + " You are already in the game.") + return + if self.state != 'waiting': + await self.channel.send(user.mention + " You cannot join at this time.") + return + if len(self.players) is MAX_PLAYERS: + await self.channel.send(user.mention + " The game is full!") + return + + await self._add_player(user) + + await self.channel.send( + "**Snakes and Ladders**: " + user.mention + " has joined the game.\nThere are now " + str( + len(self.players)) + " players in the game.") + + async def player_leave(self, user: discord.Member): + if user == self.author: + await self.channel.send(user.mention + " You are the author, and cannot leave the game. Execute " + "`sal cancel` to cancel the game.") + return + for p in self.players: + if user == p: + self.players.remove(p) + self.player_tiles.pop(p.id, None) + self.round_has_rolled.pop(p.id, None) + await self.channel.send("**Snakes and Ladders**: " + user.mention + " has left the game.") + if self.state != 'waiting' and len(self.players) == 1: + await self.channel.send("**Snakes and Ladders**: The game has been surrendered!") + self._destruct() + return + await self.channel.send(user.mention + " You are not in the match.") + + async def cancel_game(self, user: discord.Member): + if not user == self.author: + await self.channel.send(user.mention + " Only the author of the game can cancel it.") + return + await self.channel.send("**Snakes and Ladders**: Game has been canceled.") + self._destruct() + + async def start_game(self, user: discord.Member): + if not user == self.author: + await self.channel.send(user.mention + " Only the author of the game can start it.") + return + if len(self.players) < 2: + await self.channel.send(user.mention + " A minimum of 2 players is required to start the game.") + return + if not self.state == 'waiting': + await self.channel.send(user.mention + " The game cannot be started at this time.") + return + self.state = 'starting' + player_list = ', '.join(user.mention for user in self.players) + await self.channel.send("**Snakes and Ladders**: The game is starting!\nPlayers: " + player_list) + await self.start_round() + + async def start_round(self): + self.state = 'roll' + for user in self.players: + self.round_has_rolled[user.id] = False + board_img = Image.open(os.path.join('res', 'ladders', 'board.jpg')) + player_row_size = math.ceil(MAX_PLAYERS / 2) + for i, player in enumerate(self.players): + tile = self.player_tiles[player.id] + tile_coordinates = self._board_coordinate_from_index(tile) + x_offset = BOARD_MARGIN[0] + tile_coordinates[0] * BOARD_TILE_SIZE + y_offset = \ + BOARD_MARGIN[1] + ( + (10 * BOARD_TILE_SIZE) - (9 - tile_coordinates[1]) * BOARD_TILE_SIZE - BOARD_PLAYER_SIZE) + x_offset += BOARD_PLAYER_SIZE * (i % player_row_size) + y_offset -= BOARD_PLAYER_SIZE * math.floor(i / player_row_size) + board_img.paste(self.avatar_images[player.id], + box=(x_offset, y_offset)) + stream = io.BytesIO() + board_img.save(stream, format='JPEG') + board_file = discord.File(stream.getvalue(), filename='Board.jpg') + await self.channel.send("**Snakes and Ladders**: A new round has started! Current board:", file=board_file) + player_list = '\n'.join((user.mention + ": Tile " + str(self.player_tiles[user.id])) for user in self.players) + await self.channel.send( + "**Current positions**:\n" + player_list + "\n\nMention me with **roll** to roll the dice!") + + async def player_roll(self, user: discord.Member): + if user.id not in self.player_tiles: + await self.channel.send(user.mention + " You are not in the match.") + return + if self.state != 'roll': + await self.channel.send(user.mention + " You may not roll at this time.") + return + if self.round_has_rolled[user.id]: + return + roll = random.randint(1, 6) + await self.channel.send(user.mention + " rolled a **{0}**!".format(roll)) + next_tile = self.player_tiles[user.id] + roll + # apply snakes and ladders + if next_tile in BOARD: + target = BOARD[next_tile] + if target < next_tile: + await self.channel.send(user.mention + " slips on a snake and falls back to **{0}**".format(target)) + else: + await self.channel.send(user.mention + " climbs a ladder to **{0}**".format(target)) + next_tile = target + + self.player_tiles[user.id] = min(100, next_tile) + self.round_has_rolled[user.id] = True + if self._check_all_rolled(): + await self._complete_round() + + async def _complete_round(self): + self.state = 'post_round' + # check for winner + winner = self._check_winner() + if winner is None: + # there is a winner, start the next round + await self.start_round() + return + # announce winner and exit + await self.channel.send("**Snakes and Ladders**: " + winner.mention + " has won the game! :tada:") + self._destruct() + + def _check_winner(self) -> discord.Member: + if self.state != 'post_round': + return None + return next((player for player in self.players if self.player_tiles[player.id] == 100), + None) + + def _check_all_rolled(self): + return all(rolled for rolled in self.round_has_rolled.values()) + + def _destruct(self): + del self.snakes.active_sal[self.channel] + + def _board_coordinate_from_index(self, index: int): + # converts the tile number to the x/y coordinates for graphical purposes + y_level = 9 - math.floor((index - 1) / 10) + is_reversed = math.floor((index - 1) / 10) % 2 != 0 + x_level = (index - 1) % 10 + if is_reversed: + x_level = 9 - x_level + return x_level, y_level diff --git a/bot/utils/snakes/sal_board.py b/bot/utils/snakes/sal_board.py new file mode 100644 index 0000000000..d197bacdc9 --- /dev/null +++ b/bot/utils/snakes/sal_board.py @@ -0,0 +1,33 @@ +BOARD_TILE_SIZE = 56 # the size of each board tile +BOARD_PLAYER_SIZE = 20 # the size of each player icon +BOARD_MARGIN = (10, 0) # margins, in pixels (for player icons) +PLAYER_ICON_IMAGE_SIZE = 32 # the size of the image to download, should a power of 2 and higher than BOARD_PLAYER_SIZE +MAX_PLAYERS = 4 # depends on the board size/quality, 4 is for the default board + +# board definition (from, to) +BOARD = { + # ladders + 2: 38, + 7: 14, + 8: 31, + 15: 26, + 21: 42, + 28: 84, + 36: 44, + 51: 67, + 71: 91, + 78: 98, + 87: 94, + + # snakes + 99: 80, + 95: 75, + 92: 88, + 89: 68, + 74: 53, + 64: 60, + 62: 19, + 49: 11, + 46: 25, + 16: 6 +} From bdda2a84bf7bf447d5256113f374441ad44ed136 Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Mon, 14 May 2018 14:17:57 +0100 Subject: [PATCH 14/27] Movie command, initial version --- bot/cogs/snakes.py | 78 +++++++++++++++++++++++++++++++++++++++++++++- bot/constants.py | 3 +- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index f7029d0068..59feccb2a9 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -7,7 +7,7 @@ from discord import Embed, File, Member, Reaction from discord.ext.commands import AutoShardedBot, Context, command, group -from bot.constants import SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY +from bot.constants import OMDB_API_KEY, SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY from bot.utils.snakes import hatching, perlin, perlinsneks, sal log = logging.getLogger(__name__) @@ -700,6 +700,82 @@ async def roll_sal(self, ctx: Context): await game.player_roll(ctx.author) # endregion + # region: Snake movies + + @command(name="snakes.movie()", aliases=["movie"]) + async def movie(self, ctx: Context): + """ + Gets a random snake-related movie from OMDB. + + Written by Samuel and Fat & Proud during the very first code jam. + Modified by gdude for inclusion in the bot. + """ + + url = "http://www.omdbapi.com/" + page = random.randint(1, 27) + + response = await self.bot.http_session.get( + url, + params={ + "s": "snake", + "page": page, + "type": "movie", + "apikey": OMDB_API_KEY + } + ) + + data = await response.json() + movie = random.choice(data["Search"])["imdbID"] + + response = await self.bot.http_session.get( + url, + params={ + "i": movie, + "apikey": OMDB_API_KEY + } + ) + + data = await response.json() + + embed = Embed( + title=data["Title"], + color=0x399600 + ) + + del data["Response"], data["imdbID"], data["Title"] + + for key, value in data.items(): + if not value or value == "N/A" or key in ("Response", "imdbID", "Title", "Type"): + continue + + if key == "Ratings": # [{'Source': 'Internet Movie Database', 'Value': '7.6/10'}] + rating = random.choice(value) + + if rating["Source"] != "Internet Movie Database": + embed.add_field(name=f"Rating: {rating['Source']}", value=rating["Value"]) + + continue + + if key == "Poster": + embed.set_image(url=value) + continue + + elif key == "imdbRating": + key = "IMDB Rating" + + elif key == "imdbVotes": + key = "IMDB Votes" + + embed.add_field(name=key, value=value, inline=True) + + embed.set_footer(text="Data provided by the OMDB API") + + await ctx.channel.send( + embed=embed + ) + + # endregion + def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/constants.py b/bot/constants.py index 8916b28369..424c5f7f74 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -46,7 +46,8 @@ DEPLOY_BOT_KEY = os.environ.get("DEPLOY_BOT_KEY") DEPLOY_SITE_KEY = os.environ.get("DEPLOY_SITE_KEY") SITE_API_KEY = os.environ.get("BOT_API_KEY") -YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY') +YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY") +OMDB_API_KEY = os.getenv("OMDB_API_KEY") # Bot internals HELP_PREFIX = "bot." From 1a6c194fd7ee4bdbe1b9b53f850b243cbe16548b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Mon, 14 May 2018 17:30:02 +0200 Subject: [PATCH 15/27] Snakes and Ladders implemented and rewritten to use reactions for controls. --- bot/cogs/snakes.py | 131 +++-------------- bot/utils/snakes/sal.py | 260 ++++++++++++++++++++++++++++------ bot/utils/snakes/sal_board.py | 8 +- 3 files changed, 247 insertions(+), 152 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index f7029d0068..fae9414f62 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -5,7 +5,7 @@ import urllib from discord import Embed, File, Member, Reaction -from discord.ext.commands import AutoShardedBot, Context, command, group +from discord.ext.commands import AutoShardedBot, Context, command from bot.constants import SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY from bot.utils.snakes import hatching, perlin, perlinsneks, sal @@ -71,14 +71,6 @@ # Max messages to train snake_chat on MSG_MAX = 100 -# Rattlesnake mp3s -RATTLES = [ - 'rattle1.mp3', - 'rattle2.mp3', - 'rattle3.mp3', - 'rattle4.mp3' -] - class Snakes: """ @@ -91,6 +83,7 @@ class Snakes: """ def __init__(self, bot: AutoShardedBot): + self.active_sal = {} self.bot = bot self.SNAKES = ['black cobra', 'children\'s python'] # temporary self.headers = {"X-API-KEY": SITE_API_KEY} @@ -218,6 +211,19 @@ async def antidote(self, ctx: Context): This game was created by Bisk and Runew0lf for the first PythonDiscord codejam. """ + def event_check(reaction_: Reaction, user_: Member): + """ + Make sure that this reaction is what we want to operate on + """ + return ( + all(( + reaction_.message.id == board_id.id, # Reaction is on this message + reaction_.emoji in ANTIDOTE_EMOJI, # Reaction is one of the pagination emotes + user_.id != self.bot.user.id, # Reaction was not made by the Bot + user_.id == ctx.author.id # Reaction was made by author + )) + ) + # Check to see if the bot can remove reactions if not ctx.channel.permissions_for(ctx.guild.me).manage_messages: log.warning(f"Unable to start Antidote game - Missing manage_messages permissions in {ctx.channel}") @@ -256,20 +262,6 @@ async def antidote(self, ctx: Context): for emoji in ANTIDOTE_EMOJI: await board_id.add_reaction(emoji) - def event_check(reaction_: Reaction, user_: Member): - """ - Make sure that this reaction is what we want to operate on - """ - return ( - # Conditions for a successful pagination: - all(( - reaction_.message.id == board_id.id, # Reaction is on this message - reaction_.emoji in ANTIDOTE_EMOJI, # Reaction is one of the pagination emotes - user_.id != self.bot.user.id, # Reaction was not made by the Bot - user_.id == ctx.author.id # There were no restrictions - )) - ) - # Begin main game loop while not win and antidote_tries < 10: try: @@ -600,8 +592,7 @@ async def video(self, ctx: Context, search: str = None): content=f"{youtube_base_url}{data[num]['id']['videoId']}" ) - # region: Snakes and Ladders group - @group(name="snakes.sal()", aliases=["snakes.sal"]) + @command(name="snakes.sal()", aliases=["snakes.sal"]) async def sal(self, ctx: Context): """ Command group for Snakes and Ladders @@ -612,93 +603,17 @@ async def sal(self, ctx: Context): - Start a S&L game (author): sal start - Roll the dice: sal roll OR roll """ - if ctx.invoked_subcommand is None: - # alias for 'sal roll' -> roll() - if ctx.subcommand_passed is not None and ctx.subcommand_passed.lower() == "roll": - await self.bot.get_command("roll()").invoke(ctx) - return - await ctx.send("{0} Unknown S&L command".format(ctx.author.mention)) - - @sal.command(name="snakes.sal.create()", aliases=["snakes.sal.create"]) - async def create_sal(self, ctx: Context): - """ - Create a Snakes and Ladders in the channel. - """ - # check if there is already a game in this channel - channel = ctx.channel - if channel in self.active_sal: - await ctx.send("{0} A game is already in progress in this channel.".format(ctx.author.mention)) - return - game = sal.SnakeAndLaddersGame(snakes=self, channel=channel, author=ctx.author) - self.active_sal[channel] = game - await game.open_game() - - @sal.command(name="join()", aliases=["join"]) - async def join_sal(self, ctx: Context): - """ - Join a Snakes and Ladders game in the channel. - """ - channel = ctx.channel - if channel not in self.active_sal: - await ctx.send( - "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) - return - game = self.active_sal[channel] - await game.player_join(ctx.author) - - @sal.command(name="leave()", aliases=["leave", "quit"]) - async def leave_sal(self, ctx: Context): - """ - Leave the Snakes and Ladders game. - """ - channel = ctx.channel - if channel not in self.active_sal: - await ctx.send( - "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) - return - game = self.active_sal[channel] - await game.player_leave(ctx.author) - @sal.command(name="cancel()", aliases=["cancel"]) - async def cancel_sal(self, ctx: Context): - """ - Cancel the Snakes and Ladders game (author only). - """ - channel = ctx.channel - if channel not in self.active_sal: - await ctx.send( - "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) - return - game = self.active_sal[channel] - await game.cancel_game(ctx.author) - - @sal.command(name="start()", aliases=["start"]) - async def start_sal(self, ctx: Context): - """ - Start the Snakes and Ladders game (author only). - """ - channel = ctx.channel - if channel not in self.active_sal: - await ctx.send( - "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) + # CREATE # + # check if there is already a game in this channel + if ctx.channel in self.active_sal: + await ctx.send(f"{ctx.author.mention} A game is already in progress in this channel.") return - game = self.active_sal[channel] - await game.start_game(ctx.author) - @command(name="roll()", aliases=["sal roll", "roll"]) - async def roll_sal(self, ctx: Context): - """ - Roll the dice in Snakes and Ladders. - """ - channel = ctx.channel - if channel not in self.active_sal: - await ctx.send( - "{0} There is no active Snakes & Ladders game in this channel.".format(ctx.author.mention)) - return - game = self.active_sal[channel] + game = sal.SnakeAndLaddersGame(snakes=self, context=ctx) + self.active_sal[ctx.channel] = game - await game.player_roll(ctx.author) - # endregion + await game.open_game() def setup(bot): diff --git a/bot/utils/snakes/sal.py b/bot/utils/snakes/sal.py index 62e33e85de..0bc81bac25 100644 --- a/bot/utils/snakes/sal.py +++ b/bot/utils/snakes/sal.py @@ -1,10 +1,13 @@ +import asyncio import io +import logging import math import os import random import aiohttp -import discord +from discord import File, Member, Reaction +from discord.ext.commands import Context from PIL import Image from bot.utils.snakes.sal_board import ( @@ -12,26 +15,116 @@ BOARD_TILE_SIZE, MAX_PLAYERS, PLAYER_ICON_IMAGE_SIZE ) +log = logging.getLogger(__name__) + +# Emoji constants +START_EMOJI = "\u2611" # :ballot_box_with_check: - Start the game +CANCEL_EMOJI = "\u274C" # :x: - Cancel or leave the game +ROLL_EMOJI = "\U0001F3B2" # :game_die: - Roll the die! +JOIN_EMOJI = "\U0001F64B" # :raising_hand: - Join the game. + +STARTUP_SCREEN_EMOJI = [ + JOIN_EMOJI, + START_EMOJI, + CANCEL_EMOJI +] + +GAME_SCREEN_EMOJI = [ + ROLL_EMOJI, + CANCEL_EMOJI +] + class SnakeAndLaddersGame: - def __init__(self, snakes, channel: discord.TextChannel, author: discord.Member): + def __init__(self, snakes, context: Context): self.snakes = snakes - self.channel = channel + self.ctx = context + self.channel = self.ctx.channel self.state = 'booting' - self.author = author + self.started = False + self.author = self.ctx.author self.players = [] self.player_tiles = {} self.round_has_rolled = {} self.avatar_images = {} + self.board = None + self.positions = None + self.rolls = [] async def open_game(self): + """ + Create a new Snakes and Ladders game. + + Listen for reactions until players have joined, + and the game has been started. + """ + + def startup_event_check(reaction_: Reaction, user_: Member): + """ + Make sure that this reaction is what we want to operate on + """ + return ( + all(( + reaction_.message.id == startup.id, # Reaction is on startup message + reaction_.emoji in STARTUP_SCREEN_EMOJI, # Reaction is one of the startup emotes + user_.id != self.ctx.bot.user.id, # Reaction was not made by the bot + )) + ) + + # Check to see if the bot can remove reactions + if not self.channel.permissions_for(self.ctx.guild.me).manage_messages: + log.warning( + "Unable to start Snakes and Ladders - " + f"Missing manage_messages permissions in {self.channel}" + ) + return + await self._add_player(self.author) await self.channel.send( - '**Snakes and Ladders**: A new game is about to start!\nMention me and type **sal join** to participate.', - file=discord.File(os.path.join('res', 'ladders', 'banner.jpg'), filename='Snakes and Ladders.jpg')) + "**Snakes and Ladders**: A new game is about to start!", + file=File( + os.path.join("bot", "resources", "snakes_and_ladders", "banner.jpg"), + filename='Snakes and Ladders.jpg' + ) + ) + startup = await self.channel.send( + f"Press {JOIN_EMOJI} to participate, and press " + f"{START_EMOJI} to start the game" + ) + for emoji in STARTUP_SCREEN_EMOJI: + await startup.add_reaction(emoji) + self.state = 'waiting' - async def _add_player(self, user: discord.Member): + while not self.started: + try: + reaction, user = await self.ctx.bot.wait_for( + "reaction_add", + timeout=300, + check=startup_event_check + ) + if reaction.emoji == JOIN_EMOJI: + await self.player_join(user) + elif reaction.emoji == CANCEL_EMOJI: + if self.ctx.author == user: + await self.cancel_game(user) + else: + await self.player_leave(user) + elif reaction.emoji == START_EMOJI: + if self.ctx.author == user: + self.started = True + await self.start_game(user) + await startup.delete() + break + + await startup.remove_reaction(reaction.emoji, user) + + except asyncio.TimeoutError: + log.debug("Snakes and Ladders timed out waiting for a reaction") + self.cancel_game(self.author) + break # We're done, no reactions for the last 5 minutes + + async def _add_player(self, user: Member): self.players.append(user) self.player_tiles[user.id] = 1 avatar_url = user.avatar_url_as(format='jpeg', size=PLAYER_ICON_IMAGE_SIZE) @@ -41,57 +134,69 @@ async def _add_player(self, user: discord.Member): im = Image.open(io.BytesIO(avatar_bytes)).resize((BOARD_PLAYER_SIZE, BOARD_PLAYER_SIZE)) self.avatar_images[user.id] = im - async def player_join(self, user: discord.Member): + async def player_join(self, user: Member): for p in self.players: if user == p: - await self.channel.send(user.mention + " You are already in the game.") + await self.channel.send(user.mention + " You are already in the game.", delete_after=10) return if self.state != 'waiting': - await self.channel.send(user.mention + " You cannot join at this time.") + await self.channel.send(user.mention + " You cannot join at this time.", delete_after=10) return if len(self.players) is MAX_PLAYERS: - await self.channel.send(user.mention + " The game is full!") + await self.channel.send(user.mention + " The game is full!", delete_after=10) return await self._add_player(user) await self.channel.send( - "**Snakes and Ladders**: " + user.mention + " has joined the game.\nThere are now " + str( - len(self.players)) + " players in the game.") + f"**Snakes and Ladders**: {user.mention} has joined the game.\n" + f"There are now {str(len(self.players))} players in the game.", + delete_after=10 + ) - async def player_leave(self, user: discord.Member): + async def player_leave(self, user: Member): if user == self.author: - await self.channel.send(user.mention + " You are the author, and cannot leave the game. Execute " - "`sal cancel` to cancel the game.") + await self.channel.send( + user.mention + " You are the author, and cannot leave the game. Execute " + "`sal cancel` to cancel the game.", + delete_after=10 + ) return for p in self.players: if user == p: self.players.remove(p) self.player_tiles.pop(p.id, None) self.round_has_rolled.pop(p.id, None) - await self.channel.send("**Snakes and Ladders**: " + user.mention + " has left the game.") + await self.channel.send( + "**Snakes and Ladders**: " + user.mention + " has left the game.", + delete_after=10 + ) + if self.state != 'waiting' and len(self.players) == 1: await self.channel.send("**Snakes and Ladders**: The game has been surrendered!") self._destruct() return - await self.channel.send(user.mention + " You are not in the match.") + await self.channel.send(user.mention + " You are not in the match.", delete_after=10) - async def cancel_game(self, user: discord.Member): + async def cancel_game(self, user: Member): if not user == self.author: - await self.channel.send(user.mention + " Only the author of the game can cancel it.") + await self.channel.send(user.mention + " Only the author of the game can cancel it.", delete_after=10) return await self.channel.send("**Snakes and Ladders**: Game has been canceled.") self._destruct() - async def start_game(self, user: discord.Member): + async def start_game(self, user: Member): if not user == self.author: - await self.channel.send(user.mention + " Only the author of the game can start it.") + await self.channel.send(user.mention + " Only the author of the game can start it.", delete_after=10) return - if len(self.players) < 2: - await self.channel.send(user.mention + " A minimum of 2 players is required to start the game.") + if len(self.players) < 1: + await self.channel.send( + user.mention + " A minimum of 2 players is required to start the game.", + delete_after=10 + ) return if not self.state == 'waiting': - await self.channel.send(user.mention + " The game cannot be started at this time.") + await self.channel.send(user.mention + " The game cannot be started at this time.", delete_after=10) return self.state = 'starting' player_list = ', '.join(user.mention for user in self.players) @@ -99,11 +204,25 @@ async def start_game(self, user: discord.Member): await self.start_round() async def start_round(self): + + def game_event_check(reaction_: Reaction, user_: Member): + """ + Make sure that this reaction is what we want to operate on + """ + return ( + all(( + reaction_.message.id == self.positions.id, # Reaction is on positions message + reaction_.emoji in GAME_SCREEN_EMOJI, # Reaction is one of the game emotes + user_.id != self.ctx.bot.user.id, # Reaction was not made by the bot + )) + ) + self.state = 'roll' for user in self.players: self.round_has_rolled[user.id] = False - board_img = Image.open(os.path.join('res', 'ladders', 'board.jpg')) + board_img = Image.open(os.path.join("bot", "resources", "snakes_and_ladders", "board.jpg")) player_row_size = math.ceil(MAX_PLAYERS / 2) + for i, player in enumerate(self.players): tile = self.player_tiles[player.id] tile_coordinates = self._board_coordinate_from_index(tile) @@ -117,51 +236,112 @@ async def start_round(self): box=(x_offset, y_offset)) stream = io.BytesIO() board_img.save(stream, format='JPEG') - board_file = discord.File(stream.getvalue(), filename='Board.jpg') - await self.channel.send("**Snakes and Ladders**: A new round has started! Current board:", file=board_file) + board_file = File(stream.getvalue(), filename='Board.jpg') player_list = '\n'.join((user.mention + ": Tile " + str(self.player_tiles[user.id])) for user in self.players) - await self.channel.send( - "**Current positions**:\n" + player_list + "\n\nMention me with **roll** to roll the dice!") - async def player_roll(self, user: discord.Member): + # Store and send new messages + temp_board = await self.channel.send( + "**Snakes and Ladders**: A new round has started! Current board:", + file=board_file + ) + temp_positions = await self.channel.send( + f"**Current positions**:\n{player_list}\n\nUse {ROLL_EMOJI} to roll the dice!" + ) + + # Delete the previous messages + if self.board and self.positions: + await self.board.delete() + await self.positions.delete() + + # remove the roll messages + for roll in self.rolls: + await roll.delete() + self.rolls = [] + + # Save new messages + self.board = temp_board + self.positions = temp_positions + + # Wait for rolls + for emoji in GAME_SCREEN_EMOJI: + await self.positions.add_reaction(emoji) + + while True: + try: + reaction, user = await self.ctx.bot.wait_for( + "reaction_add", + timeout=300, + check=game_event_check + ) + + if reaction.emoji == ROLL_EMOJI: + await self.player_roll(user) + elif reaction.emoji == CANCEL_EMOJI: + if self.ctx.author == user: + await self.cancel_game(user) + else: + await self.player_leave(user) + + await self.positions.remove_reaction(reaction.emoji, user) + + if self._check_all_rolled(): + break + + except asyncio.TimeoutError: + log.debug("Snakes and Ladders timed out waiting for a reaction") + await self.cancel_game(self.author) + break # We're done, no reactions for the last 5 minutes + + # Round completed + await self._complete_round() + + async def player_roll(self, user: Member): if user.id not in self.player_tiles: - await self.channel.send(user.mention + " You are not in the match.") + await self.channel.send(user.mention + " You are not in the match.", delete_after=10) return if self.state != 'roll': - await self.channel.send(user.mention + " You may not roll at this time.") + await self.channel.send(user.mention + " You may not roll at this time.", delete_after=10) return if self.round_has_rolled[user.id]: return roll = random.randint(1, 6) - await self.channel.send(user.mention + " rolled a **{0}**!".format(roll)) + self.rolls.append(await self.channel.send(f"{user.mention} rolled a **{roll}**!")) next_tile = self.player_tiles[user.id] + roll + # apply snakes and ladders if next_tile in BOARD: target = BOARD[next_tile] if target < next_tile: - await self.channel.send(user.mention + " slips on a snake and falls back to **{0}**".format(target)) + await self.channel.send( + f"{user.mention} slips on a snake and falls back to **{target}**", + delete_after=15 + ) else: - await self.channel.send(user.mention + " climbs a ladder to **{0}**".format(target)) + await self.channel.send( + f"{user.mention} climbs a ladder to **{target}**", + delete_after=15 + ) next_tile = target self.player_tiles[user.id] = min(100, next_tile) self.round_has_rolled[user.id] = True - if self._check_all_rolled(): - await self._complete_round() async def _complete_round(self): + self.state = 'post_round' + # check for winner winner = self._check_winner() if winner is None: - # there is a winner, start the next round + # there is no winner, start the next round await self.start_round() return + # announce winner and exit await self.channel.send("**Snakes and Ladders**: " + winner.mention + " has won the game! :tada:") self._destruct() - def _check_winner(self) -> discord.Member: + def _check_winner(self) -> Member: if self.state != 'post_round': return None return next((player for player in self.players if self.player_tiles[player.id] == 100), diff --git a/bot/utils/snakes/sal_board.py b/bot/utils/snakes/sal_board.py index d197bacdc9..1b8eab4512 100644 --- a/bot/utils/snakes/sal_board.py +++ b/bot/utils/snakes/sal_board.py @@ -1,8 +1,8 @@ -BOARD_TILE_SIZE = 56 # the size of each board tile -BOARD_PLAYER_SIZE = 20 # the size of each player icon -BOARD_MARGIN = (10, 0) # margins, in pixels (for player icons) +BOARD_TILE_SIZE = 56 # the size of each board tile +BOARD_PLAYER_SIZE = 20 # the size of each player icon +BOARD_MARGIN = (10, 0) # margins, in pixels (for player icons) PLAYER_ICON_IMAGE_SIZE = 32 # the size of the image to download, should a power of 2 and higher than BOARD_PLAYER_SIZE -MAX_PLAYERS = 4 # depends on the board size/quality, 4 is for the default board +MAX_PLAYERS = 4 # depends on the board size/quality, 4 is for the default board # board definition (from, to) BOARD = { From 9a7a2aa2b456de52b92f9fdd226d79730f8085ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Mon, 14 May 2018 19:24:34 +0200 Subject: [PATCH 16/27] made the snek draw feature even more fabulous. --- bot/cogs/snakes.py | 113 ++++++++++++++++++++------------ bot/utils/snakes/perlinsneks.py | 88 ++++++++++++++++++++----- 2 files changed, 143 insertions(+), 58 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index fff9277faa..c1fde83d85 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,4 +1,5 @@ import asyncio +import colorsys import logging import random import string @@ -442,35 +443,36 @@ def get_random_long_message(messages, retries=10): return get_random_long_message(messages, retries - 1) return long_message - embed = Embed() - user = ctx.message.author + with ctx.typing(): + embed = Embed() + user = ctx.message.author - if not message: + if not message: - # Get a random message from the users history - messages = [] - async for message in ctx.channel.history(limit=500).filter(predicate): - messages.append(message.content) + # Get a random message from the users history + messages = [] + async for message in ctx.channel.history(limit=500).filter(predicate): + messages.append(message.content) - message = get_random_long_message(messages) + message = get_random_long_message(messages) - # Set the avatar - if user.avatar is not None: - avatar = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}" - else: - avatar = ( - "https://img00.deviantart.net/eee3/i/2017/168/3/4/" - "discord__app__avatar_rev1_by_nodeviantarthere-dbd2tp9.png" + # Set the avatar + if user.avatar is not None: + avatar = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}" + else: + avatar = ( + "https://img00.deviantart.net/eee3/i/2017/168/3/4/" + "discord__app__avatar_rev1_by_nodeviantarthere-dbd2tp9.png" + ) + + # Build and send the embed + embed.set_author( + name=f"{user.name}#{user.discriminator}", + icon_url=avatar, ) + embed.description = f"*{self._snakify(message)}*" - # Build and send the embed - embed.set_author( - name=f"{user.name}#{user.discriminator}", - icon_url=avatar, - ) - embed.description = f"*{self._snakify(message)}*" - - await ctx.channel.send(embed=embed) + await ctx.channel.send(embed=embed) @command(name="snakes.fact()", aliases=["snakes.fact"]) async def snake_fact(self, ctx: Context): @@ -501,27 +503,54 @@ async def draw(self, ctx: Context): Made by Momo and kel during the first code jam. """ - # Generate random snake attributes - width = random.randint(8, 12) - length = random.randint(15, 22) - snek_color, text_color = random.sample(perlinsneks.SNAKE_COLORS, 2) - text = random.choice(perlinsneks.SNAKE_TEXTS) - - # Build and send the snek - factory = perlin.PerlinNoiseFactory(dimension=1, octaves=2) - image_frame = perlinsneks.create_snek_frame( - factory, - snake_width=width, - snake_length=length, - snake_color=snek_color, - text=text, - text_color=text_color, - ) - png_bytes = perlinsneks.frame_to_png_bytes(image_frame) + def beautiful_pastel(hue): + """ + Returns random bright pastels. + """ + + light = random.uniform(0.7, 0.85) + saturation = 1 + + rgb = colorsys.hls_to_rgb(hue, light, saturation) + hex_rgb = "" + + for part in rgb: + value = int(part * 0xFF) + hex_rgb += f"{value:02x}" + + return int(hex_rgb, 16) + + with ctx.typing(): + + # Generate random snake attributes + width = random.randint(6, 10) + length = random.randint(15, 22) + random_hue = random.random() + snek_color = beautiful_pastel(random_hue) + text_color = beautiful_pastel((random_hue + 0.5) % 1) + bg_color = ( + random.randint(32, 50), + random.randint(32, 50), + random.randint(50, 70), + ) + text = random.choice(perlinsneks.SNAKE_TEXTS) + + # Build and send the snek + factory = perlin.PerlinNoiseFactory(dimension=1, octaves=2) + image_frame = perlinsneks.create_snek_frame( + factory, + snake_width=width, + snake_length=length, + snake_color=snek_color, + text=text, + text_color=text_color, + bg_color=bg_color + ) + png_bytes = perlinsneks.frame_to_png_bytes(image_frame) - file = File(png_bytes, filename='snek.png') + file = File(png_bytes, filename='snek.png') - await ctx.send(file=file) + await ctx.send(file=file) @command(name="snakes.hatch()", aliases=["snakes.hatch", "hatch"]) async def hatch(self, ctx: Context): diff --git a/bot/utils/snakes/perlinsneks.py b/bot/utils/snakes/perlinsneks.py index 120c3daaf4..1cec331fec 100644 --- a/bot/utils/snakes/perlinsneks.py +++ b/bot/utils/snakes/perlinsneks.py @@ -26,33 +26,62 @@ Y = 1 ANGLE_RANGE = math.pi * 2 -SNAKE_COLORS = [ - 0x15c7ea, - 0xf2ea15, - 0x96ffa0, - 0xeeaaff, - 0xff8ce9, - 0xff8496, - 0xffb472, - 0xc1c9ff, -] - SNAKE_TEXTS = [ "snek it up", - "get yo snek on", - "snek yo heart out", + "get ur snek on", + "snek ur heart out", "snek 4 ever", "i luve snek", "snek bff", "boyfriend snek", - "snek yo homies", + "dont snek ur homies", "garden snek", "snektie", "snek keks", "birthday snek!", "snek tonight?", + "snek hott lips", + "snek u latr", "netflx and snek", - "sneks on plane", + "holy snek prey4u", + "ghowst snek hauntt u", + "ipekek snek syrop", + "2 snek 2 furius", + "the shawsnek redumpton", + "snekler's list", + "snekablanca", + "romeo n snekulet", + "citizn snek", + "gon wit the snek", + "dont step on snek", + "the wizrd uf snek", + "forrest snek", + "snek of musik", + "west snek story", + "snek wars eposide XI", + "2001: a snek odyssuuy", + "E.T. the snekstra terrastriul", + "snekkin' inth rain", + "dr sneklove", + "snekley kubrik", + "willium snekspeare", + "snek on tutanic", + "a snekwork orunge", + "the snek the bad n the ogly", + "the sneksorcist", + "gudd snek huntin", + "leonurdo disnekrio", + "denzal snekington", + "snekuel l jocksons", + "kevn snek", + "snekthony hopkuns", + "hugh snekman", + "snek but it glow in durk", + "snek but u cn ride it", + "snek but slep in ur bed", + "snek but mad frum plastk", + "snek but bulong 2 ur frnd", + "sneks on plene", "baby snek", "trouser snek", "momo snek", @@ -61,7 +90,34 @@ "old snek", "slimy snek", "snek attekk", - "snek get wrekk" + "snek get wrekk", + "snek you long time", + "carpenter snek", + "drain snek", + "eat ur face snek", + "kawaii snek", + "dis snek is soft", + "snek is 4 yers uld", + "pls feed snek, is hingry", + "snek? snek? sneeeeek!!", + "solid snek", + "big bos snek", + "snek republic", + "snekoslovakia", + "snek please!", + "i brok my snek :(", + "star snek the nxt generatin", + "azsnek tempul", + "discosnek", + "bottlsnek", + "turtlsnek", + "cashiers snek", + "mega snek!!", + "one tim i saw snek neked", + "snek cnt clim trees", + "snek in muth is jus tongue", + "juan snek", + "photosnek", ] From 701547da72f7209b2ce0157376bd17faaaa2ef22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Tue, 15 May 2018 00:25:30 +0200 Subject: [PATCH 17/27] SAL, get_snek, perlin --- Pipfile | 1 + Pipfile.lock | 10 +- bot/cogs/snakes.py | 156 ++++++++++++++++++++++++++++++-- bot/converters.py | 49 ++++++++++ bot/decorators.py | 24 +++++ bot/utils/__init__.py | 78 ++++++++++++++++ bot/utils/snakes/perlinsneks.py | 94 ------------------- bot/utils/snakes/sal.py | 6 +- 8 files changed, 315 insertions(+), 103 deletions(-) create mode 100644 bot/converters.py diff --git a/Pipfile b/Pipfile index 4adfb1b542..c3c8aa848d 100644 --- a/Pipfile +++ b/Pipfile @@ -13,6 +13,7 @@ logmatic-python = "*" aiohttp = "<2.3.0,>=2.0.0" websockets = ">=4.0,<5.0" yarl = "==1.1.1" +fuzzywuzzy = "*" [dev-packages] "flake8" = "*" diff --git a/Pipfile.lock b/Pipfile.lock index e0e9538562..588af97395 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0d592e6949aad4280702fcfa059e2db4e1a84f6b6098d4ec58eb317a68061f4f" + "sha256": "79f99439b4498a05f6e50060a7c505d7935fac9b8d71ea98147b95fa6b50dff8" }, "pipfile-spec": 6, "requires": { @@ -75,6 +75,14 @@ "index": "pypi", "version": "==0.19.2" }, + "fuzzywuzzy": { + "hashes": [ + "sha256:d40c22d2744dff84885b30bbfc07fab7875f641d070374331777a4d1808b8d4e", + "sha256:ecf490216fb4d76b558a03042ff8f45a8782f17326caca1384d834cbaa2c7e6f" + ], + "index": "pypi", + "version": "==0.16.0" + }, "idna": { "hashes": [ "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index c1fde83d85..3e631ee723 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -2,13 +2,19 @@ import colorsys import logging import random +import re import string import urllib +from typing import Any, Dict +import aiohttp +import async_timeout from discord import Embed, File, Member, Reaction -from discord.ext.commands import AutoShardedBot, Context, command +from discord.ext.commands import AutoShardedBot, Context, bot_has_permissions, command from bot.constants import OMDB_API_KEY, SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY +from bot.converters import Snake +from bot.decorators import locked from bot.utils.snakes import hatching, perlin, perlinsneks, sal log = logging.getLogger(__name__) @@ -72,6 +78,9 @@ # Max messages to train snake_chat on MSG_MAX = 100 +# get_snek constants +URL = "https://en.wikipedia.org/w/api.php?" + class Snakes: """ @@ -83,6 +92,9 @@ class Snakes: https://github.com/discord-python/code-jam-1 """ + wiki_brief = re.compile(r'(.*?)(=+ (.*?) =+)', flags=re.DOTALL) + valid = ('gif', 'png', 'jpeg', 'jpg', 'webp') + def __init__(self, bot: AutoShardedBot): self.active_sal = {} self.bot = bot @@ -91,6 +103,142 @@ def __init__(self, bot: AutoShardedBot): self.quiz_url = f"{SITE_API_URL}/snake_quiz" self.fact_url = f"{SITE_API_URL}/snake_fact" + async def _fetch(self, session, url, params=None): + if params is None: + params = {} + + async with async_timeout.timeout(10): + async with session.get(url, params=params) as response: + return await response.json() + + async def get_snek(self, name: str) -> Dict[str, Any]: + """ + Goes online and fetches all the data from a wikipedia article + about a snake. Builds a dict that the get() method can use. + + Created by Ava and eivl for the very first code jam on PythonDiscord. + + :param name: The name of the snake to get information for - omit for a random snake + :return: A dict containing information on a snake + """ + + snake_info = {} + + async with aiohttp.ClientSession() as session: + params = { + 'format': 'json', + 'action': 'query', + 'list': 'search', + 'srsearch': name, + 'utf8': '', + 'srlimit': '1', + } + + json = await self._fetch(session, URL, params=params) + + # wikipedia does have a error page + try: + pageid = json["query"]["search"][0]["pageid"] + except KeyError: + # Wikipedia error page ID(?) + pageid = 41118 + + params = { + 'format': 'json', + 'action': 'query', + 'prop': 'extracts|images|info', + 'exlimit': 'max', + 'explaintext': '', + 'inprop': 'url', + 'pageids': pageid + } + + json = await self._fetch(session, URL, params=params) + + # constructing dict - handle exceptions later + try: + snake_info["title"] = json["query"]["pages"][f"{pageid}"]["title"] + snake_info["extract"] = json["query"]["pages"][f"{pageid}"]["extract"] + snake_info["images"] = json["query"]["pages"][f"{pageid}"]["images"] + snake_info["fullurl"] = json["query"]["pages"][f"{pageid}"]["fullurl"] + snake_info["pageid"] = json["query"]["pages"][f"{pageid}"]["pageid"] + except KeyError: + snake_info["error"] = True + + if snake_info["images"]: + i_url = 'https://commons.wikimedia.org/wiki/Special:FilePath/' + image_list = [] + map_list = [] + thumb_list = [] + + # Wikipedia has arbitrary images that are not snakes + banned = [ + 'Commons-logo.svg', + 'Red%20Pencil%20Icon.png', + 'distribution', + 'The%20Death%20of%20Cleopatra%20arthur.jpg', + 'Head%20of%20holotype', + 'locator', + 'Woma.png', + '-map.', + '.svg', + 'ange.', + 'Adder%20(PSF).png' + ] + + for image in snake_info["images"]: + # images come in the format of `File:filename.extension` + file, sep, filename = image["title"].partition(':') + filename = filename.replace(" ", "%20") # Wikipedia returns good data! + + if not filename.startswith('Map'): + if any(ban in filename for ban in banned): + pass + else: + image_list.append(f"{i_url}{filename}") + thumb_list.append(f"{i_url}{filename}?width=100") + else: + map_list.append(f"{i_url}{filename}") + + snake_info["image_list"] = image_list + snake_info["map_list"] = map_list + snake_info["thumb_list"] = thumb_list + return snake_info + + @command(name="snakes.get()", aliases=["snakes.get"]) + @bot_has_permissions(manage_messages=True) + @locked() + async def get(self, ctx: Context, name: Snake = None): + """ + Fetches information about a snake from Wikipedia. + :param ctx: Context object passed from discord.py + :param name: Optional, the name of the snake to get information for - omit for a random snake + """ + if name is None: + name = Snake.random() + + data = await self.get_snek(name) + + if data.get('error'): + return await ctx.send('Could not fetch data from Wikipedia.') + + match = self.wiki_brief.match(data['extract']) + description = match.group(1) if match else None + description = description.replace("\n", "\n\n") # Give us some proper paragraphs. + embed = Embed( + title=data['title'], + description=description, + colour=0x59982F, + ) + + embed.set_footer(text='Powered by Wikipedia') + + emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' + image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) + embed.set_image(url=image) + + await ctx.send(embed=embed) + @staticmethod def _snakify(message): """ @@ -195,6 +343,7 @@ async def random_snake_name(self, ctx: Context, name: str = None): return await ctx.send(embed=embed) + @bot_has_permissions(manage_messages=True) @command(name="snakes.antidote()", aliases=["snakes.antidote"]) async def antidote(self, ctx: Context): """ @@ -225,11 +374,6 @@ def event_check(reaction_: Reaction, user_: Member): )) ) - # Check to see if the bot can remove reactions - if not ctx.channel.permissions_for(ctx.guild.me).manage_messages: - log.warning(f"Unable to start Antidote game - Missing manage_messages permissions in {ctx.channel}") - return - # Initialize variables antidote_tries = 0 antidote_guess_count = 0 diff --git a/bot/converters.py b/bot/converters.py new file mode 100644 index 0000000000..48a0225402 --- /dev/null +++ b/bot/converters.py @@ -0,0 +1,49 @@ +import json +import random + +import discord +from discord.ext.commands import Converter +from fuzzywuzzy import fuzz + +from bot.utils import disambiguate + + +class Snake(Converter): + with open('snakes.json', 'r') as f: + snakes = json.load(f) + + async def convert(self, ctx, name): + name = name.lower() + + if name == 'python': + return 'Python (programming language)' + + def get_potential(iterable, *, threshold=80): + nonlocal name + potential = [] + + for item in iterable: + original, item = item, item.lower() + + if name == item: + return [original] + + a, b = fuzz.ratio(name, item), fuzz.partial_ratio(name, item) + if a >= threshold or b >= threshold: + potential.append(original) + + return potential + + all_names = self.snakes.keys() | self.snakes.values() + timeout = len(all_names) * (3 / 4) + + embed = discord.Embed(title='Found multiple choices. Please choose the correct one.', colour=0x59982F) + embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url) + + name = await disambiguate(ctx, get_potential(all_names), timeout=timeout, embed=embed) + return self.snakes.get(name, name) + + @classmethod + def random(cls): + # list cast necessary because choice() uses indexing internally + return random.choice(list(cls.snakes.values())) diff --git a/bot/decorators.py b/bot/decorators.py index b84b2c3602..4326e1ed28 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -1,4 +1,7 @@ import logging +from asyncio import Lock +from functools import wraps +from weakref import WeakValueDictionary from discord.ext import commands from discord.ext.commands import Context @@ -46,3 +49,24 @@ async def predicate(ctx: Context): f"The result of the in_channel check was {check}.") return check return commands.check(predicate) + + +def locked(): + """ + Allows the user to only run one instance of the decorated command at a time. + Subsequent calls to the command from the same author are + ignored until the command has completed invocation. + This decorator has to go before (below) the `command` decorator. + """ + def wrap(func): + func.__locks = WeakValueDictionary() + + @wraps(func) + async def inner(self, ctx, *args, **kwargs): + lock = func.__locks.setdefault(ctx.author.id, Lock()) + if lock.locked(): + return + async with func.__locks.setdefault(ctx.author.id, Lock()): + return await func(self, ctx, *args, **kwargs) + return inner + return wrap diff --git a/bot/utils/__init__.py b/bot/utils/__init__.py index aaea1feeb7..c3e483707b 100644 --- a/bot/utils/__init__.py +++ b/bot/utils/__init__.py @@ -1,3 +1,81 @@ +import asyncio +from typing import List + +import discord +from discord.ext.commands import BadArgument, Context + +from bot.pagination import LinePaginator + + +async def disambiguate( + ctx: Context, entries: List[str], *, timeout: float = 30, + per_page: int = 20, empty: bool = False, embed: discord.Embed = None +): + """ + Has the user choose between multiple entries in case one could not be chosen automatically. + :param ctx: Context object from discord.py + :param entries: List of items for user to choose from + :param timeout: Number of seconds to wait before canceling disambiguation + :param per_page: Entries per embed page + :param empty: Whether the paginator should have an extra line between items + :param embed: The embed that the paginator will use. + :return: Users choice for correct entry. + """ + + if len(entries) == 0: + raise BadArgument('No matches found.') + + if len(entries) == 1: + return entries[0] + + choices = (f'{index}: {entry}' for index, entry in enumerate(entries, start=1)) + + def check(message): + return (message.content.isdigit() and + message.author == ctx.author and + message.channel == ctx.channel) + + try: + if embed is None: + embed = discord.Embed() + + coro1 = ctx.bot.wait_for('message', check=check, timeout=timeout) + coro2 = LinePaginator.paginate(choices, ctx, embed=embed, max_lines=per_page, + empty=empty, max_size=6000, timeout=9000) + + # wait_for timeout will go to except instead of the wait_for thing as I expected + futures = [asyncio.ensure_future(coro1), asyncio.ensure_future(coro2)] + done, pending = await asyncio.wait(futures, return_when=asyncio.FIRST_COMPLETED, loop=ctx.bot.loop) + + # :yert: + result = list(done)[0].result() + + # Pagination was canceled - result is None + if result is None: + for coro in pending: + coro.cancel() + raise BadArgument('Canceled.') + + # Pagination was not initiated, only one page + if result.author == ctx.bot.user: + # Continue the wait_for + result = await list(pending)[0] + + # Love that duplicate code + for coro in pending: + coro.cancel() + except asyncio.TimeoutError: + raise BadArgument('Timed out.') + + # Guaranteed to not error because of isdigit() in check + index = int(result.content) + + try: + return entries[index - 1] + except IndexError: + raise BadArgument('Invalid choice.') + + class CaseInsensitiveDict(dict): """ We found this class on StackOverflow. Thanks to m000 for writing it! diff --git a/bot/utils/snakes/perlinsneks.py b/bot/utils/snakes/perlinsneks.py index 1cec331fec..662281775f 100644 --- a/bot/utils/snakes/perlinsneks.py +++ b/bot/utils/snakes/perlinsneks.py @@ -26,100 +26,6 @@ Y = 1 ANGLE_RANGE = math.pi * 2 -SNAKE_TEXTS = [ - "snek it up", - "get ur snek on", - "snek ur heart out", - "snek 4 ever", - "i luve snek", - "snek bff", - "boyfriend snek", - "dont snek ur homies", - "garden snek", - "snektie", - "snek keks", - "birthday snek!", - "snek tonight?", - "snek hott lips", - "snek u latr", - "netflx and snek", - "holy snek prey4u", - "ghowst snek hauntt u", - "ipekek snek syrop", - "2 snek 2 furius", - "the shawsnek redumpton", - "snekler's list", - "snekablanca", - "romeo n snekulet", - "citizn snek", - "gon wit the snek", - "dont step on snek", - "the wizrd uf snek", - "forrest snek", - "snek of musik", - "west snek story", - "snek wars eposide XI", - "2001: a snek odyssuuy", - "E.T. the snekstra terrastriul", - "snekkin' inth rain", - "dr sneklove", - "snekley kubrik", - "willium snekspeare", - "snek on tutanic", - "a snekwork orunge", - "the snek the bad n the ogly", - "the sneksorcist", - "gudd snek huntin", - "leonurdo disnekrio", - "denzal snekington", - "snekuel l jocksons", - "kevn snek", - "snekthony hopkuns", - "hugh snekman", - "snek but it glow in durk", - "snek but u cn ride it", - "snek but slep in ur bed", - "snek but mad frum plastk", - "snek but bulong 2 ur frnd", - "sneks on plene", - "baby snek", - "trouser snek", - "momo snek", - "fast snek", - "super slow snek", - "old snek", - "slimy snek", - "snek attekk", - "snek get wrekk", - "snek you long time", - "carpenter snek", - "drain snek", - "eat ur face snek", - "kawaii snek", - "dis snek is soft", - "snek is 4 yers uld", - "pls feed snek, is hingry", - "snek? snek? sneeeeek!!", - "solid snek", - "big bos snek", - "snek republic", - "snekoslovakia", - "snek please!", - "i brok my snek :(", - "star snek the nxt generatin", - "azsnek tempul", - "discosnek", - "bottlsnek", - "turtlsnek", - "cashiers snek", - "mega snek!!", - "one tim i saw snek neked", - "snek cnt clim trees", - "snek in muth is jus tongue", - "juan snek", - "photosnek", -] - def create_snek_frame( perlin_factory: perlin.PerlinNoiseFactory, perlin_lookup_vertical_shift: float = 0, diff --git a/bot/utils/snakes/sal.py b/bot/utils/snakes/sal.py index 0bc81bac25..8530d8a0f0 100644 --- a/bot/utils/snakes/sal.py +++ b/bot/utils/snakes/sal.py @@ -108,6 +108,7 @@ def startup_event_check(reaction_: Reaction, user_: Member): elif reaction.emoji == CANCEL_EMOJI: if self.ctx.author == user: await self.cancel_game(user) + return else: await self.player_leave(user) elif reaction.emoji == START_EMOJI: @@ -122,7 +123,7 @@ def startup_event_check(reaction_: Reaction, user_: Member): except asyncio.TimeoutError: log.debug("Snakes and Ladders timed out waiting for a reaction") self.cancel_game(self.author) - break # We're done, no reactions for the last 5 minutes + return # We're done, no reactions for the last 5 minutes async def _add_player(self, user: Member): self.players.append(user) @@ -279,6 +280,7 @@ def game_event_check(reaction_: Reaction, user_: Member): elif reaction.emoji == CANCEL_EMOJI: if self.ctx.author == user: await self.cancel_game(user) + return else: await self.player_leave(user) @@ -290,7 +292,7 @@ def game_event_check(reaction_: Reaction, user_: Member): except asyncio.TimeoutError: log.debug("Snakes and Ladders timed out waiting for a reaction") await self.cancel_game(self.author) - break # We're done, no reactions for the last 5 minutes + return # We're done, no reactions for the last 5 minutes # Round completed await self._complete_round() From 1aba2d9b57a719fbbe420bc4f9a2ac0f50072314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Tue, 15 May 2018 11:16:14 +0200 Subject: [PATCH 18/27] Fixing some minor problems with startup log spam. The bot will now only try to post to DEVLOG if it's not in debug mode. Also added the new snake API endpoints and prepping for database handling of all snek related datapoints. --- Pipfile | 1 + Pipfile.lock | 15 +++++++++++---- bot/cogs/events.py | 13 +++++++++---- bot/cogs/logging.py | 5 +++-- bot/cogs/snakes.py | 17 +++++++++++++---- bot/converters.py | 3 --- 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Pipfile b/Pipfile index c3c8aa848d..13843c859c 100644 --- a/Pipfile +++ b/Pipfile @@ -14,6 +14,7 @@ aiohttp = "<2.3.0,>=2.0.0" websockets = ">=4.0,<5.0" yarl = "==1.1.1" fuzzywuzzy = "*" +python-levenshtein = "*" [dev-packages] "flake8" = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 588af97395..58cf4b1460 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "79f99439b4498a05f6e50060a7c505d7935fac9b8d71ea98147b95fa6b50dff8" + "sha256": "dffbd618e2339f4e3e7b0e9a21bf27cfbd676173b123f52c9fcf1f11cfc5a6fd" }, "pipfile-spec": 6, "requires": { @@ -155,6 +155,13 @@ ], "version": "==0.1.8" }, + "python-levenshtein": { + "hashes": [ + "sha256:033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" + ], + "index": "pypi", + "version": "==0.12.0" + }, "sympy": { "hashes": [ "sha256:ac5b57691bc43919dcc21167660a57cc51797c28a4301a6144eff07b751216a4" @@ -360,10 +367,10 @@ }, "pbr": { "hashes": [ - "sha256:4e8a0ed6a8705a26768f4c3da26026013b157821fe5f95881599556ea9d91c19", - "sha256:dae4aaa78eafcad10ce2581fc34d694faa616727837fd8e55c1a00951ad6744f" + "sha256:680bf5ba9b28dd56e08eb7c267991a37c7a5f90a92c2e07108829931a50ff80a", + "sha256:6874feb22334a1e9a515193cba797664e940b763440c88115009ec323a7f2df5" ], - "version": "==4.0.2" + "version": "==4.0.3" }, "pycodestyle": { "hashes": [ diff --git a/bot/cogs/events.py b/bot/cogs/events.py index 3d89dc4b55..5106766a52 100644 --- a/bot/cogs/events.py +++ b/bot/cogs/events.py @@ -7,7 +7,11 @@ NoPrivateMessage, UserInputError ) -from bot.constants import DEVLOG_CHANNEL, PYTHON_GUILD, SITE_API_KEY, SITE_API_URL +from bot.constants import ( + DEBUG_MODE, DEVLOG_CHANNEL, + PYTHON_GUILD, SITE_API_KEY, + SITE_API_URL +) from bot.utils import chunks log = logging.getLogger(__name__) @@ -112,9 +116,10 @@ async def on_ready(self): name=key.title(), value=str(value) ) - await self.bot.get_channel(DEVLOG_CHANNEL).send( - embed=embed - ) + if not DEBUG_MODE: + await self.bot.get_channel(DEVLOG_CHANNEL).send( + embed=embed + ) async def on_member_update(self, before: Member, after: Member): if before.roles == after.roles and before.name == after.name and before.discriminator == after.discriminator: diff --git a/bot/cogs/logging.py b/bot/cogs/logging.py index 6d46a3fb43..60403ec2df 100644 --- a/bot/cogs/logging.py +++ b/bot/cogs/logging.py @@ -3,7 +3,7 @@ from discord import Embed from discord.ext.commands import AutoShardedBot -from bot.constants import DEVLOG_CHANNEL +from bot.constants import DEBUG_MODE, DEVLOG_CHANNEL log = logging.getLogger(__name__) @@ -26,7 +26,8 @@ async def on_ready(self): icon_url="https://raw.githubusercontent.com/discord-python/branding/master/logos/logo_circle.png" ) - await self.bot.get_channel(DEVLOG_CHANNEL).send(embed=embed) + if not DEBUG_MODE: + await self.bot.get_channel(DEVLOG_CHANNEL).send(embed=embed) def setup(bot): diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 3e631ee723..445ee11101 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -100,8 +100,13 @@ def __init__(self, bot: AutoShardedBot): self.bot = bot self.SNAKES = ['black cobra', 'children\'s python'] # temporary self.headers = {"X-API-KEY": SITE_API_KEY} + + # Build API urls. self.quiz_url = f"{SITE_API_URL}/snake_quiz" - self.fact_url = f"{SITE_API_URL}/snake_fact" + self.facts_url = f"{SITE_API_URL}/snake_facts" + self.names_url = f"{SITE_API_URL}/snake_names" + self.idioms_url = f"{SITE_API_URL}/snake_idioms" + self.idioms_url = f"{SITE_API_URL}/snake_movies" async def _fetch(self, session, url, params=None): if params is None: @@ -265,12 +270,16 @@ def _snakify(message): return message - def get_snake_name(self) -> str: + async def get_snake_name(self) -> Dict[str, str]: """ Gets a random snake name. :return: A random snake name, as a string. """ - return random.choice(self.SNAKES) + + response = await self.bot.http_session.get(self.names_url, headers=self.headers) + name_data = await response.json() + + return name_data @command(name="snakes.name()", aliases=["snakes.name", "snakes.name_gen", "snakes.name_gen()"]) async def random_snake_name(self, ctx: Context, name: str = None): @@ -628,7 +637,7 @@ async def snake_fact(self, ctx: Context): """ # Get a fact from the API. - response = await self.bot.http_session.get(self.fact_url, headers=self.headers) + response = await self.bot.http_session.get(self.facts_url, headers=self.headers) question = await response.json() # Build and send the embed. diff --git a/bot/converters.py b/bot/converters.py index 48a0225402..b8585716b0 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -1,4 +1,3 @@ -import json import random import discord @@ -9,8 +8,6 @@ class Snake(Converter): - with open('snakes.json', 'r') as f: - snakes = json.load(f) async def convert(self, ctx, name): name = name.lower() From 1b818181285fb7e902116ee56eae78170cd01b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Tue, 15 May 2018 13:00:58 +0200 Subject: [PATCH 19/27] Pointed all relevant functions at their respective snake API endpoints. Tested. All the data is now in our database, and everything appears to work. --- bot/cogs/events.py | 2 +- bot/cogs/snakes.py | 109 ++++++++++++++++++++++++++------------------- bot/constants.py | 1 + bot/converters.py | 27 ++++++----- 4 files changed, 80 insertions(+), 59 deletions(-) diff --git a/bot/cogs/events.py b/bot/cogs/events.py index 4a9be15233..ad53b0f8f7 100644 --- a/bot/cogs/events.py +++ b/bot/cogs/events.py @@ -73,7 +73,7 @@ async def on_command_error(self, ctx: Context, e: CommandError): f"Sorry, an unexpected error occurred. Please let us know!\n\n```{e}```" ) raise e.original - log.error(f"COMMAND ERROR: '{e}'") + raise e async def on_ready(self): users = [] diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 73240c548a..efea0723e1 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -19,6 +19,9 @@ log = logging.getLogger(__name__) +# Color +SNAKE_COLOR = 0x399600 + # Antidote constants SYRINGE_EMOJI = "\U0001F489" # :syringe: PILL_EMOJI = "\U0001F48A" # :pill: @@ -98,7 +101,6 @@ class Snakes: def __init__(self, bot: AutoShardedBot): self.active_sal = {} self.bot = bot - self.SNAKES = ['black cobra', 'children\'s python'] # temporary self.headers = {"X-API-KEY": SITE_API_KEY} # Build API urls. @@ -106,7 +108,6 @@ def __init__(self, bot: AutoShardedBot): self.facts_url = f"{SITE_API_URL}/snake_facts" self.names_url = f"{SITE_API_URL}/snake_names" self.idioms_url = f"{SITE_API_URL}/snake_idioms" - self.idioms_url = f"{SITE_API_URL}/snake_movies" async def _fetch(self, session, url, params=None): if params is None: @@ -119,7 +120,7 @@ async def _fetch(self, session, url, params=None): async def get_snek(self, name: str) -> Dict[str, Any]: """ Goes online and fetches all the data from a wikipedia article - about a snake. Builds a dict that the get() method can use. + about a snake. Builds a dict that the .get() method can use. Created by Ava and eivl for the very first code jam on PythonDiscord. @@ -218,31 +219,46 @@ async def get(self, ctx: Context, name: Snake = None): Fetches information about a snake from Wikipedia. :param ctx: Context object passed from discord.py :param name: Optional, the name of the snake to get information for - omit for a random snake - """ - if name is None: - name = await Snake.random() - - data = await self.get_snek(name) - if data.get('error'): - return await ctx.send('Could not fetch data from Wikipedia.') - - match = self.wiki_brief.match(data['extract']) - description = match.group(1) if match else None - description = description.replace("\n", "\n\n") # Give us some proper paragraphs. - embed = Embed( - title=data['title'], - description=description, - colour=0x59982F, - ) + Created by Ava and eivl + """ - embed.set_footer(text='Powered by Wikipedia') + with ctx.typing(): + if name is None: + name = await Snake.random() + + data = await self.get_snek(name) + + if data.get('error'): + return await ctx.send('Could not fetch data from Wikipedia.') + + match = self.wiki_brief.match(data['extract']) + description = match.group(1) if match else None + description = description.replace("\n", "\n\n") # Give us some proper paragraphs. + + # Shorten the description if needed + if len(description) > 1000: + description = description[:1000] + last_newline = description.rfind("\n") + if last_newline > 0: + description = description[:last_newline] + + # Strip and add the Wiki link. + description = description.strip("\n") + description += f"\n\nRead more on [Wikipedia]({data['fullurl']})" + + # Build and send the embed. + embed = Embed( + title=data['title'], + description=description, + colour=0x59982F, + ) - emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' - image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) - embed.set_image(url=image) + emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' + image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) + embed.set_image(url=image) - await ctx.send(embed=embed) + await ctx.send(embed=embed) @staticmethod def _snakify(message): @@ -346,7 +362,7 @@ async def random_snake_name(self, ctx: Context, name: str = None): embed = Embed( title="Snake name", description=f"Your snake-name is **{result}**", - color=0x399600 + color=SNAKE_COLOR ) return await ctx.send(embed=embed) @@ -392,7 +408,7 @@ def event_check(reaction_: Reaction, user_: Member): page_result_list = [] win = False - antidote_embed = Embed(color=0x399600, title="Antidote") + antidote_embed = Embed(color=SNAKE_COLOR, title="Antidote") antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) # Generate answer @@ -472,7 +488,7 @@ def event_check(reaction_: Reaction, user_: Member): # Winning / Ending Screen if win is True: - antidote_embed = Embed(color=0x399600, title="Antidote") + antidote_embed = Embed(color=SNAKE_COLOR, title="Antidote") antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) antidote_embed.set_image(url="https://i.makeagif.com/media/7-12-2015/Cj1pts.gif") antidote_embed.add_field(name=f"You have created the snake antidote!", @@ -480,7 +496,7 @@ def event_check(reaction_: Reaction, user_: Member): f"You had {10 - antidote_tries} tries remaining.") await board_id.edit(embed=antidote_embed) else: - antidote_embed = Embed(color=0x399600, title="Antidote") + antidote_embed = Embed(color=SNAKE_COLOR, title="Antidote") antidote_embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) antidote_embed.set_image(url="https://media.giphy.com/media/ceeN6U57leAhi/giphy.gif") antidote_embed.add_field(name=EMPTY_UNICODE, @@ -518,7 +534,7 @@ def valid_answer(reaction, user): # Build and send the embed. embed = Embed( - color=0x399600, + color=SNAKE_COLOR, title=question["question"], description="\n".join( [f"**{key.upper()}**: {answer}" for key, answer in options.items()] @@ -554,7 +570,7 @@ async def zen(self, ctx: Context): embed = Embed( title="Zzzen of Pythhon", - color=0x399600 + color=SNAKE_COLOR ) # Get the zen quote and snakify it @@ -568,7 +584,7 @@ async def zen(self, ctx: Context): ) @command(name="snakes.snakify()", aliases=["snakes.snakify"]) - async def snake_chat(self, ctx: Context, message: str = None): + async def snakify(self, ctx: Context, message: str = None): """ How would I talk if I were a snake? :param ctx: context @@ -642,7 +658,7 @@ async def snake_fact(self, ctx: Context): # Build and send the embed. embed = Embed( title="Snake fact", - color=0x399600, + color=SNAKE_COLOR, description=question ) await ctx.channel.send(embed=embed) @@ -685,7 +701,10 @@ def beautiful_pastel(hue): random.randint(32, 50), random.randint(50, 70), ) - text = random.choice(perlinsneks.SNAKE_TEXTS) + + # Get a snake idiom from the API + response = await self.bot.http_session.get(self.idioms_url, headers=self.headers) + text = await response.json() # Build and send the snek factory = perlin.PerlinNoiseFactory(dimension=1, octaves=2) @@ -750,7 +769,8 @@ async def video(self, ctx: Context, search: str = None): if search: query = search + ' snake' else: - query = 'snake' + snake = await self.get_snake_name() + query = snake['name'] # Build the URL and make the request url = f'https://www.googleapis.com/youtube/v3/search' @@ -767,11 +787,14 @@ async def video(self, ctx: Context, search: str = None): data = response['items'] # Send the user a video - num = random.randint(0, 5) # 5 videos are returned from the api - youtube_base_url = 'https://www.youtube.com/watch?v=' - await ctx.channel.send( - content=f"{youtube_base_url}{data[num]['id']['videoId']}" - ) + if len(data) > 0: + num = random.randint(0, len(data) - 1) + youtube_base_url = 'https://www.youtube.com/watch?v=' + await ctx.channel.send( + content=f"{youtube_base_url}{data[num]['id']['videoId']}" + ) + else: + log.warning(f"CRITICAL ERROR: YouTube API returned {response}") @command(name="snakes.sal()", aliases=["snakes.sal"]) async def sal(self, ctx: Context): @@ -796,8 +819,6 @@ async def sal(self, ctx: Context): await game.open_game() - # region: Snake movies - @command(name="snakes.movie()", aliases=["movie"]) async def movie(self, ctx: Context): """ @@ -819,7 +840,6 @@ async def movie(self, ctx: Context): "apikey": OMDB_API_KEY } ) - data = await response.json() movie = random.choice(data["Search"])["imdbID"] @@ -830,12 +850,11 @@ async def movie(self, ctx: Context): "apikey": OMDB_API_KEY } ) - data = await response.json() embed = Embed( title=data["Title"], - color=0x399600 + color=SNAKE_COLOR ) del data["Response"], data["imdbID"], data["Title"] @@ -870,8 +889,6 @@ async def movie(self, ctx: Context): embed=embed ) - # endregion - def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/constants.py b/bot/constants.py index 424c5f7f74..a11be75066 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -41,6 +41,7 @@ SITE_API_URL = f"{SITE_PROTOCOL}://api.{SITE_URL}" GITHUB_URL_BOT = "https://github.com/discord-python/bot" BOT_AVATAR_URL = "https://raw.githubusercontent.com/discord-python/branding/master/logos/logo_circle/logo_circle.png" +OMDB_URL = "http://www.omdbapi.com/" # Keys DEPLOY_BOT_KEY = os.environ.get("DEPLOY_BOT_KEY") diff --git a/bot/converters.py b/bot/converters.py index 3553ba6a8b..c1afeabbeb 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -16,6 +16,7 @@ class Snake(Converter): snakes = None async def convert(self, ctx, name): + await self.build_list() name = name.lower() if name == 'python': @@ -37,26 +38,18 @@ def get_potential(iterable, *, threshold=80): return potential - names = [snake['name'] for snake in self.snakes] - scientific = [snake['scientific'] for snake in self.snakes] - all_names = names | scientific + names = {snake['name']: snake['scientific'] for snake in self.snakes} + all_names = names.keys() | names.values() timeout = len(all_names) * (3 / 4) embed = discord.Embed(title='Found multiple choices. Please choose the correct one.', colour=0x59982F) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url) name = await disambiguate(ctx, get_potential(all_names), timeout=timeout, embed=embed) - return self.snakes.get(name, name) + return names.get(name, name) @classmethod - async def random(cls): - """ - This is stupid. We should find a way to - somehow get the global session into a - global context, so I can get it from here. - :return: - """ - + async def build_list(cls): if cls.snakes is None: if DEBUG_MODE: http_session = ClientSession( @@ -82,5 +75,15 @@ async def random(cls): cls.snakes = await response.json() http_session.close() + @classmethod + async def random(cls): + """ + This is stupid. We should find a way to + somehow get the global session into a + global context, so I can get it from here. + :return: + """ + + await cls.build_list() names = [snake['scientific'] for snake in cls.snakes] return random.choice(names) From d8572e8ed3907091151a687fc86a6eaf87be4276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Tue, 15 May 2018 14:18:21 +0200 Subject: [PATCH 20/27] Added the guessing game by Ava and eivl --- bot/cogs/snakes.py | 127 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 99 insertions(+), 28 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index efea0723e1..b9177a51ee 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -9,7 +9,7 @@ import aiohttp import async_timeout -from discord import Embed, File, Member, Reaction +from discord import Embed, File, Member, Message, Reaction, from discord.ext.commands import AutoShardedBot, Context, bot_has_permissions, command from bot.constants import OMDB_API_KEY, SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY @@ -84,6 +84,33 @@ # get_snek constants URL = "https://en.wikipedia.org/w/api.php?" +# snake guess responses +INCORRECT_GUESS = [ + "Nope, that's not what it is.", + "Not quite.", + "Not even close.", + "Terrible guess.", + "Nnnno.", + "Dude. No.", + "I thought everyone knew this one.", + "Guess you suck at snakes.", + "Bet you feel stupid now.", + "Hahahaha, no.", + "Did you hit the wrong key?" +] + +CORRECT_GUESS = [ + "**WRONG**. Wait, no, actually you're right.", + "Yeah, you got it!", + "Yep, that's exactly what it is.", + "Uh-huh. Yep yep yep.", + "Yeah that's right.", + "Yup. How did you know that?", + "Are you a herpetologist?", + "Sure, okay, but I bet you can't pronounce it.", + "Are you cheating?" +] + class Snakes: """ @@ -297,6 +324,44 @@ async def get_snake_name(self) -> Dict[str, str]: return name_data + async def validate_answer(self, ctx: Context, message: Message, answer: str, options: list): + """ + Validate the answer using a reaction event loop + :return: + """ + + def predicate(reaction, user): + """ + Test if the the answer is valid and can be evaluated. + """ + return ( + reaction.message.id == message.id # The reaction is attached to the question we asked. + and user == ctx.author # It's the user who triggered the quiz. + and str(reaction.emoji) in ANSWERS_EMOJI.values() # The reaction is one of the options. + ) + + for emoji in ANSWERS_EMOJI.values(): + await message.add_reaction(emoji) + + # Validate the answer + try: + reaction, user = await ctx.bot.wait_for("reaction_add", timeout=45.0, check=predicate) + except asyncio.TimeoutError: + await ctx.channel.send(f"You took too long. The correct answer was **{options[answer]}**.") + await message.clear_reactions() + return + + if str(reaction.emoji) == ANSWERS_EMOJI[answer]: + await ctx.send(f"{random.choice(CORRECT_GUESS)} The correct answer was **{options[answer]}**.") + else: + wrong_answer = ANSWERS_EMOJI_REVERSE[str(reaction.emoji)] + await ctx.send( + f"{random.choice(INCORRECT_GUESS)} **{wrong_answer}** is incorrect. " + f"The correct answer was **{options[answer].lower()}**." + ) + + await message.clear_reactions() + @command(name="snakes.name()", aliases=["snakes.name", "snakes.name_gen", "snakes.name_gen()"]) async def random_snake_name(self, ctx: Context, name: str = None): """ @@ -516,16 +581,6 @@ async def quiz(self, ctx: Context): and modified by lemon for inclusion in this bot. """ - def valid_answer(reaction, user): - """ - Test if the the answer is valid and can be evaluated. - """ - return ( - reaction.message.id == quiz.id # The reaction is attached to the question we asked. - and user == ctx.author # It's the user who triggered the quiz. - and str(reaction.emoji) in ANSWERS_EMOJI.values() # The reaction is one of the options. - ) - # Prepare a question. response = await self.bot.http_session.get(self.quiz_url, headers=self.headers) question = await response.json() @@ -540,24 +595,9 @@ def valid_answer(reaction, user): [f"**{key.upper()}**: {answer}" for key, answer in options.items()] ) ) - quiz = await ctx.channel.send("", embed=embed) - for emoji in ANSWERS_EMOJI.values(): - await quiz.add_reaction(emoji) - - # Validate the answer - try: - reaction, user = await ctx.bot.wait_for("reaction_add", timeout=20.0, check=valid_answer) - except asyncio.TimeoutError: - await ctx.channel.send("Bah! You took too long.") - return - if str(reaction.emoji) == ANSWERS_EMOJI[answer]: - await ctx.channel.send(f"You selected **{options[answer]}**, which is correct! Well done!") - else: - wrong_answer = ANSWERS_EMOJI_REVERSE[str(reaction.emoji)] - await ctx.channel.send( - f"Sorry, **{wrong_answer}** is incorrect. The correct answer was \"**{options[answer]}**\"." - ) + quiz = await ctx.channel.send("", embed=embed) + await self.validate_answer(ctx, quiz, answer, options) @command(name="snakes.zen()", aliases=["zen"]) async def zen(self, ctx: Context): @@ -819,6 +859,37 @@ async def sal(self, ctx: Context): await game.open_game() + @command(name="snakes.guess()", aliases=["snakes.guess", "identify"]) + @locked() + async def guess(self, ctx): + """ + Snake identifying game! + """ + + with ctx.typing(): + + image = None + + while image is None: + snakes = [await Snake.random() for _ in range(4)] + snake = random.choice(snakes) + answer = "abcd"[snakes.index(snake)] + + data = await self.get_snek(snake) + + image = next((url for url in data['image_list'] if url.endswith(self.valid)), None) + + embed = Embed( + title='Which of the following is the snake in the image?', + description="\n".join(f"{'ABCD'[snakes.index(snake)]}: {snake}" for snake in snakes), + colour=SNAKE_COLOR + ) + embed.set_image(url=image) + + guess = await ctx.send(embed=embed) + options = {f"{'abcd'[snakes.index(snake)]}": snake for snake in snakes} + await self.validate_answer(ctx, guess, answer, options) + @command(name="snakes.movie()", aliases=["movie"]) async def movie(self, ctx: Context): """ From 1a179ec8925ce972dd43c53bb09c33bf7721f097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Tue, 15 May 2018 14:21:36 +0200 Subject: [PATCH 21/27] Trailing comma, baby --- bot/cogs/snakes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index b9177a51ee..41fe8f8cd6 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -9,7 +9,7 @@ import aiohttp import async_timeout -from discord import Embed, File, Member, Message, Reaction, +from discord import Embed, File, Member, Message, Reaction from discord.ext.commands import AutoShardedBot, Context, bot_has_permissions, command from bot.constants import OMDB_API_KEY, SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY From b26104355d3915a25bc36dda0f535f0f334711cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Tue, 15 May 2018 15:05:48 +0200 Subject: [PATCH 22/27] Added snake cards. --- bot/cogs/snakes.py | 341 +++++++++++++----- .../snake_cards/backs/card_back1.jpg | Bin 0 -> 165788 bytes .../snake_cards/backs/card_back2.jpg | Bin 0 -> 140868 bytes bot/resources/snake_cards/card_bottom.png | Bin 0 -> 18165 bytes bot/resources/snake_cards/card_frame.png | Bin 0 -> 1460 bytes bot/resources/snake_cards/card_top.png | Bin 0 -> 12581 bytes bot/resources/snake_cards/expressway.ttf | Bin 0 -> 156244 bytes 7 files changed, 257 insertions(+), 84 deletions(-) create mode 100644 bot/resources/snake_cards/backs/card_back1.jpg create mode 100644 bot/resources/snake_cards/backs/card_back2.jpg create mode 100644 bot/resources/snake_cards/card_bottom.png create mode 100644 bot/resources/snake_cards/card_frame.png create mode 100644 bot/resources/snake_cards/card_top.png create mode 100644 bot/resources/snake_cards/expressway.ttf diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 41fe8f8cd6..199ef38fa7 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,14 +1,19 @@ import asyncio import colorsys import logging +import os import random import re import string +import textwrap import urllib +from functools import partial +from io import BytesIO from typing import Any, Dict import aiohttp import async_timeout +from PIL import Image, ImageDraw, ImageFont from discord import Embed, File, Member, Message, Reaction from discord.ext.commands import AutoShardedBot, Context, bot_has_permissions, command @@ -111,6 +116,42 @@ "Are you cheating?" ] +# snake card consts +CARD = { + "top": Image.open("bot/resources/snake_cards/card_top.png"), + "frame": Image.open("bot/resources/snake_cards/card_frame.png"), + "bottom": Image.open("bot/resources/snake_cards/card_bottom.png"), + "backs": [Image.open(f"bot/resources/snake_cards/backs/{file}") for file in os.listdir("bot/resources/snake_cards/backs")], + "font": ImageFont.truetype("bot/resources/snake_cards/expressway.ttf", 20) +} + +SPECIAL_CARDS = { + "python": { + "name": "Python", + "info": "Python is a species of programming language, commonly used by coding beginners and experts alike. " + "It was first discovered in 1989 by Guido van Rossum in the Netherlands, and was released to the wild " + "two years later. Its use of dynamic typing is one of many distinct features, alongside significant " + "whitespace, heavy emphasis on readability, and, above all, absolutely pain-free software " + "distribution... *sigh*", + "image_list": [ + "https://www.python.org/static/community_logos/python-logo-master-v3-TM-flattened.png" + ] + }, + "bob ross": { + "name": "Bob Ross", + "info": "Robert Norman Ross (October 29, 1942 – July 4, 1995) was an American painter, art instructor, and " + "television host. He was the creator and host of The Joy of Painting, an instructional television " + "program that aired from 1983 to 1994 on PBS in the United States, and also aired in Canada, " + "Latin America, and Europe. Ross went from being a public-television personality in the 1980s and " + "1990s to being an Internet celebrity in the 21st century, popular with fans on " + "YouTube and many other websites.", + "image_list": [ + "https://images05.military.com/sites/default/files/styles/full/public/media/people/2013/05/" + "bobrosspainting.jpg?itok=A3G_e8MM" + ] + } +} + class Snakes: """ @@ -136,6 +177,32 @@ def __init__(self, bot: AutoShardedBot): self.names_url = f"{SITE_API_URL}/snake_names" self.idioms_url = f"{SITE_API_URL}/snake_idioms" + @staticmethod + def _snakify(message): + """ + Sssnakifffiesss a sstring. + """ + + # Replace fricatives with exaggerated snake fricatives. + simple_fricatives = [ + "f", "s", "z", "h", + "F", "S", "Z", "H", + ] + complex_fricatives = [ + "th", "sh", "Th", "Sh" + ] + + for letter in simple_fricatives: + if letter.islower(): + message = message.replace(letter, letter * random.randint(2, 4)) + else: + message = message.replace(letter, (letter * random.randint(2, 4)).title()) + + for fricative in complex_fricatives: + message = message.replace(fricative, fricative[0] + fricative[1] * random.randint(2, 4)) + + return message + async def _fetch(self, session, url, params=None): if params is None: params = {} @@ -144,7 +211,7 @@ async def _fetch(self, session, url, params=None): async with session.get(url, params=params) as response: return await response.json() - async def get_snek(self, name: str) -> Dict[str, Any]: + async def _get_snek(self, name: str) -> Dict[str, Any]: """ Goes online and fetches all the data from a wikipedia article about a snake. Builds a dict that the .get() method can use. @@ -236,84 +303,15 @@ async def get_snek(self, name: str) -> Dict[str, Any]: snake_info["image_list"] = image_list snake_info["map_list"] = map_list snake_info["thumb_list"] = thumb_list - return snake_info - - @command(name="snakes.get()", aliases=["snakes.get"]) - @bot_has_permissions(manage_messages=True) - @locked() - async def get(self, ctx: Context, name: Snake = None): - """ - Fetches information about a snake from Wikipedia. - :param ctx: Context object passed from discord.py - :param name: Optional, the name of the snake to get information for - omit for a random snake + snake_info["name"] = name - Created by Ava and eivl - """ - - with ctx.typing(): - if name is None: - name = await Snake.random() - - data = await self.get_snek(name) - - if data.get('error'): - return await ctx.send('Could not fetch data from Wikipedia.') - - match = self.wiki_brief.match(data['extract']) - description = match.group(1) if match else None - description = description.replace("\n", "\n\n") # Give us some proper paragraphs. - - # Shorten the description if needed - if len(description) > 1000: - description = description[:1000] - last_newline = description.rfind("\n") - if last_newline > 0: - description = description[:last_newline] - - # Strip and add the Wiki link. - description = description.strip("\n") - description += f"\n\nRead more on [Wikipedia]({data['fullurl']})" - - # Build and send the embed. - embed = Embed( - title=data['title'], - description=description, - colour=0x59982F, - ) - - emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' - image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) - embed.set_image(url=image) - - await ctx.send(embed=embed) - - @staticmethod - def _snakify(message): - """ - Sssnakifffiesss a sstring. - """ - - # Replace fricatives with exaggerated snake fricatives. - simple_fricatives = [ - "f", "s", "z", "h", - "F", "S", "Z", "H", - ] - complex_fricatives = [ - "th", "sh", "Th", "Sh" - ] - - for letter in simple_fricatives: - if letter.islower(): - message = message.replace(letter, letter * random.randint(2, 4)) - else: - message = message.replace(letter, (letter * random.randint(2, 4)).title()) - - for fricative in complex_fricatives: - message = message.replace(fricative, fricative[0] + fricative[1] * random.randint(2, 4)) - - return message + match = self.wiki_brief.match(snake_info['extract']) + info = match.group(1) if match else None + info = info.replace("\n", "\n\n") # Give us some proper paragraphs. + snake_info["info"] = info + return snake_info - async def get_snake_name(self) -> Dict[str, str]: + async def _get_snake_name(self) -> Dict[str, str]: """ Gets a random snake name. :return: A random snake name, as a string. @@ -324,7 +322,7 @@ async def get_snake_name(self) -> Dict[str, str]: return name_data - async def validate_answer(self, ctx: Context, message: Message, answer: str, options: list): + async def _validate_answer(self, ctx: Context, message: Message, answer: str, options: list): """ Validate the answer using a reaction event loop :return: @@ -362,6 +360,53 @@ def predicate(reaction, user): await message.clear_reactions() + @command(name="snakes.get()", aliases=["snakes.get"]) + @bot_has_permissions(manage_messages=True) + @locked() + async def get(self, ctx: Context, name: Snake = None): + """ + Fetches information about a snake from Wikipedia. + :param ctx: Context object passed from discord.py + :param name: Optional, the name of the snake to get information for - omit for a random snake + + Created by Ava and eivl + """ + + with ctx.typing(): + if name is None: + name = await Snake.random() + + data = await self._get_snek(name) + + if data.get('error'): + return await ctx.send('Could not fetch data from Wikipedia.') + + description = data["info"] + + # Shorten the description if needed + if len(description) > 1000: + description = description[:1000] + last_newline = description.rfind("\n") + if last_newline > 0: + description = description[:last_newline] + + # Strip and add the Wiki link. + description = description.strip("\n") + description += f"\n\nRead more on [Wikipedia]({data['fullurl']})" + + # Build and send the embed. + embed = Embed( + title=data['title'], + description=description, + colour=0x59982F, + ) + + emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' + image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) + embed.set_image(url=image) + + await ctx.send(embed=embed) + @command(name="snakes.name()", aliases=["snakes.name", "snakes.name_gen", "snakes.name_gen()"]) async def random_snake_name(self, ctx: Context, name: str = None): """ @@ -384,7 +429,7 @@ async def random_snake_name(self, ctx: Context, name: str = None): This was written by Iceman, and modified for inclusion into the bot by lemon. """ - snake_name = await self.get_snake_name() + snake_name = await self._get_snake_name() snake_name = snake_name['name'] snake_prefix = "" @@ -597,7 +642,7 @@ async def quiz(self, ctx: Context): ) quiz = await ctx.channel.send("", embed=embed) - await self.validate_answer(ctx, quiz, answer, options) + await self._validate_answer(ctx, quiz, answer, options) @command(name="snakes.zen()", aliases=["zen"]) async def zen(self, ctx: Context): @@ -809,7 +854,7 @@ async def video(self, ctx: Context, search: str = None): if search: query = search + ' snake' else: - snake = await self.get_snake_name() + snake = await self._get_snake_name() query = snake['name'] # Build the URL and make the request @@ -864,6 +909,9 @@ async def sal(self, ctx: Context): async def guess(self, ctx): """ Snake identifying game! + + Made by Ava and eivl for the first code jam. + Modified by lemon. """ with ctx.typing(): @@ -875,7 +923,7 @@ async def guess(self, ctx): snake = random.choice(snakes) answer = "abcd"[snakes.index(snake)] - data = await self.get_snek(snake) + data = await self._get_snek(snake) image = next((url for url in data['image_list'] if url.endswith(self.valid)), None) @@ -888,9 +936,9 @@ async def guess(self, ctx): guess = await ctx.send(embed=embed) options = {f"{'abcd'[snakes.index(snake)]}": snake for snake in snakes} - await self.validate_answer(ctx, guess, answer, options) + await self._validate_answer(ctx, guess, answer, options) - @command(name="snakes.movie()", aliases=["movie"]) + @command(name="snakes.movie()", aliases=["snakes.movie"]) async def movie(self, ctx: Context): """ Gets a random snake-related movie from OMDB. @@ -960,6 +1008,131 @@ async def movie(self, ctx: Context): embed=embed ) + @staticmethod + def generate_card(buffer: BytesIO, content: dict) -> BytesIO: + """ + Generate a card from snake information. + + Written by juan and Someone during the first code jam. + """ + + snake = Image.open(buffer) + + # Get the size of the snake icon, configure the height of the image box (yes, it changes) + icon_width = 347 # Hardcoded, not much i can do about that + icon_height = int((icon_width / snake.width) * snake.height) + frame_copies = icon_height // CARD['frame'].height + 1 + snake.thumbnail((icon_width, icon_height)) + + # Get the dimensions of the final image + main_height = icon_height + CARD['top'].height + CARD['bottom'].height + main_width = CARD['frame'].width + + # Start creating the foreground + foreground = Image.new("RGBA", (main_width, main_height), (0, 0, 0, 0)) + foreground.paste(CARD['top'], (0, 0)) + + # Generate the frame borders to the correct height + for offset in range(frame_copies): + position = (0, CARD['top'].height + offset * CARD['frame'].height) + foreground.paste(CARD['frame'], position) + + # Add the image and bottom part of the image + foreground.paste(snake, (36, CARD['top'].height)) # Also hardcoded :( + foreground.paste(CARD['bottom'], (0, CARD['top'].height + icon_height)) + + # Setup the background + back = random.choice(CARD['backs']) + back_copies = main_height // back.height + 1 + full_image = Image.new("RGBA", (main_width, main_height), (0, 0, 0, 0)) + + # Generate the tiled background + for offset in range(back_copies): + full_image.paste(back, (16, 16 + offset * back.height)) + + # Place the foreground onto the final image + full_image.paste(foreground, (0, 0), foreground) + + # Get the first two sentences of the info + description = '.'.join(content['info'].split(".")[:2]) + '.' + + # Setup positioning variables + margin = 36 + offset = CARD['top'].height + icon_height + margin + + # Create blank rectangle image which will be behind the text + rectangle = Image.new( + "RGBA", + (main_width, main_height), + (0, 0, 0, 0) + ) + + # Draw a semi-transparent rectangle on it + rect = ImageDraw.Draw(rectangle) + rect.rectangle( + (margin, offset, main_width - margin, main_height - margin), + fill=(63, 63, 63, 128) + ) + + del rect + + # Paste it onto the final image + full_image.paste(rectangle, (0, 0), mask=rectangle) + + # Draw the text onto the final image + draw = ImageDraw.Draw(full_image) + for line in textwrap.wrap(description, 36): + draw.text([margin + 4, offset], line, font=CARD['font']) + offset += CARD['font'].getsize(line)[1] + + del draw + + # Get the image contents as a BufferIO object + buffer = BytesIO() + full_image.save(buffer, 'PNG') + buffer.seek(0) + + return buffer + + @command(name="snakes.card()", aliases=["snakes.card"]) + async def snake_card(self, ctx: Context, name: str = None): + """ + Create an interesting little card from a snake! + + Created by juan and Someone during the first code jam. + """ + + # Get the snake data we need + if name and name.lower() in SPECIAL_CARDS: + content = SPECIAL_CARDS[name.lower()] + + elif not name: + name_obj = await self._get_snake_name() + name = name_obj['scientific'] + content = await self._get_snek(name) + + else: + content = await self._get_snek(name) + + # Make the card + async with ctx.typing(): + + stream = BytesIO() + async with async_timeout.timeout(10): + async with self.bot.http_session.get(content['image_list'][0]) as response: + stream.write(await response.read()) + + stream.seek(0) + + func = partial(self.generate_card, stream, content) + final_buffer = await self.bot.loop.run_in_executor(None, func) + + # Send it! + await ctx.send( + f"A wild {content['name'].title()} appears!", + file=File(final_buffer, filename=content['name'].replace(" ", "") + ".png") +) + def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/resources/snake_cards/backs/card_back1.jpg b/bot/resources/snake_cards/backs/card_back1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..22959fa737d58c7f78c0b681e67acfda34fa2bf2 GIT binary patch literal 165788 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%0AQ-YZMjRp3zQhKInVlZ~#JggN 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%0AQynwR3zY-EU^`()L(Z6G-#*htF1^10& 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

^+q+-QKi7?^H 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≦dh4BiH$#BBsb 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 literal 0 HcmV?d00001 diff --git a/bot/resources/snake_cards/backs/card_back2.jpg b/bot/resources/snake_cards/backs/card_back2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d56edc3203be7a16eb09a56dda90896478c35108 GIT binary patch literal 140868 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

K`_d?JvGbsy1=%SQ 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 MvQ$J57ymy0KSwQ8;nk$%Rj zZ!Y62IW-kEzGW3hIl_=-pCfU<@xydK|DNSmE0ea$$_nUP)mhE)!ux4evUe`wWy3k% zFN6?l3NJpG9l9aSPXnV+n81t|?Q0MAD9Js7NCC<$7k;aEXSho_B6!^QjT)Ge_@TO@ zg5+|lowa@I!oH&IBf8<6C!+$F4v&jmPk-M&%z($otigAYCBo+!cU9Z?|L*Rmk8f`j zO(JJ4bfTL-{(WL&wY5zFtH{wHK9Zd12JVx5OB>8M=sH*=$%gC}(2cwN6JrANCTpy0 zvezp-t@%sneq?&-x_Vc`-m>p#;bvVt^DPTlb+$ah69%DaujcYTs2_uNu9bx>mB)#4 z^snsFT3lRg@W&XBnUOoRn6#LRR(>J189w*6^*9!{TXM$(a*VYenML;+MDe4}H#2|q ze|j(y75YO`oEg{O`{O$E>C)rz@aeJKDwm_Yf?W9!u}WFGky1{2NJw5KwjaeyGcc&F zB7NRPr)mZ!sUx(Y0AycLwdH+JyCvt%tx)KEZHUIQhv!cuJh7gKtF`ea;CvY_E^}0H z0rSs)Sz?%)DRz+$C&&48D@t`?IK`aYCt33tT#G?mKHu-A(OUPMn!#=hlpa0^U9-Pk ziIG-T2(y-`1CP#!<1|>$`wvAv&_swsy z`;-3Nf*&ia9f4@S0h9@>4s@qNsX zib%N1Nj35QIv((NwjA*Ea35~^xDB5v8~^v`H<1PJfGheRq&HgkaQw$&oD+@@+Jpnz zNk�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 literal 0 HcmV?d00001 diff --git a/bot/resources/snake_cards/card_top.png b/bot/resources/snake_cards/card_top.png new file mode 100644 index 0000000000000000000000000000000000000000..e329c873ab907a3a0b08c33a8673e142fada4e57 GIT binary patch literal 12581 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 R{d)l*FRda~Enyn+{{Zc8PLBWp literal 0 HcmV?d00001 diff --git a/bot/resources/snake_cards/expressway.ttf b/bot/resources/snake_cards/expressway.ttf new file mode 100644 index 0000000000000000000000000000000000000000..39e15794777c78b361c5a9454634e7cab4ed7d60 GIT binary patch literal 156244 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%0A+-@j8hE& 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 PLwLG)j>QLzipTTc*L|?A literal 0 HcmV?d00001 From 2e9c3e93c28f759e3b24ea4d3b27a845530c7025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Wed, 16 May 2018 02:17:51 +0200 Subject: [PATCH 23/27] Added the snakes.about command, and cleaned up the cog. Still got a couple of bugs with snake_card, but other than that this is done. --- bot/cogs/snakes.py | 952 +++++++++++++++++++++++++-------------------- 1 file changed, 522 insertions(+), 430 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 199ef38fa7..06d3a76bc5 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -13,17 +13,18 @@ import aiohttp import async_timeout +from discord import Colour, Embed, File, Member, Message, Reaction +from discord.ext.commands import AutoShardedBot, BadArgument, Context, bot_has_permissions, command from PIL import Image, ImageDraw, ImageFont -from discord import Embed, File, Member, Message, Reaction -from discord.ext.commands import AutoShardedBot, Context, bot_has_permissions, command -from bot.constants import OMDB_API_KEY, SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY +from bot.constants import ERROR_REPLIES, OMDB_API_KEY, SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY from bot.converters import Snake from bot.decorators import locked from bot.utils.snakes import hatching, perlin, perlinsneks, sal log = logging.getLogger(__name__) +# region: Constants # Color SNAKE_COLOR = 0x399600 @@ -121,7 +122,10 @@ "top": Image.open("bot/resources/snake_cards/card_top.png"), "frame": Image.open("bot/resources/snake_cards/card_frame.png"), "bottom": Image.open("bot/resources/snake_cards/card_bottom.png"), - "backs": [Image.open(f"bot/resources/snake_cards/backs/{file}") for file in os.listdir("bot/resources/snake_cards/backs")], + "backs": [ + Image.open(f"bot/resources/snake_cards/backs/{file}") + for file in os.listdir("bot/resources/snake_cards/backs") + ], "font": ImageFont.truetype("bot/resources/snake_cards/expressway.ttf", 20) } @@ -130,9 +134,7 @@ "name": "Python", "info": "Python is a species of programming language, commonly used by coding beginners and experts alike. " "It was first discovered in 1989 by Guido van Rossum in the Netherlands, and was released to the wild " - "two years later. Its use of dynamic typing is one of many distinct features, alongside significant " - "whitespace, heavy emphasis on readability, and, above all, absolutely pain-free software " - "distribution... *sigh*", + "two years later.", "image_list": [ "https://www.python.org/static/community_logos/python-logo-master-v3-TM-flattened.png" ] @@ -142,15 +144,22 @@ "info": "Robert Norman Ross (October 29, 1942 – July 4, 1995) was an American painter, art instructor, and " "television host. He was the creator and host of The Joy of Painting, an instructional television " "program that aired from 1983 to 1994 on PBS in the United States, and also aired in Canada, " - "Latin America, and Europe. Ross went from being a public-television personality in the 1980s and " - "1990s to being an Internet celebrity in the 21st century, popular with fans on " - "YouTube and many other websites.", + "Latin America, and Europe.", "image_list": [ "https://images05.military.com/sites/default/files/styles/full/public/media/people/2013/05/" "bobrosspainting.jpg?itok=A3G_e8MM" ] + }, + "mystery snake": { + "name": "Mystery Snake", + "info": "The Mystery Snake is rumored to be a thin, serpentine creature that hides in spaghetti dinners. " + "It has yellow, pasta-like scales with a completely smooth texture, and is quite glossy. ", + "image_list": [ + "https://img.thrfun.com/img/080/349/spaghetti_dinner_l1.jpg" + ] } } +# endregion class Snakes: @@ -177,6 +186,93 @@ def __init__(self, bot: AutoShardedBot): self.names_url = f"{SITE_API_URL}/snake_names" self.idioms_url = f"{SITE_API_URL}/snake_idioms" + # region: Helper methods + @staticmethod + def generate_card(buffer: BytesIO, content: dict) -> BytesIO: + """ + Generate a card from snake information. + + Written by juan and Someone during the first code jam. + """ + + snake = Image.open(buffer) + + # Get the size of the snake icon, configure the height of the image box (yes, it changes) + icon_width = 347 # Hardcoded, not much i can do about that + icon_height = int((icon_width / snake.width) * snake.height) + frame_copies = icon_height // CARD['frame'].height + 1 + snake.thumbnail((icon_width, icon_height)) + + # Get the dimensions of the final image + main_height = icon_height + CARD['top'].height + CARD['bottom'].height + main_width = CARD['frame'].width + + # Start creating the foreground + foreground = Image.new("RGBA", (main_width, main_height), (0, 0, 0, 0)) + foreground.paste(CARD['top'], (0, 0)) + + # Generate the frame borders to the correct height + for offset in range(frame_copies): + position = (0, CARD['top'].height + offset * CARD['frame'].height) + foreground.paste(CARD['frame'], position) + + # Add the image and bottom part of the image + foreground.paste(snake, (36, CARD['top'].height)) # Also hardcoded :( + foreground.paste(CARD['bottom'], (0, CARD['top'].height + icon_height)) + + # Setup the background + back = random.choice(CARD['backs']) + back_copies = main_height // back.height + 1 + full_image = Image.new("RGBA", (main_width, main_height), (0, 0, 0, 0)) + + # Generate the tiled background + for offset in range(back_copies): + full_image.paste(back, (16, 16 + offset * back.height)) + + # Place the foreground onto the final image + full_image.paste(foreground, (0, 0), foreground) + + # Get the first two sentences of the info + description = '.'.join(content['info'].split(".")[:2]) + '.' + + # Setup positioning variables + margin = 36 + offset = CARD['top'].height + icon_height + margin + + # Create blank rectangle image which will be behind the text + rectangle = Image.new( + "RGBA", + (main_width, main_height), + (0, 0, 0, 0) + ) + + # Draw a semi-transparent rectangle on it + rect = ImageDraw.Draw(rectangle) + rect.rectangle( + (margin, offset, main_width - margin, main_height - margin), + fill=(63, 63, 63, 128) + ) + + del rect + + # Paste it onto the final image + full_image.paste(rectangle, (0, 0), mask=rectangle) + + # Draw the text onto the final image + draw = ImageDraw.Draw(full_image) + for line in textwrap.wrap(description, 36): + draw.text([margin + 4, offset], line, font=CARD['font']) + offset += CARD['font'].getsize(line)[1] + + del draw + + # Get the image contents as a BufferIO object + buffer = BytesIO() + full_image.save(buffer, 'PNG') + buffer.seek(0) + + return buffer + @staticmethod def _snakify(message): """ @@ -204,6 +300,10 @@ def _snakify(message): return message async def _fetch(self, session, url, params=None): + """ + Asyncronous web request helper method. + """ + if params is None: params = {} @@ -216,7 +316,7 @@ async def _get_snek(self, name: str) -> Dict[str, Any]: Goes online and fetches all the data from a wikipedia article about a snake. Builds a dict that the .get() method can use. - Created by Ava and eivl for the very first code jam on PythonDiscord. + Created by Ava and eivl. :param name: The name of the snake to get information for - omit for a random snake :return: A dict containing information on a snake @@ -242,6 +342,8 @@ async def _get_snek(self, name: str) -> Dict[str, Any]: except KeyError: # Wikipedia error page ID(?) pageid = 41118 + except IndexError: + return None params = { 'format': 'json', @@ -307,8 +409,12 @@ async def _get_snek(self, name: str) -> Dict[str, Any]: match = self.wiki_brief.match(snake_info['extract']) info = match.group(1) if match else None - info = info.replace("\n", "\n\n") # Give us some proper paragraphs. + + if info: + info = info.replace("\n", "\n\n") # Give us some proper paragraphs. + snake_info["info"] = info + return snake_info async def _get_snake_name(self) -> Dict[str, str]: @@ -352,131 +458,14 @@ def predicate(reaction, user): if str(reaction.emoji) == ANSWERS_EMOJI[answer]: await ctx.send(f"{random.choice(CORRECT_GUESS)} The correct answer was **{options[answer]}**.") else: - wrong_answer = ANSWERS_EMOJI_REVERSE[str(reaction.emoji)] await ctx.send( - f"{random.choice(INCORRECT_GUESS)} **{wrong_answer}** is incorrect. " - f"The correct answer was **{options[answer].lower()}**." + f"{random.choice(INCORRECT_GUESS)} The correct answer was **{options[answer]}**." ) await message.clear_reactions() + # endregion - @command(name="snakes.get()", aliases=["snakes.get"]) - @bot_has_permissions(manage_messages=True) - @locked() - async def get(self, ctx: Context, name: Snake = None): - """ - Fetches information about a snake from Wikipedia. - :param ctx: Context object passed from discord.py - :param name: Optional, the name of the snake to get information for - omit for a random snake - - Created by Ava and eivl - """ - - with ctx.typing(): - if name is None: - name = await Snake.random() - - data = await self._get_snek(name) - - if data.get('error'): - return await ctx.send('Could not fetch data from Wikipedia.') - - description = data["info"] - - # Shorten the description if needed - if len(description) > 1000: - description = description[:1000] - last_newline = description.rfind("\n") - if last_newline > 0: - description = description[:last_newline] - - # Strip and add the Wiki link. - description = description.strip("\n") - description += f"\n\nRead more on [Wikipedia]({data['fullurl']})" - - # Build and send the embed. - embed = Embed( - title=data['title'], - description=description, - colour=0x59982F, - ) - - emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' - image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) - embed.set_image(url=image) - - await ctx.send(embed=embed) - - @command(name="snakes.name()", aliases=["snakes.name", "snakes.name_gen", "snakes.name_gen()"]) - async def random_snake_name(self, ctx: Context, name: str = None): - """ - Slices the users name at the last vowel (or second last if the name - ends with a vowel), and then combines it with a random snake name, - which is sliced at the first vowel (or second if the name starts with - a vowel). - - If the name contains no vowels, it just appends the snakename - to the end of the name. - - Examples: - lemon + anaconda = lemoconda - krzsn + anaconda = krzsnconda - gdude + anaconda = gduconda - aperture + anaconda = apertuconda - lucy + python = luthon - joseph + taipan = joseipan - - This was written by Iceman, and modified for inclusion into the bot by lemon. - """ - - snake_name = await self._get_snake_name() - snake_name = snake_name['name'] - snake_prefix = "" - - # Set aside every word in the snake name except the last. - if " " in snake_name: - snake_prefix = " ".join(snake_name.split()[:-1]) - snake_name = snake_name.split()[-1] - - # If no name is provided, use whoever called the command. - if name: - user_name = name - else: - user_name = ctx.author.display_name - - # Get the index of the vowel to slice the username at - user_slice_index = len(user_name) - for index, char in enumerate(reversed(user_name)): - if index == 0: - continue - if char.lower() in "aeiouy": - user_slice_index -= index - break - - # Now, get the index of the vowel to slice the snake_name at - snake_slice_index = 0 - for index, char in enumerate(snake_name): - if index == 0: - continue - if char.lower() in "aeiouy": - snake_slice_index = index + 1 - break - - # Combine! - snake_name = snake_name[snake_slice_index:] - user_name = user_name[:user_slice_index] - result = f"{snake_prefix} {user_name}{snake_name}" - result = string.capwords(result) - - # Embed and send - embed = Embed( - title="Snake name", - description=f"Your snake-name is **{result}**", - color=SNAKE_COLOR - ) - - return await ctx.send(embed=embed) - + # region: Commands @bot_has_permissions(manage_messages=True) @command(name="snakes.antidote()", aliases=["snakes.antidote"]) async def antidote(self, ctx: Context): @@ -492,7 +481,7 @@ async def antidote(self, ctx: Context): Info: The game automatically ends after 5 minutes inactivity. You should only use each ingredient once. - This game was created by Bisk and Runew0lf for the first PythonDiscord codejam. + This game was created by Lord Bisk and Runew0lf. """ def event_check(reaction_: Reaction, user_: Member): @@ -617,163 +606,33 @@ def event_check(reaction_: Reaction, user_: Member): log.debug("Ending pagination and removing all reactions...") await board_id.clear_reactions() - @command(name="snakes.quiz()", aliases=["snakes.quiz"]) - async def quiz(self, ctx: Context): + @command(name="snakes.draw()", aliases=["snakes.draw"]) + async def draw(self, ctx: Context): """ - Asks a snake-related question in the chat and validates the user's guess. + Draws a random snek using Perlin noise - This was created by Mushy and Cardium for the code jam, - and modified by lemon for inclusion in this bot. + Written by Momo and kel. + Modified by juan and lemon. """ - # Prepare a question. - response = await self.bot.http_session.get(self.quiz_url, headers=self.headers) - question = await response.json() - answer = question["answerkey"] - options = {key: question[key] for key in ANSWERS_EMOJI.keys()} + def beautiful_pastel(hue): + """ + Returns random bright pastels. + """ - # Build and send the embed. - embed = Embed( - color=SNAKE_COLOR, - title=question["question"], - description="\n".join( - [f"**{key.upper()}**: {answer}" for key, answer in options.items()] - ) - ) + light = random.uniform(0.7, 0.85) + saturation = 1 - quiz = await ctx.channel.send("", embed=embed) - await self._validate_answer(ctx, quiz, answer, options) + rgb = colorsys.hls_to_rgb(hue, light, saturation) + hex_rgb = "" - @command(name="snakes.zen()", aliases=["zen"]) - async def zen(self, ctx: Context): - """ - Gets a random quote from the Zen of Python. + for part in rgb: + value = int(part * 0xFF) + hex_rgb += f"{value:02x}" - Written by Prithaj and Andrew during the very first code jam. - Modified by lemon for inclusion in the bot. - """ + return int(hex_rgb, 16) - embed = Embed( - title="Zzzen of Pythhon", - color=SNAKE_COLOR - ) - - # Get the zen quote and snakify it - zen_quote = random.choice(ZEN.splitlines()) - zen_quote = self._snakify(zen_quote) - - # Embed and send - embed.description = zen_quote - await ctx.channel.send( - embed=embed - ) - - @command(name="snakes.snakify()", aliases=["snakes.snakify"]) - async def snakify(self, ctx: Context, message: str = None): - """ - How would I talk if I were a snake? - :param ctx: context - :param message: If this is passed, it will snakify the message. - If not, it will snakify a random message from - the users history. - """ - - def predicate(message): - """ - Check if the message was sent by the author. - """ - return message.author == ctx.message.author - - def get_random_long_message(messages, retries=10): - """ - Fetch a message that's at least 3 words long, - but only if it is possible to do so in retries - attempts. Else, just return whatever the last - message is. - """ - long_message = random.choice(messages) - if len(long_message.split()) < 3 or retries <= 0: - return get_random_long_message(messages, retries - 1) - return long_message - - with ctx.typing(): - embed = Embed() - user = ctx.message.author - - if not message: - - # Get a random message from the users history - messages = [] - async for message in ctx.channel.history(limit=500).filter(predicate): - messages.append(message.content) - - message = get_random_long_message(messages) - - # Set the avatar - if user.avatar is not None: - avatar = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}" - else: - avatar = ( - "https://img00.deviantart.net/eee3/i/2017/168/3/4/" - "discord__app__avatar_rev1_by_nodeviantarthere-dbd2tp9.png" - ) - - # Build and send the embed - embed.set_author( - name=f"{user.name}#{user.discriminator}", - icon_url=avatar, - ) - embed.description = f"*{self._snakify(message)}*" - - await ctx.channel.send(embed=embed) - - @command(name="snakes.fact()", aliases=["snakes.fact"]) - async def snake_fact(self, ctx: Context): - """ - Gets a snake-related fact - - This was created by Prithaj and Andrew for code jam 1, - and modified by lemon for inclusion in this bot. - """ - - # Get a fact from the API. - response = await self.bot.http_session.get(self.facts_url, headers=self.headers) - question = await response.json() - - # Build and send the embed. - embed = Embed( - title="Snake fact", - color=SNAKE_COLOR, - description=question - ) - await ctx.channel.send(embed=embed) - - @command(name="snakes.draw()", aliases=["snakes.draw"]) - async def draw(self, ctx: Context): - """ - Draws a random snek using Perlin noise - - Made by Momo and kel during the first code jam. - """ - - def beautiful_pastel(hue): - """ - Returns random bright pastels. - """ - - light = random.uniform(0.7, 0.85) - saturation = 1 - - rgb = colorsys.hls_to_rgb(hue, light, saturation) - hex_rgb = "" - - for part in rgb: - value = int(part * 0xFF) - hex_rgb += f"{value:02x}" - - return int(hex_rgb, 16) - - with ctx.typing(): + with ctx.typing(): # Generate random snake attributes width = random.randint(6, 10) @@ -808,101 +667,52 @@ def beautiful_pastel(hue): await ctx.send(file=file) - @command(name="snakes.hatch()", aliases=["snakes.hatch", "hatch"]) - async def hatch(self, ctx: Context): + @command(name="snakes.get()", aliases=["snakes.get"]) + @bot_has_permissions(manage_messages=True) + @locked() + async def get(self, ctx: Context, name: Snake = None): """ - Hatches your personal snake + Fetches information about a snake from Wikipedia. + :param ctx: Context object passed from discord.py + :param name: Optional, the name of the snake to get information for - omit for a random snake - Made by Momo and kel during the first code jam. + Created by Ava and eivl. """ - # Pick a random snake to hatch. - snake_name = random.choice(list(hatching.snakes.keys())) - snake_image = hatching.snakes[snake_name] - - # Hatch the snake - message = await ctx.channel.send(embed=Embed(description="Hatching your snake :snake:...")) - await asyncio.sleep(1) - - for stage in hatching.stages: - hatch_embed = Embed(description=stage) - await message.edit(embed=hatch_embed) - await asyncio.sleep(1) - await asyncio.sleep(1) - await message.delete() - - # Build and send the embed. - my_snake_embed = Embed(description=":tada: Congrats! You hatched: **{0}**".format(snake_name)) - my_snake_embed.set_thumbnail(url=snake_image) - my_snake_embed.set_footer( - text=" Owner: {0}#{1}".format(ctx.message.author.name, ctx.message.author.discriminator) - ) + with ctx.typing(): + if name is None: + name = await Snake.random() - await ctx.channel.send(embed=my_snake_embed) + data = await self._get_snek(name) - @command(name="snakes.video()", aliases=["snakes.video", "snakes.get_video()", "snakes.get_video"]) - async def video(self, ctx: Context, search: str = None): - """ - Gets a YouTube video about snakes - :param name: Optional, a name of a snake. Used to search for videos with that name - :param ctx: Context object passed from discord.py + if data.get('error'): + return await ctx.send('Could not fetch data from Wikipedia.') - Created by Andrew and Prithaj for the first code jam. - """ + description = data["info"] - # Are we searching for anything specific? - if search: - query = search + ' snake' - else: - snake = await self._get_snake_name() - query = snake['name'] + # Shorten the description if needed + if len(description) > 1000: + description = description[:1000] + last_newline = description.rfind("\n") + if last_newline > 0: + description = description[:last_newline] - # Build the URL and make the request - url = f'https://www.googleapis.com/youtube/v3/search' - response = await self.bot.http_session.get( - url, - params={ - "part": "snippet", - "q": urllib.parse.quote(query), - "type": "video", - "key": YOUTUBE_API_KEY - } - ) - response = await response.json() - data = response['items'] + # Strip and add the Wiki link. + description = description.strip("\n") + description += f"\n\nRead more on [Wikipedia]({data['fullurl']})" - # Send the user a video - if len(data) > 0: - num = random.randint(0, len(data) - 1) - youtube_base_url = 'https://www.youtube.com/watch?v=' - await ctx.channel.send( - content=f"{youtube_base_url}{data[num]['id']['videoId']}" + # Build and send the embed. + embed = Embed( + title=data['title'], + description=description, + colour=0x59982F, ) - else: - log.warning(f"CRITICAL ERROR: YouTube API returned {response}") - - @command(name="snakes.sal()", aliases=["snakes.sal"]) - async def sal(self, ctx: Context): - """ - Command group for Snakes and Ladders - - Create a S&L game: sal create - - Join a S&L game: sal join - - Leave a S&L game: sal leave - - Cancel a S&L game (author): sal cancel - - Start a S&L game (author): sal start - - Roll the dice: sal roll OR roll - """ - - # CREATE # - # check if there is already a game in this channel - if ctx.channel in self.active_sal: - await ctx.send(f"{ctx.author.mention} A game is already in progress in this channel.") - return - game = sal.SnakeAndLaddersGame(snakes=self, context=ctx) - self.active_sal[ctx.channel] = game + emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' + image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) + embed.set_image(url=image) - await game.open_game() + await ctx.send(embed=embed) @command(name="snakes.guess()", aliases=["snakes.guess", "identify"]) @locked() @@ -910,7 +720,7 @@ async def guess(self, ctx): """ Snake identifying game! - Made by Ava and eivl for the first code jam. + Made by Ava and eivl. Modified by lemon. """ @@ -938,13 +748,45 @@ async def guess(self, ctx): options = {f"{'abcd'[snakes.index(snake)]}": snake for snake in snakes} await self._validate_answer(ctx, guess, answer, options) + @command(name="snakes.hatch()", aliases=["snakes.hatch", "hatch"]) + async def hatch(self, ctx: Context): + """ + Hatches your personal snake + + Written by Momo and kel. + """ + + # Pick a random snake to hatch. + snake_name = random.choice(list(hatching.snakes.keys())) + snake_image = hatching.snakes[snake_name] + + # Hatch the snake + message = await ctx.channel.send(embed=Embed(description="Hatching your snake :snake:...")) + await asyncio.sleep(1) + + for stage in hatching.stages: + hatch_embed = Embed(description=stage) + await message.edit(embed=hatch_embed) + await asyncio.sleep(1) + await asyncio.sleep(1) + await message.delete() + + # Build and send the embed. + my_snake_embed = Embed(description=":tada: Congrats! You hatched: **{0}**".format(snake_name)) + my_snake_embed.set_thumbnail(url=snake_image) + my_snake_embed.set_footer( + text=" Owner: {0}#{1}".format(ctx.message.author.name, ctx.message.author.discriminator) + ) + + await ctx.channel.send(embed=my_snake_embed) + @command(name="snakes.movie()", aliases=["snakes.movie"]) async def movie(self, ctx: Context): """ Gets a random snake-related movie from OMDB. - Written by Samuel and Fat & Proud during the very first code jam. - Modified by gdude for inclusion in the bot. + Written by Samuel. + Modified by gdude. """ url = "http://www.omdbapi.com/" @@ -1008,91 +850,169 @@ async def movie(self, ctx: Context): embed=embed ) - @staticmethod - def generate_card(buffer: BytesIO, content: dict) -> BytesIO: + @command(name="snakes.quiz()", aliases=["snakes.quiz"]) + async def quiz(self, ctx: Context): """ - Generate a card from snake information. + Asks a snake-related question in the chat and validates the user's guess. - Written by juan and Someone during the first code jam. + This was created by Mushy and Cardium, + and modified by Urthas and lemon. """ - snake = Image.open(buffer) - - # Get the size of the snake icon, configure the height of the image box (yes, it changes) - icon_width = 347 # Hardcoded, not much i can do about that - icon_height = int((icon_width / snake.width) * snake.height) - frame_copies = icon_height // CARD['frame'].height + 1 - snake.thumbnail((icon_width, icon_height)) + # Prepare a question. + response = await self.bot.http_session.get(self.quiz_url, headers=self.headers) + question = await response.json() + answer = question["answerkey"] + options = {key: question["options"][key] for key in ANSWERS_EMOJI.keys()} - # Get the dimensions of the final image - main_height = icon_height + CARD['top'].height + CARD['bottom'].height - main_width = CARD['frame'].width + # Build and send the embed. + embed = Embed( + color=SNAKE_COLOR, + title=question["question"], + description="\n".join( + [f"**{key.upper()}**: {answer}" for key, answer in options.items()] + ) + ) - # Start creating the foreground - foreground = Image.new("RGBA", (main_width, main_height), (0, 0, 0, 0)) - foreground.paste(CARD['top'], (0, 0)) + quiz = await ctx.channel.send("", embed=embed) + await self._validate_answer(ctx, quiz, answer, options) - # Generate the frame borders to the correct height - for offset in range(frame_copies): - position = (0, CARD['top'].height + offset * CARD['frame'].height) - foreground.paste(CARD['frame'], position) + @command(name="snakes.name()", aliases=["snakes.name", "snakes.name_gen", "snakes.name_gen()"]) + async def random_snake_name(self, ctx: Context, name: str = None): + """ + Slices the users name at the last vowel (or second last if the name + ends with a vowel), and then combines it with a random snake name, + which is sliced at the first vowel (or second if the name starts with + a vowel). - # Add the image and bottom part of the image - foreground.paste(snake, (36, CARD['top'].height)) # Also hardcoded :( - foreground.paste(CARD['bottom'], (0, CARD['top'].height + icon_height)) + If the name contains no vowels, it just appends the snakename + to the end of the name. - # Setup the background - back = random.choice(CARD['backs']) - back_copies = main_height // back.height + 1 - full_image = Image.new("RGBA", (main_width, main_height), (0, 0, 0, 0)) + Examples: + lemon + anaconda = lemoconda + krzsn + anaconda = krzsnconda + gdude + anaconda = gduconda + aperture + anaconda = apertuconda + lucy + python = luthon + joseph + taipan = joseipan - # Generate the tiled background - for offset in range(back_copies): - full_image.paste(back, (16, 16 + offset * back.height)) + This was written by Iceman, and modified for inclusion into the bot by lemon. + """ - # Place the foreground onto the final image - full_image.paste(foreground, (0, 0), foreground) + snake_name = await self._get_snake_name() + snake_name = snake_name['name'] + snake_prefix = "" - # Get the first two sentences of the info - description = '.'.join(content['info'].split(".")[:2]) + '.' + # Set aside every word in the snake name except the last. + if " " in snake_name: + snake_prefix = " ".join(snake_name.split()[:-1]) + snake_name = snake_name.split()[-1] - # Setup positioning variables - margin = 36 - offset = CARD['top'].height + icon_height + margin + # If no name is provided, use whoever called the command. + if name: + user_name = name + else: + user_name = ctx.author.display_name - # Create blank rectangle image which will be behind the text - rectangle = Image.new( - "RGBA", - (main_width, main_height), - (0, 0, 0, 0) - ) + # Get the index of the vowel to slice the username at + user_slice_index = len(user_name) + for index, char in enumerate(reversed(user_name)): + if index == 0: + continue + if char.lower() in "aeiouy": + user_slice_index -= index + break - # Draw a semi-transparent rectangle on it - rect = ImageDraw.Draw(rectangle) - rect.rectangle( - (margin, offset, main_width - margin, main_height - margin), - fill=(63, 63, 63, 128) + # Now, get the index of the vowel to slice the snake_name at + snake_slice_index = 0 + for index, char in enumerate(snake_name): + if index == 0: + continue + if char.lower() in "aeiouy": + snake_slice_index = index + 1 + break + + # Combine! + snake_name = snake_name[snake_slice_index:] + user_name = user_name[:user_slice_index] + result = f"{snake_prefix} {user_name}{snake_name}" + result = string.capwords(result) + + # Embed and send + embed = Embed( + title="Snake name", + description=f"Your snake-name is **{result}**", + color=SNAKE_COLOR ) - del rect + return await ctx.send(embed=embed) - # Paste it onto the final image - full_image.paste(rectangle, (0, 0), mask=rectangle) + @command(name="snakes.sal()", aliases=["snakes.sal"]) + async def sal(self, ctx: Context): + """ + Play a game of Snakes and Ladders! - # Draw the text onto the final image - draw = ImageDraw.Draw(full_image) - for line in textwrap.wrap(description, 36): - draw.text([margin + 4, offset], line, font=CARD['font']) - offset += CARD['font'].getsize(line)[1] + Written by Momo and kel. + Modified by lemon. + """ - del draw + # CREATE # + # check if there is already a game in this channel + if ctx.channel in self.active_sal: + await ctx.send(f"{ctx.author.mention} A game is already in progress in this channel.") + return - # Get the image contents as a BufferIO object - buffer = BytesIO() - full_image.save(buffer, 'PNG') - buffer.seek(0) + game = sal.SnakeAndLaddersGame(snakes=self, context=ctx) + self.active_sal[ctx.channel] = game - return buffer + await game.open_game() + + @command(name="snakes.about()", aliases=["snakes.about"]) + async def snake_about(self, ctx: Context): + """ + A command that shows an embed with information about the event, + it's participants, and its winners. + """ + + contributors = [ + "<@!245270749919576066>", + "<@!396290259907903491>", + "<@!172395097705414656>", + "<@!361708843425726474>", + "<@!300302216663793665>", + "<@!210248051430916096>", + "<@!174588005745557505>", + "<@!87793066227822592>", + "<@!211619754039967744>", + "<@!97347867923976192>", + "<@!136081839474343936>", + "<@!263560579770220554>", + "<@!104749643715387392>", + "<@!303940835005825024>", + ] + + embed = Embed( + title="About the snake cog", + description=( + "The features in this cog were created by members of the community " + "during our first ever [code jam event](https://github.com/discord-python/code-jam-1). \n\n" + "The event saw over 50 participants, who competed to write a discord bot cog with a snake theme over " + "48 hours. The staff then selected the best features from all the best teams, and made modifications " + "to ensure they would all work together before integrating them into the community bot.\n\n" + "It was a tight race, but in the end, <@!104749643715387392> and <@!303940835005825024> " + "walked away as grand champions. Make sure you check out `bot.snakes.sal()`, `bot.snakes.draw()` " + "and `bot.snakes.hatch()` to see what they came up with." + ) + ) + + embed.add_field( + name="Contributors", + value=( + ", ".join(contributors) + ) + ) + + await ctx.channel.send(embed=embed) @command(name="snakes.card()", aliases=["snakes.card"]) async def snake_card(self, ctx: Context, name: str = None): @@ -1114,6 +1034,9 @@ async def snake_card(self, ctx: Context, name: str = None): else: content = await self._get_snek(name) + if not content or not len(content['image_list']): + content = SPECIAL_CARDS['mystery snake'] + # Make the card async with ctx.typing(): @@ -1131,7 +1054,176 @@ async def snake_card(self, ctx: Context, name: str = None): await ctx.send( f"A wild {content['name'].title()} appears!", file=File(final_buffer, filename=content['name'].replace(" ", "") + ".png") -) + ) + + @command(name="snakes.fact()", aliases=["snakes.fact"]) + async def snake_fact(self, ctx: Context): + """ + Gets a snake-related fact + + Written by Andrew and Prithaj. + Modified by lemon. + """ + + # Get a fact from the API. + response = await self.bot.http_session.get(self.facts_url, headers=self.headers) + question = await response.json() + + # Build and send the embed. + embed = Embed( + title="Snake fact", + color=SNAKE_COLOR, + description=question + ) + await ctx.channel.send(embed=embed) + + @command(name="snakes()", aliases=["snakes"]) + async def snake_help(self, ctx: Context): + """ + This just invokes the help command on this cog. + """ + + log.debug(f"{ctx.author} requested info about the snakes cog") + return await ctx.invoke(self.bot.get_command("help"), "Snakes") + + @command(name="snakes.snakify()", aliases=["snakes.snakify"]) + async def snakify(self, ctx: Context, message: str = None): + """ + How would I talk if I were a snake? + :param ctx: context + :param message: If this is passed, it will snakify the message. + If not, it will snakify a random message from + the users history. + + Written by Momo and kel. + Modified by lemon. + """ + + def predicate(message): + """ + Check if the message was sent by the author. + """ + return message.author == ctx.message.author + + def get_random_long_message(messages, retries=10): + """ + Fetch a message that's at least 3 words long, + but only if it is possible to do so in retries + attempts. Else, just return whatever the last + message is. + """ + long_message = random.choice(messages) + if len(long_message.split()) < 3 or retries <= 0: + return get_random_long_message(messages, retries - 1) + return long_message + + with ctx.typing(): + embed = Embed() + user = ctx.message.author + + if not message: + + # Get a random message from the users history + messages = [] + async for message in ctx.channel.history(limit=500).filter(predicate): + messages.append(message.content) + + message = get_random_long_message(messages) + + # Set the avatar + if user.avatar is not None: + avatar = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}" + else: + avatar = ( + "https://img00.deviantart.net/eee3/i/2017/168/3/4/" + "discord__app__avatar_rev1_by_nodeviantarthere-dbd2tp9.png" + ) + + # Build and send the embed + embed.set_author( + name=f"{user.name}#{user.discriminator}", + icon_url=avatar, + ) + embed.description = f"*{self._snakify(message)}*" + + await ctx.channel.send(embed=embed) + + @command(name="snakes.video()", aliases=["snakes.video", "snakes.get_video()", "snakes.get_video"]) + async def video(self, ctx: Context, search: str = None): + """ + Gets a YouTube video about snakes + :param name: Optional, a name of a snake. Used to search for videos with that name + :param ctx: Context object passed from discord.py + + Written by Andrew and Prithaj. + """ + + # Are we searching for anything specific? + if search: + query = search + ' snake' + else: + snake = await self._get_snake_name() + query = snake['name'] + + # Build the URL and make the request + url = f'https://www.googleapis.com/youtube/v3/search' + response = await self.bot.http_session.get( + url, + params={ + "part": "snippet", + "q": urllib.parse.quote(query), + "type": "video", + "key": YOUTUBE_API_KEY + } + ) + response = await response.json() + data = response['items'] + + # Send the user a video + if len(data) > 0: + num = random.randint(0, len(data) - 1) + youtube_base_url = 'https://www.youtube.com/watch?v=' + await ctx.channel.send( + content=f"{youtube_base_url}{data[num]['id']['videoId']}" + ) + else: + log.warning(f"CRITICAL ERROR: YouTube API returned {response}") + + @command(name="snakes.zen()", aliases=["zen"]) + async def zen(self, ctx: Context): + """ + Gets a random quote from the Zen of Python. + + Written by Prithaj and Andrew. + Modified by lemon. + """ + + embed = Embed( + title="Zzzen of Pythhon", + color=SNAKE_COLOR + ) + + # Get the zen quote and snakify it + zen_quote = random.choice(ZEN.splitlines()) + zen_quote = self._snakify(zen_quote) + + # Embed and send + embed.description = zen_quote + await ctx.channel.send( + embed=embed + ) + # endregion + + @get.error + async def command_error(self, ctx, error): + if isinstance(error, BadArgument): + embed = Embed() + embed.colour = Colour.red() + embed.description = str(error) + embed.title = random.choice(ERROR_REPLIES) + await ctx.send(embed=embed) + else: + log.error(f"Unhandled tag command error: {error} ({error.original})") def setup(bot): From d784ca04219292fc9b2e773d3a2870b7f499fb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Fri, 18 May 2018 19:20:02 +0200 Subject: [PATCH 24/27] Some fixes for the snake cards. Cards now use the converter on the snake input, so it can disambiguate just like .get. Also made the special cases like bob ross available to both .get and .card --- bot/cogs/snakes.py | 74 ++++++++++++++++++---------------------------- bot/converters.py | 51 ++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 06d3a76bc5..8c397e8c1f 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -128,37 +128,6 @@ ], "font": ImageFont.truetype("bot/resources/snake_cards/expressway.ttf", 20) } - -SPECIAL_CARDS = { - "python": { - "name": "Python", - "info": "Python is a species of programming language, commonly used by coding beginners and experts alike. " - "It was first discovered in 1989 by Guido van Rossum in the Netherlands, and was released to the wild " - "two years later.", - "image_list": [ - "https://www.python.org/static/community_logos/python-logo-master-v3-TM-flattened.png" - ] - }, - "bob ross": { - "name": "Bob Ross", - "info": "Robert Norman Ross (October 29, 1942 – July 4, 1995) was an American painter, art instructor, and " - "television host. He was the creator and host of The Joy of Painting, an instructional television " - "program that aired from 1983 to 1994 on PBS in the United States, and also aired in Canada, " - "Latin America, and Europe.", - "image_list": [ - "https://images05.military.com/sites/default/files/styles/full/public/media/people/2013/05/" - "bobrosspainting.jpg?itok=A3G_e8MM" - ] - }, - "mystery snake": { - "name": "Mystery Snake", - "info": "The Mystery Snake is rumored to be a thin, serpentine creature that hides in spaghetti dinners. " - "It has yellow, pasta-like scales with a completely smooth texture, and is quite glossy. ", - "image_list": [ - "https://img.thrfun.com/img/080/349/spaghetti_dinner_l1.jpg" - ] - } -} # endregion @@ -683,7 +652,10 @@ async def get(self, ctx: Context, name: Snake = None): if name is None: name = await Snake.random() - data = await self._get_snek(name) + if isinstance(name, dict): + data = name + else: + data = await self._get_snek(name) if data.get('error'): return await ctx.send('Could not fetch data from Wikipedia.') @@ -698,17 +670,19 @@ async def get(self, ctx: Context, name: Snake = None): description = description[:last_newline] # Strip and add the Wiki link. - description = description.strip("\n") - description += f"\n\nRead more on [Wikipedia]({data['fullurl']})" + if "fullurl" in data: + description = description.strip("\n") + description += f"\n\nRead more on [Wikipedia]({data['fullurl']})" # Build and send the embed. embed = Embed( - title=data['title'], + title=data.get("title", data.get('name')), description=description, colour=0x59982F, ) emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' + print(next((url for url in data['image_list']))) image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) embed.set_image(url=image) @@ -1015,7 +989,7 @@ async def snake_about(self, ctx: Context): await ctx.channel.send(embed=embed) @command(name="snakes.card()", aliases=["snakes.card"]) - async def snake_card(self, ctx: Context, name: str = None): + async def snake_card(self, ctx: Context, name: Snake = None): """ Create an interesting little card from a snake! @@ -1023,20 +997,17 @@ async def snake_card(self, ctx: Context, name: str = None): """ # Get the snake data we need - if name and name.lower() in SPECIAL_CARDS: - content = SPECIAL_CARDS[name.lower()] - - elif not name: + if not name: name_obj = await self._get_snake_name() name = name_obj['scientific'] content = await self._get_snek(name) + elif isinstance(name, dict): + content = name + else: content = await self._get_snek(name) - if not content or not len(content['image_list']): - content = SPECIAL_CARDS['mystery snake'] - # Make the card async with ctx.typing(): @@ -1214,16 +1185,27 @@ async def zen(self, ctx: Context): ) # endregion + @snake_card.error @get.error async def command_error(self, ctx, error): + + embed = Embed() + embed.colour = Colour.red() + if isinstance(error, BadArgument): - embed = Embed() - embed.colour = Colour.red() embed.description = str(error) embed.title = random.choice(ERROR_REPLIES) - await ctx.send(embed=embed) + + elif isinstance(error, OSError): + log.error(f"snake_card encountered an OSError: {error} ({error.original})") + embed.description = "Could not generate the snake card! Please try again." + embed.title = random.choice(ERROR_REPLIES) + else: log.error(f"Unhandled tag command error: {error} ({error.original})") + return + + await ctx.send(embed=embed) def setup(bot): diff --git a/bot/converters.py b/bot/converters.py index c1afeabbeb..4186ec320c 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -10,10 +10,12 @@ from bot.utils import disambiguate NAMES_URL = f"{SITE_API_URL}/snake_names" +SPECIAL_URL = f"{SITE_API_URL}/special_snakes" class Snake(Converter): snakes = None + special_cases = None async def convert(self, ctx, name): await self.build_list() @@ -38,6 +40,10 @@ def get_potential(iterable, *, threshold=80): return potential + # Handle special cases + if name.lower() in self.special_cases: + return self.special_cases.get(name.lower(), name.lower()) + names = {snake['name']: snake['scientific'] for snake in self.snakes} all_names = names.keys() | names.values() timeout = len(all_names) * (3 / 4) @@ -50,30 +56,45 @@ def get_potential(iterable, *, threshold=80): @classmethod async def build_list(cls): - if cls.snakes is None: - if DEBUG_MODE: - http_session = ClientSession( - connector=TCPConnector( - resolver=AsyncResolver(), - family=socket.AF_INET, - verify_ssl=False, - ) + + headers = {"X-API-KEY": SITE_API_KEY} + + # Set up the session + if DEBUG_MODE: + http_session = ClientSession( + connector=TCPConnector( + resolver=AsyncResolver(), + family=socket.AF_INET, + verify_ssl=False, ) - else: - http_session = ClientSession( - connector=TCPConnector( - resolver=AsyncResolver() - ) + ) + else: + http_session = ClientSession( + connector=TCPConnector( + resolver=AsyncResolver() ) + ) - headers = {"X-API-KEY": SITE_API_KEY} + # Get all the snakes + if cls.snakes is None: response = await http_session.get( NAMES_URL, params={"get_all": "true"}, headers=headers ) cls.snakes = await response.json() - http_session.close() + + # Get the special cases + if cls.special_cases is None: + response = await http_session.get( + SPECIAL_URL, + headers=headers + ) + special_cases = await response.json() + cls.special_cases = {snake['name'].lower(): snake for snake in special_cases} + + # Close the session + http_session.close() @classmethod async def random(cls): From 1f19b2886232ebf4e877abf2b01b956fb6b22487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Fri, 18 May 2018 19:40:55 +0200 Subject: [PATCH 25/27] Some fixes to address Volcyy's review. --- bot/__init__.py | 2 +- bot/cogs/snakes.py | 23 +++++++++-------------- bot/decorators.py | 1 + bot/utils/__init__.py | 4 ++++ bot/utils/snakes/perlin.py | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/bot/__init__.py b/bot/__init__.py index aef96f9a56..afc16e37f7 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -243,7 +243,7 @@ def parse_python(buffer_pos): self.index += pos # If the command looks like a python syntax command, try to parse it. - if current and current == "(" or current == "[": + if current == "(" or current == "[": try: result = parse_python(pos) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 8c397e8c1f..3a5202c1d8 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -40,13 +40,13 @@ HOLE_EMOJI = "\u2B1C" # :white_square: - Used in guesses EMPTY_UNICODE = "\u200b" # literally just an empty space -ANTIDOTE_EMOJI = [ +ANTIDOTE_EMOJI = ( SYRINGE_EMOJI, PILL_EMOJI, HOURGLASS_EMOJI, CROSSBONES_EMOJI, ALEMBIC_EMOJI, -] +) # Quiz constants ANSWERS_EMOJI = { @@ -91,7 +91,7 @@ URL = "https://en.wikipedia.org/w/api.php?" # snake guess responses -INCORRECT_GUESS = [ +INCORRECT_GUESS = ( "Nope, that's not what it is.", "Not quite.", "Not even close.", @@ -103,9 +103,9 @@ "Bet you feel stupid now.", "Hahahaha, no.", "Did you hit the wrong key?" -] +) -CORRECT_GUESS = [ +CORRECT_GUESS = ( "**WRONG**. Wait, no, actually you're right.", "Yeah, you got it!", "Yep, that's exactly what it is.", @@ -115,7 +115,7 @@ "Are you a herpetologist?", "Sure, okay, but I bet you can't pronounce it.", "Are you cheating?" -] +) # snake card consts CARD = { @@ -142,7 +142,7 @@ class Snakes: """ wiki_brief = re.compile(r'(.*?)(=+ (.*?) =+)', flags=re.DOTALL) - valid = ('gif', 'png', 'jpeg', 'jpg', 'webp') + valid_image_extensions = ('gif', 'png', 'jpeg', 'jpg', 'webp') def __init__(self, bot: AutoShardedBot): self.active_sal = {} @@ -222,8 +222,6 @@ def generate_card(buffer: BytesIO, content: dict) -> BytesIO: fill=(63, 63, 63, 128) ) - del rect - # Paste it onto the final image full_image.paste(rectangle, (0, 0), mask=rectangle) @@ -233,8 +231,6 @@ def generate_card(buffer: BytesIO, content: dict) -> BytesIO: draw.text([margin + 4, offset], line, font=CARD['font']) offset += CARD['font'].getsize(line)[1] - del draw - # Get the image contents as a BufferIO object buffer = BytesIO() full_image.save(buffer, 'PNG') @@ -682,8 +678,7 @@ async def get(self, ctx: Context, name: Snake = None): ) emoji = 'https://emojipedia-us.s3.amazonaws.com/thumbs/60/google/3/snake_1f40d.png' - print(next((url for url in data['image_list']))) - image = next((url for url in data['image_list'] if url.endswith(self.valid)), emoji) + image = next((url for url in data['image_list'] if url.endswith(self.valid_image_extensions)), emoji) embed.set_image(url=image) await ctx.send(embed=embed) @@ -709,7 +704,7 @@ async def guess(self, ctx): data = await self._get_snek(snake) - image = next((url for url in data['image_list'] if url.endswith(self.valid)), None) + image = next((url for url in data['image_list'] if url.endswith(self.valid_image_extensions)), None) embed = Embed( title='Which of the following is the snake in the image?', diff --git a/bot/decorators.py b/bot/decorators.py index 4326e1ed28..256d8aea07 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -58,6 +58,7 @@ def locked(): ignored until the command has completed invocation. This decorator has to go before (below) the `command` decorator. """ + def wrap(func): func.__locks = WeakValueDictionary() diff --git a/bot/utils/__init__.py b/bot/utils/__init__.py index c3e483707b..1a902b68cf 100644 --- a/bot/utils/__init__.py +++ b/bot/utils/__init__.py @@ -13,6 +13,10 @@ async def disambiguate( ): """ Has the user choose between multiple entries in case one could not be chosen automatically. + + This will raise a BadArgument if entries is empty, if the disambiguation event times out, + or if the user makes an invalid choice. + :param ctx: Context object from discord.py :param entries: List of items for user to choose from :param timeout: Number of seconds to wait before canceling disambiguation diff --git a/bot/utils/snakes/perlin.py b/bot/utils/snakes/perlin.py index 19eafe6a05..0401787ef5 100644 --- a/bot/utils/snakes/perlin.py +++ b/bot/utils/snakes/perlin.py @@ -3,9 +3,9 @@ Taken from: https://gist.github.com/eevee/26f547457522755cb1fb8739d0ea89a1 Licensed under ISC """ + import math import random -# Licensed under ISC from itertools import product From 18663a79df5cccfcac529b914ea6cb4f45157359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Fri, 18 May 2018 20:17:37 +0200 Subject: [PATCH 26/27] Addressing comments by gdude on the site PR --- bot/cogs/events.py | 12 ++++++++---- bot/cogs/hiphopify.py | 2 +- bot/cogs/snakes.py | 8 ++++---- bot/cogs/tags.py | 2 +- bot/converters.py | 4 ++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/bot/cogs/events.py b/bot/cogs/events.py index f13713c07a..d8f5edd334 100644 --- a/bot/cogs/events.py +++ b/bot/cogs/events.py @@ -7,9 +7,13 @@ NoPrivateMessage, UserInputError ) -from bot.constants import DEVLOG_CHANNEL, PYTHON_GUILD, SITE_API_KEY, SITE_API_USER_URL +from bot.constants import ( + DEBUG_MODE, DEVLOG_CHANNEL, PYTHON_GUILD, + SITE_API_KEY, SITE_API_URL +) log = logging.getLogger(__name__) +USERS_URL = f"{SITE_API_URL}/bot/users" class Events: @@ -24,13 +28,13 @@ async def send_updated_users(self, *users, replace_all=False): try: if replace_all: response = await self.bot.http_session.post( - url=f"{SITE_API_URL}/user", + url=USERS_URL, json=list(users), headers={"X-API-Key": SITE_API_KEY} ) else: response = await self.bot.http_session.put( - url=f"{SITE_API_URL}/user", + url=USERS_URL, json=list(users), headers={"X-API-Key": SITE_API_KEY} ) @@ -43,7 +47,7 @@ async def send_updated_users(self, *users, replace_all=False): async def send_delete_users(self, *users): try: response = await self.bot.http_session.delete( - url=f"{SITE_API_URL}/user", + url=USERS_URL, json=list(users), headers={"X-API-Key": SITE_API_KEY} diff --git a/bot/cogs/hiphopify.py b/bot/cogs/hiphopify.py index a29d09b209..bb8dc13004 100644 --- a/bot/cogs/hiphopify.py +++ b/bot/cogs/hiphopify.py @@ -23,7 +23,7 @@ class Hiphopify: def __init__(self, bot: AutoShardedBot): self.bot = bot self.headers = {"X-API-KEY": SITE_API_KEY} - self.url = f"{SITE_API_URL}/hiphopify" + self.url = f"{SITE_API_URL}/bot/hiphopify" async def on_member_update(self, before, after): """ diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 3a5202c1d8..8f39429252 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -150,10 +150,10 @@ def __init__(self, bot: AutoShardedBot): self.headers = {"X-API-KEY": SITE_API_KEY} # Build API urls. - self.quiz_url = f"{SITE_API_URL}/snake_quiz" - self.facts_url = f"{SITE_API_URL}/snake_facts" - self.names_url = f"{SITE_API_URL}/snake_names" - self.idioms_url = f"{SITE_API_URL}/snake_idioms" + self.quiz_url = f"{SITE_API_URL}/bot/snake_quiz" + self.facts_url = f"{SITE_API_URL}/bot/snake_facts" + self.names_url = f"{SITE_API_URL}/bot/snake_names" + self.idioms_url = f"{SITE_API_URL}/bot/snake_idioms" # region: Helper methods @staticmethod diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py index f85160c9f6..46be1c44a1 100644 --- a/bot/cogs/tags.py +++ b/bot/cogs/tags.py @@ -87,7 +87,7 @@ def __init__(self, bot: AutoShardedBot): self.bot = bot self.tag_cooldowns = {} self.headers = {"X-API-KEY": SITE_API_KEY} - self.url = f"{SITE_API_URL}/tags" + self.url = f"{SITE_API_URL}/bot/tags" async def get_tag_data(self, tag_name=None) -> dict: """ diff --git a/bot/converters.py b/bot/converters.py index 4186ec320c..a629768b79 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -9,8 +9,8 @@ from bot.constants import DEBUG_MODE, SITE_API_KEY, SITE_API_URL from bot.utils import disambiguate -NAMES_URL = f"{SITE_API_URL}/snake_names" -SPECIAL_URL = f"{SITE_API_URL}/special_snakes" +NAMES_URL = f"{SITE_API_URL}/bot/snake_names" +SPECIAL_URL = f"{SITE_API_URL}/bot/special_snakes" class Snake(Converter): From 9f5f0cef5000f741e22734d8537683d1c607995b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Sand=C3=B8y?= Date: Sat, 19 May 2018 18:54:15 +0200 Subject: [PATCH 27/27] Changes requested by Joseph --- bot/cogs/snakes.py | 110 ++++++++++++++++++++++++--------------------- bot/decorators.py | 15 +++++++ 2 files changed, 73 insertions(+), 52 deletions(-) diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index 8f39429252..3a5d79148f 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -17,7 +17,10 @@ from discord.ext.commands import AutoShardedBot, BadArgument, Context, bot_has_permissions, command from PIL import Image, ImageDraw, ImageFont -from bot.constants import ERROR_REPLIES, OMDB_API_KEY, SITE_API_KEY, SITE_API_URL, YOUTUBE_API_KEY +from bot.constants import ( + ERROR_REPLIES, OMDB_API_KEY, SITE_API_KEY, + SITE_API_URL, YOUTUBE_API_KEY +) from bot.converters import Snake from bot.decorators import locked from bot.utils.snakes import hatching, perlin, perlinsneks, sal @@ -157,7 +160,25 @@ def __init__(self, bot: AutoShardedBot): # region: Helper methods @staticmethod - def generate_card(buffer: BytesIO, content: dict) -> BytesIO: + def _beautiful_pastel(hue): + """ + Returns random bright pastels. + """ + + light = random.uniform(0.7, 0.85) + saturation = 1 + + rgb = colorsys.hls_to_rgb(hue, light, saturation) + hex_rgb = "" + + for part in rgb: + value = int(part * 0xFF) + hex_rgb += f"{value:02x}" + + return int(hex_rgb, 16) + + @staticmethod + def _generate_card(buffer: BytesIO, content: dict) -> BytesIO: """ Generate a card from snake information. @@ -276,6 +297,20 @@ async def _fetch(self, session, url, params=None): async with session.get(url, params=params) as response: return await response.json() + def _get_random_long_message(self, messages, retries=10): + """ + Fetch a message that's at least 3 words long, + but only if it is possible to do so in retries + attempts. Else, just return whatever the last + message is. + """ + + long_message = random.choice(messages) + if len(long_message.split()) < 3 or retries <= 0: + return self._get_random_long_message(messages, retries - 1) + + return long_message + async def _get_snek(self, name: str) -> Dict[str, Any]: """ Goes online and fetches all the data from a wikipedia article @@ -433,6 +468,7 @@ def predicate(reaction, user): # region: Commands @bot_has_permissions(manage_messages=True) @command(name="snakes.antidote()", aliases=["snakes.antidote"]) + @locked() async def antidote(self, ctx: Context): """ Antidote - Can you create the antivenom before the patient dies? @@ -449,10 +485,11 @@ async def antidote(self, ctx: Context): This game was created by Lord Bisk and Runew0lf. """ - def event_check(reaction_: Reaction, user_: Member): + def predicate(reaction_: Reaction, user_: Member): """ Make sure that this reaction is what we want to operate on """ + return ( all(( reaction_.message.id == board_id.id, # Reaction is on this message @@ -498,7 +535,7 @@ def event_check(reaction_: Reaction, user_: Member): # Begin main game loop while not win and antidote_tries < 10: try: - reaction, user = await ctx.bot.wait_for("reaction_add", timeout=300, check=event_check) + reaction, user = await ctx.bot.wait_for("reaction_add", timeout=300, check=predicate) except asyncio.TimeoutError: log.debug("Antidote timed out waiting for a reaction") break # We're done, no reactions for the last 5 minutes @@ -580,31 +617,14 @@ async def draw(self, ctx: Context): Modified by juan and lemon. """ - def beautiful_pastel(hue): - """ - Returns random bright pastels. - """ - - light = random.uniform(0.7, 0.85) - saturation = 1 - - rgb = colorsys.hls_to_rgb(hue, light, saturation) - hex_rgb = "" - - for part in rgb: - value = int(part * 0xFF) - hex_rgb += f"{value:02x}" - - return int(hex_rgb, 16) - with ctx.typing(): # Generate random snake attributes width = random.randint(6, 10) length = random.randint(15, 22) random_hue = random.random() - snek_color = beautiful_pastel(random_hue) - text_color = beautiful_pastel((random_hue + 0.5) % 1) + snek_color = self._beautiful_pastel(random_hue) + text_color = self._beautiful_pastel((random_hue + 0.5) % 1) bg_color = ( random.randint(32, 50), random.randint(32, 50), @@ -820,6 +840,7 @@ async def movie(self, ctx: Context): ) @command(name="snakes.quiz()", aliases=["snakes.quiz"]) + @locked() async def quiz(self, ctx: Context): """ Asks a snake-related question in the chat and validates the user's guess. @@ -917,6 +938,7 @@ async def random_snake_name(self, ctx: Context, name: str = None): return await ctx.send(embed=embed) @command(name="snakes.sal()", aliases=["snakes.sal"]) + @locked() async def sal(self, ctx: Context): """ Play a game of Snakes and Ladders! @@ -925,7 +947,6 @@ async def sal(self, ctx: Context): Modified by lemon. """ - # CREATE # # check if there is already a game in this channel if ctx.channel in self.active_sal: await ctx.send(f"{ctx.author.mention} A game is already in progress in this channel.") @@ -1013,7 +1034,7 @@ async def snake_card(self, ctx: Context, name: Snake = None): stream.seek(0) - func = partial(self.generate_card, stream, content) + func = partial(self._generate_card, stream, content) final_buffer = await self.bot.loop.run_in_executor(None, func) # Send it! @@ -1065,24 +1086,6 @@ async def snakify(self, ctx: Context, message: str = None): Modified by lemon. """ - def predicate(message): - """ - Check if the message was sent by the author. - """ - return message.author == ctx.message.author - - def get_random_long_message(messages, retries=10): - """ - Fetch a message that's at least 3 words long, - but only if it is possible to do so in retries - attempts. Else, just return whatever the last - message is. - """ - long_message = random.choice(messages) - if len(long_message.split()) < 3 or retries <= 0: - return get_random_long_message(messages, retries - 1) - return long_message - with ctx.typing(): embed = Embed() user = ctx.message.author @@ -1091,19 +1094,18 @@ def get_random_long_message(messages, retries=10): # Get a random message from the users history messages = [] - async for message in ctx.channel.history(limit=500).filter(predicate): + async for message in ctx.channel.history(limit=500).filter( + lambda msg: msg.author == ctx.message.author # Message was sent by author. + ): messages.append(message.content) - message = get_random_long_message(messages) + message = self._get_random_long_message(messages) # Set the avatar if user.avatar is not None: avatar = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}" else: - avatar = ( - "https://img00.deviantart.net/eee3/i/2017/168/3/4/" - "discord__app__avatar_rev1_by_nodeviantarthere-dbd2tp9.png" - ) + avatar = ctx.author.default_avatar_url # Build and send the embed embed.set_author( @@ -1153,12 +1155,13 @@ async def video(self, ctx: Context, search: str = None): content=f"{youtube_base_url}{data[num]['id']['videoId']}" ) else: - log.warning(f"CRITICAL ERROR: YouTube API returned {response}") + log.warning(f"YouTube API error. Full response looks like {response}") @command(name="snakes.zen()", aliases=["zen"]) async def zen(self, ctx: Context): """ - Gets a random quote from the Zen of Python. + Gets a random quote from the Zen of Python, + except as if spoken by a snake. Written by Prithaj and Andrew. Modified by lemon. @@ -1180,8 +1183,10 @@ async def zen(self, ctx: Context): ) # endregion - @snake_card.error + # region: Error handlers @get.error + @snake_card.error + @video.error async def command_error(self, ctx, error): embed = Embed() @@ -1201,6 +1206,7 @@ async def command_error(self, ctx, error): return await ctx.send(embed=embed) + # endregion def setup(bot): diff --git a/bot/decorators.py b/bot/decorators.py index 256d8aea07..fe974cbd3b 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -1,11 +1,15 @@ import logging +import random from asyncio import Lock from functools import wraps from weakref import WeakValueDictionary +from discord import Colour, Embed from discord.ext import commands from discord.ext.commands import Context +from bot.constants import ERROR_REPLIES + log = logging.getLogger(__name__) @@ -56,6 +60,7 @@ def locked(): Allows the user to only run one instance of the decorated command at a time. Subsequent calls to the command from the same author are ignored until the command has completed invocation. + This decorator has to go before (below) the `command` decorator. """ @@ -66,7 +71,17 @@ def wrap(func): async def inner(self, ctx, *args, **kwargs): lock = func.__locks.setdefault(ctx.author.id, Lock()) if lock.locked(): + embed = Embed() + embed.colour = Colour.red() + + log.debug(f"User tried to invoke a locked command.") + embed.description = ( + "You're already using this command. Please wait until it is done before you use it again." + ) + embed.title = random.choice(ERROR_REPLIES) + await ctx.send(embed=embed) return + async with func.__locks.setdefault(ctx.author.id, Lock()): return await func(self, ctx, *args, **kwargs) return inner