diff options
15 files changed, 463 insertions, 0 deletions
diff --git a/bot/resources/easter/egghead_questions.json b/bot/resources/easter/egghead_questions.json new file mode 100644 index 00000000..e4e21ebe --- /dev/null +++ b/bot/resources/easter/egghead_questions.json @@ -0,0 +1,181 @@ +[ + { + "question": "Where did the idea of the Easter Bunny originate?", + "answers": [ + "Russia", + "The United States", + "The UK", + "Germany" + ], + "correct_answer": 3 + }, + { + "question": "The Easter Bunny was originally going to be a...", + "answers": [ + "hare", + "possum", + "cat", + "dove" + ], + "correct_answer": 0 + }, + { + "question": "Which of the following is NOT a movie about Easter?", + "answers": [ + "Winnie the Pooh - Springtime with Roo", + "It's a Wonderful Life", + "The Passion of the Christ", + "Here Comes Peter Cottontail" + ], + "correct_answer": 1 + }, + { + "question": "In Australia, what animal is used instead of the Easter Bunny?", + "answers": [ + "kangaroo", + "wombat", + "koala", + "bilby" + ], + "correct_answer": 3 + }, + { + "question": "When was the first Earth Day?", + "answers": [ + "1982", + "2003", + "1999", + "1970" + ], + "correct_answer": 2 + }, + { + "question": "Who is considered to be the founder of Earth Day?", + "answers": [ + "President Jimmy Carter", + "President John F. Kennedy", + "Vice President Al Gore", + "Senator Gaylord Nelson" + ], + "correct_answer": 3 + }, + { + "question": "Approximately how many countries participated in Earth Day 2000?", + "answers": [ + "60", + "140", + "180", + "240" + ], + "correct_answer": 2 + }, + { + "question": "As Earth Day is this month, how old is the Earth?", + "answers": [ + "4.5 billion years old", + "5 million years old", + "10 billion years old", + "6.7 billion years old" + ], + "correct_answer": 0 + }, + { + "question": "As a celebration of Earth Day, what is the percentage of Oxygen in the Earth's atmosphere?", + "answers": [ + "18%", + "21%", + "25%", + "31%" + ], + "correct_answer": 1 + }, + { + "question": "In what year did Google begin its tradition of April Fools Jokes?", + "answers": [ + "1997", + "2000", + "2003", + "2007" + ], + "correct_answer": 1 + }, + { + "question": "Which type of chocolate is the most healthy?", + "answers": [ + "Dark", + "White", + "Milk" + ], + "correct_answer": 0 + }, + { + "question": "How many bars of milk chocolate would you have to eat to get the same amount of caffeine as in one cup of coffee?", + "answers": [ + "3", + "9", + "14", + "20" + ], + "correct_answer": 2 + }, + { + "question": "Aztecs used to use one of the ingedients of chocolate, cocoa beans, as...", + "answers": [ + "currency", + "medicine", + "dye", + "fertilizer" + ], + "correct_answer": 0 + }, + { + "question": "Which European country was the first to enjoy chocolate?", + "answers": [ + "France", + "Spain", + "England", + "Switzerland" + ], + "correct_answer": 1 + }, + { + "question": "The first European Chocolate Shop opened in what city in 1657?", + "answers": [ + "Paris, France", + "Madrid, Spain", + "Zürich, Switzerland", + "London, England" + ], + "correct_answer": 3 + }, + { + "question": "On average, how many eggs does a hen lay in a year?", + "answers": [ + "Between 200-230", + "Between 250-270", + "Between 300-330", + "Between 370-400" + ], + "correct_answer": 1 + }, + { + "question": "What determines the colour of an egg yolk?", + "answers": [ + "The size of the hen", + "The age of a hen", + "The diet of a hen", + "The colour of a hen's feathers" + ], + "correct_answer": 2 + }, + { + "question": "What country produces the most eggs in a year?", + "answers": [ + "China", + "India", + "The United States", + "Japan" + ], + "correct_answer": 0 + } +]
\ No newline at end of file diff --git a/bot/resources/easter/traditions.json b/bot/resources/easter/traditions.json new file mode 100644 index 00000000..f9dd6d81 --- /dev/null +++ b/bot/resources/easter/traditions.json @@ -0,0 +1,13 @@ +{"England": "Easter in England is celebrated through the exchange of Easter Eggs and other gifts like clothes, chocolates or holidays packages. Easter bonnets or baskets are also made that have fillings like daffodils in them.", +"Haiti": "In Haiti, kids have the freedom to spend Good Friday playing outdoors. On this day colourful kites fill the sky and children run long distances, often barefoot, trying to get their kite higher than their friends.", +"Indonesia": "Slightly unconventional, but kids in Indonesia celebrate Easter with a tooth brushing competition!", +"Ethipoia": "In Ethiopia, Easter is called Fasika and marks the end of a 55-day fast during which Christians have only eaten one vegetarian meal a day. Ethiopians will often break their fast after church by eating injera (a type of bread) or teff pancakes, made from grass flour.", +"El Salvador": "On Good Friday communities make rug-like paintings on the streets with sand and sawdust. These later become the path for processions and main avenues and streets are closed", +"Ghana": "Ghanaians dress in certain colours to mark the different days of Easter. On Good Friday, depending on the church denomination, men and women will either dress in dark mourning clothes or bright colours. On Easter Sunday everyone wears white.", +"Kenya": "On Easter Sunday, kids in Kenya look forward to a sumptuous Easter meal after church (Easter services are known to last for three hours!). Children share Nyama Choma (roasted meat) and have a soft drink with their meal!", +"Guatemala": "In Guatemala, Easter customs include a large, colourful celebration marked by countless processions. The main roads are closed, and the sound of music rings through the streets. Special food is prepared such as curtido (a diced vegetable mix which is cooked in vinegar to achieve a sour taste), fish, eggs, chickpeas, fruit mix, pumpkin, pacaya palm and spondias fruit (a Spanish version of a plum.)", +"Germany": "In Germany, Easter is known by the name of Ostern. Easter holidays for children last for about three weeks. Good Friday, Easter Saturday and Easter Sunday are the days when people do not work at all.", +"Mexico": "Semana Santa and Pascua (two separate observances) form a part of Easter celebrations in Mexico. Semana Santa stands for the entire Holy Week, from Palm Sunday to Easter Saturday, whereas the Pascua is the observance of the period from the Resurrection Sunday to the following Saturday.", +"Poland": "They shape the Easter Butter Lamb (Baranek Wielkanocyny) from a chunk of butter. They attempt to make it look like a fluffy lamb!", +"Greece": "They burn an effigy of Judas Iscariot, the betrayer of Jesus, sometimes is done as part of a Passion Play! It is hung by the neck and then burnt.", +"Philippines": "Some Christians put themselves through the same pain that Christ endured, they have someone naile them to a cross and put a crown of thornes on their head."} diff --git a/bot/resources/halloween/spooky_rating.json b/bot/resources/halloween/spooky_rating.json new file mode 100644 index 00000000..1815befc --- /dev/null +++ b/bot/resources/halloween/spooky_rating.json @@ -0,0 +1,47 @@ +{ + "-1": { + "title": "\uD83D\uDD6F You're not scarin' anyone \uD83D\uDD6F", + "text": "No matter what you say or do, nobody even flinches when you try to scare them. Was your costume this year only a white sheet with holes for eyes? Or did you even bother with a costume at all? Either way, don't expect too many treats when going from door-to-door.", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/candle.jpeg" + }, + "5": { + "title": "\uD83D\uDC76 Like taking candy from a baby \uD83D\uDC76", + "text": "Your scaring will probably make a baby cry... but that's the limit on your frightening powers. Be careful not to get to the point where everyone's running away from you because they don't like you, not because they're scared of you.", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/baby.jpeg" + }, + "20": { + "title": "\uD83C\uDFDA You're skills are forming... \uD83C\uDFDA", + "text": "As you become the Devil's apprentice, you begin to make people jump every time you sneak up on them. A good start, but you have to learn not to wear the same costume every year until it doesn't fit you. People will notice you and your prowess will decrease.", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/tiger.jpeg" + }, + "30": { + "title": "\uD83D\uDC80 Picture Perfect... \uD83D\uDC80", + "text": "You've nailed the costume this year! You look suuuper scary! Now make sure to play the part and act out your costume and you'll be sure to give a few people a massive fright!", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/costume.jpeg" + }, + "50": { + "title": "\uD83D\uDC7B Uhm... are you human \uD83D\uDC7B", + "text": "Uhm... you're too good to be human and now you're beginning to sound like a ghost. You're almost invisible when haunting and nobody truly knows where you are at any given time. But they will always scream at the sound of a ghost...", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/ghost.jpeg" + }, + "65": { + "title": "\uD83C\uDF83 That potion can't be real \uD83C\uDF83", + "text": "You're carrying... some... unknown liquids and no one knows who they are but yourself. Be careful on who you use these powerful spells on, because no Mage has the power to do any irreversible enchantments because even you won't know what will happen to these mortals.", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/necromancer.jepg" + }, + "80": { + "title": "\uD83E\uDD21 The most sinister face \uD83E\uDD21", + "text": "Who knew something intended to be playful could be so menacing... Especially other people seeing you in their nightmares, continuing to haunt them day by day, stuck in their head throughout the entire year. Make sure to pull a face they will never forget.", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/clown.jpeg" + }, + "95": { + "title": "\uD83D\uDE08 The Devil's Accomplice \uD83D\uDE08", + "text": "Imagine being allies with the most evil character with an aim to scare people to death. Force people to suffer as they proceed straight to hell to meet your boss and best friend. Not even you know the power He has...", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/jackolantern.jpg" + }, + "100": { + "title":"\uD83D\uDC7F The Devil Himself \uD83D\uDC7F", + "text": "You are the evillest creature in existence to scare anyone and everyone humanly possible. The reason your underlings are called mortals is that they die. With your help, they die a lot quicker. With all the evil power in the universe, you know what to do.", + "image": "https://raw.githubusercontent.com/python-discord/seasonalbot/master/bot/resources/halloween/spookyrating/devil.jpeg" + } +}
\ No newline at end of file diff --git a/bot/resources/halloween/spookyrating/baby.jpeg b/bot/resources/halloween/spookyrating/baby.jpeg Binary files differnew file mode 100644 index 00000000..199f8bca --- /dev/null +++ b/bot/resources/halloween/spookyrating/baby.jpeg diff --git a/bot/resources/halloween/spookyrating/candle.jpeg b/bot/resources/halloween/spookyrating/candle.jpeg Binary files differnew file mode 100644 index 00000000..9913752b --- /dev/null +++ b/bot/resources/halloween/spookyrating/candle.jpeg diff --git a/bot/resources/halloween/spookyrating/clown.jpeg b/bot/resources/halloween/spookyrating/clown.jpeg Binary files differnew file mode 100644 index 00000000..f23c4f70 --- /dev/null +++ b/bot/resources/halloween/spookyrating/clown.jpeg diff --git a/bot/resources/halloween/spookyrating/costume.jpeg b/bot/resources/halloween/spookyrating/costume.jpeg Binary files differnew file mode 100644 index 00000000..b3c21af0 --- /dev/null +++ b/bot/resources/halloween/spookyrating/costume.jpeg diff --git a/bot/resources/halloween/spookyrating/devil.jpeg b/bot/resources/halloween/spookyrating/devil.jpeg Binary files differnew file mode 100644 index 00000000..4f45aaa7 --- /dev/null +++ b/bot/resources/halloween/spookyrating/devil.jpeg diff --git a/bot/resources/halloween/spookyrating/ghost.jpeg b/bot/resources/halloween/spookyrating/ghost.jpeg Binary files differnew file mode 100644 index 00000000..0cb13346 --- /dev/null +++ b/bot/resources/halloween/spookyrating/ghost.jpeg diff --git a/bot/resources/halloween/spookyrating/jackolantern.jpeg b/bot/resources/halloween/spookyrating/jackolantern.jpeg Binary files differnew file mode 100644 index 00000000..d7cf3d08 --- /dev/null +++ b/bot/resources/halloween/spookyrating/jackolantern.jpeg diff --git a/bot/resources/halloween/spookyrating/necromancer.jpeg b/bot/resources/halloween/spookyrating/necromancer.jpeg Binary files differnew file mode 100644 index 00000000..60b1e689 --- /dev/null +++ b/bot/resources/halloween/spookyrating/necromancer.jpeg diff --git a/bot/resources/halloween/spookyrating/tiger.jpeg b/bot/resources/halloween/spookyrating/tiger.jpeg Binary files differnew file mode 100644 index 00000000..0419f5df --- /dev/null +++ b/bot/resources/halloween/spookyrating/tiger.jpeg diff --git a/bot/seasons/easter/egghead_quiz.py b/bot/seasons/easter/egghead_quiz.py new file mode 100644 index 00000000..8dd2c21d --- /dev/null +++ b/bot/seasons/easter/egghead_quiz.py @@ -0,0 +1,121 @@ +import asyncio +import logging +import random +from json import load +from pathlib import Path + +import discord +from discord.ext import commands + +from bot.constants import Colours + +log = logging.getLogger(__name__) + +with open(Path('bot', 'resources', 'easter', 'egghead_questions.json'), 'r', encoding="utf8") as f: + EGGHEAD_QUESTIONS = load(f) + + +EMOJIS = [ + '\U0001f1e6', '\U0001f1e7', '\U0001f1e8', '\U0001f1e9', '\U0001f1ea', + '\U0001f1eb', '\U0001f1ec', '\U0001f1ed', '\U0001f1ee', '\U0001f1ef', + '\U0001f1f0', '\U0001f1f1', '\U0001f1f2', '\U0001f1f3', '\U0001f1f4', + '\U0001f1f5', '\U0001f1f6', '\U0001f1f7', '\U0001f1f8', '\U0001f1f9', + '\U0001f1fa', '\U0001f1fb', '\U0001f1fc', '\U0001f1fd', '\U0001f1fe', + '\U0001f1ff' +] # Regional Indicators A-Z (used for voting) + +TIMELIMIT = 30 + + +class EggheadQuiz(commands.Cog): + """This cog contains the command for the Easter quiz!""" + + def __init__(self, bot): + self.bot = bot + self.quiz_messages = {} + + @commands.command(aliases=["eggheadquiz", "easterquiz"]) + async def eggquiz(self, ctx): + """ + Gives a random quiz question, waits 30 seconds and then outputs the answer + + Also informs of the percentages and votes of each option + """ + + random_question = random.choice(EGGHEAD_QUESTIONS) + question, answers = random_question["question"], random_question["answers"] + answers = [(EMOJIS[i], a) for i, a in enumerate(answers)] + correct = EMOJIS[random_question["correct_answer"]] + + valid_emojis = [emoji for emoji, _ in answers] + + description = f"You have {TIMELIMIT} seconds to vote.\n\n" + description += "\n".join([f"{emoji} -> **{answer}**" for emoji, answer in answers]) + + q_embed = discord.Embed(title=question, description=description, colour=Colours.pink) + + msg = await ctx.send(embed=q_embed) + for emoji in valid_emojis: + await msg.add_reaction(emoji) + + self.quiz_messages[msg.id] = valid_emojis + + await asyncio.sleep(TIMELIMIT) + + del self.quiz_messages[msg.id] + + msg = await ctx.channel.fetch_message(msg.id) # Refreshes message + + total_no = sum([len(await r.users().flatten()) for r in msg.reactions]) - len(valid_emojis) # - bot's reactions + + if total_no == 0: + return await msg.delete() # to avoid ZeroDivisionError if nobody reacts + + results = ["**VOTES:**"] + for emoji, _ in answers: + num = [len(await r.users().flatten()) for r in msg.reactions if str(r.emoji) == emoji][0] - 1 + percent = round(100 * num / total_no) + s = "" if num == 1 else "s" + string = f"{emoji} - {num} vote{s} ({percent}%)" + results.append(string) + + mentions = " ".join([ + u.mention for u in [ + await r.users().flatten() for r in msg.reactions if str(r.emoji) == correct + ][0] if not u.bot + ]) + + content = f"Well done {mentions} for getting it correct!" if mentions else "Nobody got it right..." + + a_embed = discord.Embed( + title=f"The correct answer was {correct}!", + description="\n".join(results), + colour=Colours.pink + ) + + await ctx.send(content, embed=a_embed) + + @staticmethod + async def already_reacted(message, user): + """Returns whether a given user has reacted more than once to a given message""" + users = [u.id for reaction in [await r.users().flatten() for r in message.reactions] for u in reaction] + return users.count(user.id) > 1 # Old reaction plus new reaction + + @commands.Cog.listener() + async def on_reaction_add(self, reaction, user): + """Listener to listen specifically for reactions of quiz messages""" + if user.bot: + return + if reaction.message.id not in self.quiz_messages: + return + if str(reaction.emoji) not in self.quiz_messages[reaction.message.id]: + return await reaction.message.remove_reaction(reaction, user) + if await self.already_reacted(reaction.message, user): + return await reaction.message.remove_reaction(reaction, user) + + +def setup(bot): + """Cog load.""" + + bot.add_cog(EggheadQuiz(bot)) + log.info("EggheadQuiz bot loaded") diff --git a/bot/seasons/easter/traditions.py b/bot/seasons/easter/traditions.py new file mode 100644 index 00000000..05cd79f3 --- /dev/null +++ b/bot/seasons/easter/traditions.py @@ -0,0 +1,33 @@ +import json +import logging +import random +from pathlib import Path + +from discord.ext import commands + +log = logging.getLogger(__name__) + +with open(Path('bot', 'resources', 'easter', 'traditions.json'), 'r', encoding="utf8") as f: + traditions = json.load(f) + + +class Traditions(commands.Cog): + """A cog which allows users to get a random easter tradition or custom from a random country.""" + + def __init__(self, bot): + self.bot = bot + + @commands.command(aliases=('eastercustoms',)) + async def easter_tradition(self, ctx): + """Responds with a random tradition or custom""" + + random_country = random.choice(list(traditions)) + + await ctx.send(f"{random_country}:\n{traditions[random_country]}") + + +def setup(bot): + """Traditions Cog load.""" + + bot.add_cog(Traditions(bot)) + log.info("Traditions cog loaded") diff --git a/bot/seasons/halloween/spookyrating.py b/bot/seasons/halloween/spookyrating.py new file mode 100644 index 00000000..a9cfda9b --- /dev/null +++ b/bot/seasons/halloween/spookyrating.py @@ -0,0 +1,68 @@ +import bisect +import json +import logging +import random +from pathlib import Path + +import discord +from discord.ext import commands + +from bot.constants import Colours + +log = logging.getLogger(__name__) + +with Path('bot', 'resources', 'halloween', 'spooky_rating.json').open() as file: + SPOOKY_DATA = json.load(file) + SPOOKY_DATA = sorted((int(key), value) for key, value in SPOOKY_DATA.items()) + + +class SpookyRating(commands.Cog): + """A cog for calculating one's spooky rating""" + + def __init__(self, bot): + self.bot = bot + self.local_random = random.Random() + + @commands.command() + @commands.cooldown(rate=1, per=5, type=commands.BucketType.user) + async def spookyrating(self, ctx, who: discord.Member = None): + """ + Calculates the spooky rating of someone. + + Any user will always yield the same result, no matter who calls the command + """ + + if who is None: + who = ctx.author + + # This ensures that the same result over multiple runtimes + self.local_random.seed(who.id) + spooky_percent = self.local_random.randint(1, 101) + + # We need the -1 due to how bisect returns the point + # see the documentation for further detail + # https://docs.python.org/3/library/bisect.html#bisect.bisect + index = bisect.bisect(SPOOKY_DATA, (spooky_percent,)) - 1 + + _, data = SPOOKY_DATA[index] + + embed = discord.Embed( + title=data['title'], + description=f'{who} scored {spooky_percent}%!', + color=Colours.orange + ) + embed.add_field( + name='A whisper from Satan', + value=data['text'] + ) + embed.set_thumbnail( + url=data['image'] + ) + + await ctx.send(embed=embed) + + +def setup(bot): + """Cog load.""" + bot.add_cog(SpookyRating(bot)) + log.info("SpookyRating cog loaded") |