From 2780043e6ddd5dbee82b62d85289f0518613ce7b Mon Sep 17 00:00:00 2001 From: Janine vN Date: Sat, 4 Sep 2021 23:22:12 -0400 Subject: Move Easter to Holidays Folder This moves the easter seasonal features into a more cohesive holidays/easter folder. Additionally, this splits out earth day into its own holiday folder. --- bot/exts/easter/__init__.py | 0 bot/exts/easter/april_fools_vids.py | 30 ---- bot/exts/easter/bunny_name_generator.py | 94 ----------- bot/exts/easter/earth_photos.py | 66 -------- bot/exts/easter/easter_riddle.py | 112 ------------- bot/exts/easter/egg_decorating.py | 119 -------------- bot/exts/easter/egg_facts.py | 55 ------- bot/exts/easter/egghead_quiz.py | 118 -------------- bot/exts/easter/save_the_planet.py | 25 --- bot/exts/easter/traditions.py | 28 ---- bot/exts/halloween/__init__.py | 0 bot/exts/holidays/__init__.py | 0 bot/exts/holidays/earth_day/__init__.py | 0 bot/exts/holidays/earth_day/save_the_planet.py | 25 +++ bot/exts/holidays/easter/__init__.py | 0 bot/exts/holidays/easter/april_fools_vids.py | 30 ++++ bot/exts/holidays/easter/bunny_name_generator.py | 94 +++++++++++ bot/exts/holidays/easter/earth_photos.py | 66 ++++++++ bot/exts/holidays/easter/easter_riddle.py | 112 +++++++++++++ bot/exts/holidays/easter/egg_decorating.py | 119 ++++++++++++++ bot/exts/holidays/easter/egg_facts.py | 55 +++++++ bot/exts/holidays/easter/egghead_quiz.py | 118 ++++++++++++++ bot/exts/holidays/easter/traditions.py | 28 ++++ bot/exts/pride/__init__.py | 0 bot/resources/easter/april_fools_vids.json | 130 --------------- bot/resources/easter/bunny_names.json | 29 ---- bot/resources/easter/chocolate_bunny.png | Bin 7789 -> 0 bytes bot/resources/easter/easter_egg_facts.json | 17 -- bot/resources/easter/easter_eggs/design1.png | Bin 3996 -> 0 bytes bot/resources/easter/easter_eggs/design2.png | Bin 3918 -> 0 bytes bot/resources/easter/easter_eggs/design3.png | Bin 3349 -> 0 bytes bot/resources/easter/easter_eggs/design4.png | Bin 3355 -> 0 bytes bot/resources/easter/easter_eggs/design5.png | Bin 3054 -> 0 bytes bot/resources/easter/easter_eggs/design6.png | Bin 4758 -> 0 bytes bot/resources/easter/easter_riddle.json | 74 --------- bot/resources/easter/egghead_questions.json | 181 --------------------- bot/resources/easter/save_the_planet.json | 77 --------- bot/resources/easter/traditions.json | 13 -- .../holidays/earth_day/save_the_planet.json | 77 +++++++++ .../holidays/easter/april_fools_vids.json | 130 +++++++++++++++ bot/resources/holidays/easter/bunny_names.json | 29 ++++ bot/resources/holidays/easter/chocolate_bunny.png | Bin 0 -> 7789 bytes .../holidays/easter/easter_egg_facts.json | 17 ++ .../holidays/easter/easter_eggs/design1.png | Bin 0 -> 3996 bytes .../holidays/easter/easter_eggs/design2.png | Bin 0 -> 3918 bytes .../holidays/easter/easter_eggs/design3.png | Bin 0 -> 3349 bytes .../holidays/easter/easter_eggs/design4.png | Bin 0 -> 3355 bytes .../holidays/easter/easter_eggs/design5.png | Bin 0 -> 3054 bytes .../holidays/easter/easter_eggs/design6.png | Bin 0 -> 4758 bytes bot/resources/holidays/easter/easter_riddle.json | 74 +++++++++ .../holidays/easter/egghead_questions.json | 181 +++++++++++++++++++++ bot/resources/holidays/easter/traditions.json | 13 ++ 52 files changed, 1168 insertions(+), 1168 deletions(-) delete mode 100644 bot/exts/easter/__init__.py delete mode 100644 bot/exts/easter/april_fools_vids.py delete mode 100644 bot/exts/easter/bunny_name_generator.py delete mode 100644 bot/exts/easter/earth_photos.py delete mode 100644 bot/exts/easter/easter_riddle.py delete mode 100644 bot/exts/easter/egg_decorating.py delete mode 100644 bot/exts/easter/egg_facts.py delete mode 100644 bot/exts/easter/egghead_quiz.py delete mode 100644 bot/exts/easter/save_the_planet.py delete mode 100644 bot/exts/easter/traditions.py delete mode 100644 bot/exts/halloween/__init__.py create mode 100644 bot/exts/holidays/__init__.py create mode 100644 bot/exts/holidays/earth_day/__init__.py create mode 100644 bot/exts/holidays/earth_day/save_the_planet.py create mode 100644 bot/exts/holidays/easter/__init__.py create mode 100644 bot/exts/holidays/easter/april_fools_vids.py create mode 100644 bot/exts/holidays/easter/bunny_name_generator.py create mode 100644 bot/exts/holidays/easter/earth_photos.py create mode 100644 bot/exts/holidays/easter/easter_riddle.py create mode 100644 bot/exts/holidays/easter/egg_decorating.py create mode 100644 bot/exts/holidays/easter/egg_facts.py create mode 100644 bot/exts/holidays/easter/egghead_quiz.py create mode 100644 bot/exts/holidays/easter/traditions.py delete mode 100644 bot/exts/pride/__init__.py delete mode 100644 bot/resources/easter/april_fools_vids.json delete mode 100644 bot/resources/easter/bunny_names.json delete mode 100644 bot/resources/easter/chocolate_bunny.png delete mode 100644 bot/resources/easter/easter_egg_facts.json delete mode 100644 bot/resources/easter/easter_eggs/design1.png delete mode 100644 bot/resources/easter/easter_eggs/design2.png delete mode 100644 bot/resources/easter/easter_eggs/design3.png delete mode 100644 bot/resources/easter/easter_eggs/design4.png delete mode 100644 bot/resources/easter/easter_eggs/design5.png delete mode 100644 bot/resources/easter/easter_eggs/design6.png delete mode 100644 bot/resources/easter/easter_riddle.json delete mode 100644 bot/resources/easter/egghead_questions.json delete mode 100644 bot/resources/easter/save_the_planet.json delete mode 100644 bot/resources/easter/traditions.json create mode 100644 bot/resources/holidays/earth_day/save_the_planet.json create mode 100644 bot/resources/holidays/easter/april_fools_vids.json create mode 100644 bot/resources/holidays/easter/bunny_names.json create mode 100644 bot/resources/holidays/easter/chocolate_bunny.png create mode 100644 bot/resources/holidays/easter/easter_egg_facts.json create mode 100644 bot/resources/holidays/easter/easter_eggs/design1.png create mode 100644 bot/resources/holidays/easter/easter_eggs/design2.png create mode 100644 bot/resources/holidays/easter/easter_eggs/design3.png create mode 100644 bot/resources/holidays/easter/easter_eggs/design4.png create mode 100644 bot/resources/holidays/easter/easter_eggs/design5.png create mode 100644 bot/resources/holidays/easter/easter_eggs/design6.png create mode 100644 bot/resources/holidays/easter/easter_riddle.json create mode 100644 bot/resources/holidays/easter/egghead_questions.json create mode 100644 bot/resources/holidays/easter/traditions.json (limited to 'bot') diff --git a/bot/exts/easter/__init__.py b/bot/exts/easter/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bot/exts/easter/april_fools_vids.py b/bot/exts/easter/april_fools_vids.py deleted file mode 100644 index 5ef40704..00000000 --- a/bot/exts/easter/april_fools_vids.py +++ /dev/null @@ -1,30 +0,0 @@ -import logging -import random -from json import loads -from pathlib import Path - -from discord.ext import commands - -from bot.bot import Bot - -log = logging.getLogger(__name__) - -ALL_VIDS = loads(Path("bot/resources/easter/april_fools_vids.json").read_text("utf-8")) - - -class AprilFoolVideos(commands.Cog): - """A cog for April Fools' that gets a random April Fools' video from Youtube.""" - - @commands.command(name="fool") - async def april_fools(self, ctx: commands.Context) -> None: - """Get a random April Fools' video from Youtube.""" - video = random.choice(ALL_VIDS) - - channel, url = video["channel"], video["url"] - - await ctx.send(f"Check out this April Fools' video by {channel}.\n\n{url}") - - -def setup(bot: Bot) -> None: - """Load the April Fools' Cog.""" - bot.add_cog(AprilFoolVideos()) diff --git a/bot/exts/easter/bunny_name_generator.py b/bot/exts/easter/bunny_name_generator.py deleted file mode 100644 index 4c3137de..00000000 --- a/bot/exts/easter/bunny_name_generator.py +++ /dev/null @@ -1,94 +0,0 @@ -import json -import logging -import random -import re -from pathlib import Path -from typing import Optional - -from discord.ext import commands - -from bot.bot import Bot - -log = logging.getLogger(__name__) - -BUNNY_NAMES = json.loads(Path("bot/resources/easter/bunny_names.json").read_text("utf8")) - - -class BunnyNameGenerator(commands.Cog): - """Generate a random bunny name, or bunnify your Discord username!""" - - @staticmethod - def find_separators(displayname: str) -> Optional[list[str]]: - """Check if Discord name contains spaces so we can bunnify an individual word in the name.""" - new_name = re.split(r"[_.\s]", displayname) - if displayname not in new_name: - return new_name - return None - - @staticmethod - def find_vowels(displayname: str) -> Optional[str]: - """ - Finds vowels in the user's display name. - - If the Discord name contains a vowel and the letter y, it will match one or more of these patterns. - - Only the most recently matched pattern will apply the changes. - """ - expressions = [ - ("a.+y", "patchy"), - ("e.+y", "ears"), - ("i.+y", "ditsy"), - ("o.+y", "oofy"), - ("u.+y", "uffy"), - ] - - for exp, vowel_sub in expressions: - new_name = re.sub(exp, vowel_sub, displayname) - if new_name != displayname: - return new_name - - @staticmethod - def append_name(displayname: str) -> str: - """Adds a suffix to the end of the Discord name.""" - extensions = ["foot", "ear", "nose", "tail"] - suffix = random.choice(extensions) - appended_name = displayname + suffix - - return appended_name - - @commands.command() - async def bunnyname(self, ctx: commands.Context) -> None: - """Picks a random bunny name from a JSON file.""" - await ctx.send(random.choice(BUNNY_NAMES["names"])) - - @commands.command() - async def bunnifyme(self, ctx: commands.Context) -> None: - """Gets your Discord username and bunnifies it.""" - username = ctx.author.display_name - - # If name contains spaces or other separators, get the individual words to randomly bunnify - spaces_in_name = self.find_separators(username) - - # If name contains vowels, see if it matches any of the patterns in this function - # If there are matches, the bunnified name is returned. - vowels_in_name = self.find_vowels(username) - - # Default if the checks above return None - unmatched_name = self.append_name(username) - - if spaces_in_name is not None: - replacements = ["Cotton", "Fluff", "Floof" "Bounce", "Snuffle", "Nibble", "Cuddle", "Velvetpaw", "Carrot"] - word_to_replace = random.choice(spaces_in_name) - substitute = random.choice(replacements) - bunnified_name = username.replace(word_to_replace, substitute) - elif vowels_in_name is not None: - bunnified_name = vowels_in_name - elif unmatched_name: - bunnified_name = unmatched_name - - await ctx.send(bunnified_name) - - -def setup(bot: Bot) -> None: - """Load the Bunny Name Generator Cog.""" - bot.add_cog(BunnyNameGenerator()) diff --git a/bot/exts/easter/earth_photos.py b/bot/exts/easter/earth_photos.py deleted file mode 100644 index f65790af..00000000 --- a/bot/exts/easter/earth_photos.py +++ /dev/null @@ -1,66 +0,0 @@ -import logging - -import discord -from discord.ext import commands - -from bot.bot import Bot -from bot.constants import Colours -from bot.constants import Tokens - -log = logging.getLogger(__name__) - -API_URL = "https://api.unsplash.com/photos/random" - - -class EarthPhotos(commands.Cog): - """This cog contains the command for earth photos.""" - - def __init__(self, bot: Bot): - self.bot = bot - - @commands.command(aliases=("earth",)) - async def earth_photos(self, ctx: commands.Context) -> None: - """Returns a random photo of earth, sourced from Unsplash.""" - async with ctx.typing(): - async with self.bot.http_session.get( - API_URL, - params={"query": "planet_earth", "client_id": Tokens.unsplash_access_key} - ) as r: - jsondata = await r.json() - linksdata = jsondata.get("urls") - embedlink = linksdata.get("regular") - downloadlinksdata = jsondata.get("links") - userdata = jsondata.get("user") - username = userdata.get("name") - userlinks = userdata.get("links") - profile = userlinks.get("html") - # Referral flags - rf = "?utm_source=Sir%20Lancebot&utm_medium=referral" - async with self.bot.http_session.get( - downloadlinksdata.get("download_location"), - params={"client_id": Tokens.unsplash_access_key} - ) as _: - pass - - embed = discord.Embed( - title="Earth Photo", - description="A photo of Earth 🌎 from Unsplash.", - color=Colours.grass_green - ) - embed.set_image(url=embedlink) - embed.add_field( - name="Author", - value=( - f"Photo by [{username}]({profile}{rf}) " - f"on [Unsplash](https://unsplash.com{rf})." - ) - ) - await ctx.send(embed=embed) - - -def setup(bot: Bot) -> None: - """Load the Earth Photos cog.""" - if not Tokens.unsplash_access_key: - log.warning("No Unsplash access key found. Cog not loading.") - return - bot.add_cog(EarthPhotos(bot)) diff --git a/bot/exts/easter/easter_riddle.py b/bot/exts/easter/easter_riddle.py deleted file mode 100644 index 88b3be2f..00000000 --- a/bot/exts/easter/easter_riddle.py +++ /dev/null @@ -1,112 +0,0 @@ -import asyncio -import logging -import random -from json import loads -from pathlib import Path - -import discord -from discord.ext import commands - -from bot.bot import Bot -from bot.constants import Colours, NEGATIVE_REPLIES - -log = logging.getLogger(__name__) - -RIDDLE_QUESTIONS = loads(Path("bot/resources/easter/easter_riddle.json").read_text("utf8")) - -TIMELIMIT = 10 - - -class EasterRiddle(commands.Cog): - """This cog contains the command for the Easter quiz!""" - - def __init__(self, bot: Bot): - self.bot = bot - self.winners = set() - self.correct = "" - self.current_channel = None - - @commands.command(aliases=("riddlemethis", "riddleme")) - async def riddle(self, ctx: commands.Context) -> None: - """ - Gives a random riddle, then provides 2 hints at certain intervals before revealing the answer. - - The duration of the hint interval can be configured by changing the TIMELIMIT constant in this file. - """ - if self.current_channel: - await ctx.send(f"A riddle is already being solved in {self.current_channel.mention}!") - return - - # Don't let users start in a DM - if not ctx.guild: - await ctx.send( - embed=discord.Embed( - title=random.choice(NEGATIVE_REPLIES), - description="You can't start riddles in DMs", - colour=discord.Colour.red() - ) - ) - return - - self.current_channel = ctx.channel - - random_question = random.choice(RIDDLE_QUESTIONS) - question = random_question["question"] - hints = random_question["riddles"] - self.correct = random_question["correct_answer"] - - description = f"You have {TIMELIMIT} seconds before the first hint." - - riddle_embed = discord.Embed(title=question, description=description, colour=Colours.pink) - - await ctx.send(embed=riddle_embed) - await asyncio.sleep(TIMELIMIT) - - hint_embed = discord.Embed( - title=f"Here's a hint: {hints[0]}!", - colour=Colours.pink - ) - - await ctx.send(embed=hint_embed) - await asyncio.sleep(TIMELIMIT) - - hint_embed = discord.Embed( - title=f"Here's a hint: {hints[1]}!", - colour=Colours.pink - ) - - await ctx.send(embed=hint_embed) - await asyncio.sleep(TIMELIMIT) - - if self.winners: - win_list = " ".join(self.winners) - content = f"Well done {win_list} for getting it right!" - else: - content = "Nobody got it right..." - - answer_embed = discord.Embed( - title=f"The answer is: {self.correct}!", - colour=Colours.pink - ) - - await ctx.send(content, embed=answer_embed) - - self.winners.clear() - self.current_channel = None - - @commands.Cog.listener() - async def on_message(self, message: discord.Message) -> None: - """If a non-bot user enters a correct answer, their username gets added to self.winners.""" - if self.current_channel != message.channel: - return - - if self.bot.user == message.author: - return - - if message.content.lower() == self.correct.lower(): - self.winners.add(message.author.mention) - - -def setup(bot: Bot) -> None: - """Easter Riddle Cog load.""" - bot.add_cog(EasterRiddle(bot)) diff --git a/bot/exts/easter/egg_decorating.py b/bot/exts/easter/egg_decorating.py deleted file mode 100644 index fb5701c4..00000000 --- a/bot/exts/easter/egg_decorating.py +++ /dev/null @@ -1,119 +0,0 @@ -import json -import logging -import random -from contextlib import suppress -from io import BytesIO -from pathlib import Path -from typing import Optional, Union - -import discord -from PIL import Image -from discord.ext import commands - -from bot.bot import Bot -from bot.utils import helpers - -log = logging.getLogger(__name__) - -HTML_COLOURS = json.loads(Path("bot/resources/evergreen/html_colours.json").read_text("utf8")) - -XKCD_COLOURS = json.loads(Path("bot/resources/evergreen/xkcd_colours.json").read_text("utf8")) - -COLOURS = [ - (255, 0, 0, 255), (255, 128, 0, 255), (255, 255, 0, 255), (0, 255, 0, 255), - (0, 255, 255, 255), (0, 0, 255, 255), (255, 0, 255, 255), (128, 0, 128, 255) -] # Colours to be replaced - Red, Orange, Yellow, Green, Light Blue, Dark Blue, Pink, Purple - -IRREPLACEABLE = [ - (0, 0, 0, 0), (0, 0, 0, 255) -] # Colours that are meant to stay the same - Transparent and Black - - -class EggDecorating(commands.Cog): - """Decorate some easter eggs!""" - - @staticmethod - def replace_invalid(colour: str) -> Optional[int]: - """Attempts to match with HTML or XKCD colour names, returning the int value.""" - with suppress(KeyError): - return int(HTML_COLOURS[colour], 16) - with suppress(KeyError): - return int(XKCD_COLOURS[colour], 16) - return None - - @commands.command(aliases=("decorateegg",)) - async def eggdecorate( - self, ctx: commands.Context, *colours: Union[discord.Colour, str] - ) -> Optional[Image.Image]: - """ - Picks a random egg design and decorates it using the given colours. - - Colours are split by spaces, unless you wrap the colour name in double quotes. - Discord colour names, HTML colour names, XKCD colour names and hex values are accepted. - """ - if len(colours) < 2: - await ctx.send("You must include at least 2 colours!") - return - - invalid = [] - colours = list(colours) - for idx, colour in enumerate(colours): - if isinstance(colour, discord.Colour): - continue - value = self.replace_invalid(colour) - if value: - colours[idx] = discord.Colour(value) - else: - invalid.append(helpers.suppress_links(colour)) - - if len(invalid) > 1: - await ctx.send(f"Sorry, I don't know these colours: {' '.join(invalid)}") - return - elif len(invalid) == 1: - await ctx.send(f"Sorry, I don't know the colour {invalid[0]}!") - return - - async with ctx.typing(): - # Expand list to 8 colours - colours_n = len(colours) - if colours_n < 8: - q, r = divmod(8, colours_n) - colours = colours * q + colours[:r] - num = random.randint(1, 6) - im = Image.open(Path(f"bot/resources/easter/easter_eggs/design{num}.png")) - data = list(im.getdata()) - - replaceable = {x for x in data if x not in IRREPLACEABLE} - replaceable = sorted(replaceable, key=COLOURS.index) - - replacing_colours = {colour: colours[i] for i, colour in enumerate(replaceable)} - new_data = [] - for x in data: - if x in replacing_colours: - new_data.append((*replacing_colours[x].to_rgb(), 255)) - # Also ensures that the alpha channel has a value - else: - new_data.append(x) - new_im = Image.new(im.mode, im.size) - new_im.putdata(new_data) - - bufferedio = BytesIO() - new_im.save(bufferedio, format="PNG") - - bufferedio.seek(0) - - file = discord.File(bufferedio, filename="egg.png") # Creates file to be used in embed - embed = discord.Embed( - title="Your Colourful Easter Egg", - description="Here is your pretty little egg. Hope you like it!" - ) - embed.set_image(url="attachment://egg.png") - embed.set_footer(text=f"Made by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url) - - await ctx.send(file=file, embed=embed) - return new_im - - -def setup(bot: Bot) -> None: - """Load the Egg decorating Cog.""" - bot.add_cog(EggDecorating()) diff --git a/bot/exts/easter/egg_facts.py b/bot/exts/easter/egg_facts.py deleted file mode 100644 index 486e735f..00000000 --- a/bot/exts/easter/egg_facts.py +++ /dev/null @@ -1,55 +0,0 @@ -import logging -import random -from json import loads -from pathlib import Path - -import discord -from discord.ext import commands - -from bot.bot import Bot -from bot.constants import Channels, Colours, Month -from bot.utils.decorators import seasonal_task - -log = logging.getLogger(__name__) - -EGG_FACTS = loads(Path("bot/resources/easter/easter_egg_facts.json").read_text("utf8")) - - -class EasterFacts(commands.Cog): - """ - A cog contains a command that will return an easter egg fact when called. - - It also contains a background task which sends an easter egg fact in the event channel everyday. - """ - - def __init__(self, bot: Bot): - self.bot = bot - self.daily_fact_task = self.bot.loop.create_task(self.send_egg_fact_daily()) - - @seasonal_task(Month.APRIL) - async def send_egg_fact_daily(self) -> None: - """A background task that sends an easter egg fact in the event channel everyday.""" - await self.bot.wait_until_guild_available() - - channel = self.bot.get_channel(Channels.community_bot_commands) - await channel.send(embed=self.make_embed()) - - @commands.command(name="eggfact", aliases=("fact",)) - async def easter_facts(self, ctx: commands.Context) -> None: - """Get easter egg facts.""" - embed = self.make_embed() - await ctx.send(embed=embed) - - @staticmethod - def make_embed() -> discord.Embed: - """Makes a nice embed for the message to be sent.""" - return discord.Embed( - colour=Colours.soft_red, - title="Easter Egg Fact", - description=random.choice(EGG_FACTS) - ) - - -def setup(bot: Bot) -> None: - """Load the Easter Egg facts Cog.""" - bot.add_cog(EasterFacts(bot)) diff --git a/bot/exts/easter/egghead_quiz.py b/bot/exts/easter/egghead_quiz.py deleted file mode 100644 index ad550567..00000000 --- a/bot/exts/easter/egghead_quiz.py +++ /dev/null @@ -1,118 +0,0 @@ -import asyncio -import logging -import random -from json import loads -from pathlib import Path -from typing import Union - -import discord -from discord.ext import commands - -from bot.bot import Bot -from bot.constants import Colours - -log = logging.getLogger(__name__) - -EGGHEAD_QUESTIONS = loads(Path("bot/resources/easter/egghead_questions.json").read_text("utf8")) - - -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): - self.quiz_messages = {} - - @commands.command(aliases=("eggheadquiz", "easterquiz")) - async def eggquiz(self, ctx: commands.Context) -> None: - """ - 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.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: discord.Message, user: Union[discord.Member, discord.User]) -> bool: - """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: discord.Reaction, user: Union[discord.Member, discord.User]) -> None: - """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: Bot) -> None: - """Load the Egghead Quiz Cog.""" - bot.add_cog(EggheadQuiz()) diff --git a/bot/exts/easter/save_the_planet.py b/bot/exts/easter/save_the_planet.py deleted file mode 100644 index 1bd515f2..00000000 --- a/bot/exts/easter/save_the_planet.py +++ /dev/null @@ -1,25 +0,0 @@ -import json -from pathlib import Path - -from discord import Embed -from discord.ext import commands - -from bot.bot import Bot -from bot.utils.randomization import RandomCycle - -EMBED_DATA = RandomCycle(json.loads(Path("bot/resources/easter/save_the_planet.json").read_text("utf8"))) - - -class SaveThePlanet(commands.Cog): - """A cog that teaches users how they can help our planet.""" - - @commands.command(aliases=("savetheearth", "saveplanet", "saveearth")) - async def savetheplanet(self, ctx: commands.Context) -> None: - """Responds with a random tip on how to be eco-friendly and help our planet.""" - return_embed = Embed.from_dict(next(EMBED_DATA)) - await ctx.send(embed=return_embed) - - -def setup(bot: Bot) -> None: - """Load the Save the Planet Cog.""" - bot.add_cog(SaveThePlanet()) diff --git a/bot/exts/easter/traditions.py b/bot/exts/easter/traditions.py deleted file mode 100644 index 93404f3e..00000000 --- a/bot/exts/easter/traditions.py +++ /dev/null @@ -1,28 +0,0 @@ -import json -import logging -import random -from pathlib import Path - -from discord.ext import commands - -from bot.bot import Bot - -log = logging.getLogger(__name__) - -traditions = json.loads(Path("bot/resources/easter/traditions.json").read_text("utf8")) - - -class Traditions(commands.Cog): - """A cog which allows users to get a random easter tradition or custom from a random country.""" - - @commands.command(aliases=("eastercustoms",)) - async def easter_tradition(self, ctx: commands.Context) -> None: - """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: Bot) -> None: - """Load the Traditions Cog.""" - bot.add_cog(Traditions()) diff --git a/bot/exts/halloween/__init__.py b/bot/exts/halloween/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bot/exts/holidays/__init__.py b/bot/exts/holidays/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bot/exts/holidays/earth_day/__init__.py b/bot/exts/holidays/earth_day/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bot/exts/holidays/earth_day/save_the_planet.py b/bot/exts/holidays/earth_day/save_the_planet.py new file mode 100644 index 00000000..13c84886 --- /dev/null +++ b/bot/exts/holidays/earth_day/save_the_planet.py @@ -0,0 +1,25 @@ +import json +from pathlib import Path + +from discord import Embed +from discord.ext import commands + +from bot.bot import Bot +from bot.utils.randomization import RandomCycle + +EMBED_DATA = RandomCycle(json.loads(Path("bot/resources/holidays/earth_day/save_the_planet.json").read_text("utf8"))) + + +class SaveThePlanet(commands.Cog): + """A cog that teaches users how they can help our planet.""" + + @commands.command(aliases=("savetheearth", "saveplanet", "saveearth")) + async def savetheplanet(self, ctx: commands.Context) -> None: + """Responds with a random tip on how to be eco-friendly and help our planet.""" + return_embed = Embed.from_dict(next(EMBED_DATA)) + await ctx.send(embed=return_embed) + + +def setup(bot: Bot) -> None: + """Load the Save the Planet Cog.""" + bot.add_cog(SaveThePlanet()) diff --git a/bot/exts/holidays/easter/__init__.py b/bot/exts/holidays/easter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bot/exts/holidays/easter/april_fools_vids.py b/bot/exts/holidays/easter/april_fools_vids.py new file mode 100644 index 00000000..ae22f751 --- /dev/null +++ b/bot/exts/holidays/easter/april_fools_vids.py @@ -0,0 +1,30 @@ +import logging +import random +from json import loads +from pathlib import Path + +from discord.ext import commands + +from bot.bot import Bot + +log = logging.getLogger(__name__) + +ALL_VIDS = loads(Path("bot/resources/holidays/easter/april_fools_vids.json").read_text("utf-8")) + + +class AprilFoolVideos(commands.Cog): + """A cog for April Fools' that gets a random April Fools' video from Youtube.""" + + @commands.command(name="fool") + async def april_fools(self, ctx: commands.Context) -> None: + """Get a random April Fools' video from Youtube.""" + video = random.choice(ALL_VIDS) + + channel, url = video["channel"], video["url"] + + await ctx.send(f"Check out this April Fools' video by {channel}.\n\n{url}") + + +def setup(bot: Bot) -> None: + """Load the April Fools' Cog.""" + bot.add_cog(AprilFoolVideos()) diff --git a/bot/exts/holidays/easter/bunny_name_generator.py b/bot/exts/holidays/easter/bunny_name_generator.py new file mode 100644 index 00000000..f767f7c5 --- /dev/null +++ b/bot/exts/holidays/easter/bunny_name_generator.py @@ -0,0 +1,94 @@ +import json +import logging +import random +import re +from pathlib import Path +from typing import Optional + +from discord.ext import commands + +from bot.bot import Bot + +log = logging.getLogger(__name__) + +BUNNY_NAMES = json.loads(Path("bot/resources/holidays/easter/bunny_names.json").read_text("utf8")) + + +class BunnyNameGenerator(commands.Cog): + """Generate a random bunny name, or bunnify your Discord username!""" + + @staticmethod + def find_separators(displayname: str) -> Optional[list[str]]: + """Check if Discord name contains spaces so we can bunnify an individual word in the name.""" + new_name = re.split(r"[_.\s]", displayname) + if displayname not in new_name: + return new_name + return None + + @staticmethod + def find_vowels(displayname: str) -> Optional[str]: + """ + Finds vowels in the user's display name. + + If the Discord name contains a vowel and the letter y, it will match one or more of these patterns. + + Only the most recently matched pattern will apply the changes. + """ + expressions = [ + ("a.+y", "patchy"), + ("e.+y", "ears"), + ("i.+y", "ditsy"), + ("o.+y", "oofy"), + ("u.+y", "uffy"), + ] + + for exp, vowel_sub in expressions: + new_name = re.sub(exp, vowel_sub, displayname) + if new_name != displayname: + return new_name + + @staticmethod + def append_name(displayname: str) -> str: + """Adds a suffix to the end of the Discord name.""" + extensions = ["foot", "ear", "nose", "tail"] + suffix = random.choice(extensions) + appended_name = displayname + suffix + + return appended_name + + @commands.command() + async def bunnyname(self, ctx: commands.Context) -> None: + """Picks a random bunny name from a JSON file.""" + await ctx.send(random.choice(BUNNY_NAMES["names"])) + + @commands.command() + async def bunnifyme(self, ctx: commands.Context) -> None: + """Gets your Discord username and bunnifies it.""" + username = ctx.author.display_name + + # If name contains spaces or other separators, get the individual words to randomly bunnify + spaces_in_name = self.find_separators(username) + + # If name contains vowels, see if it matches any of the patterns in this function + # If there are matches, the bunnified name is returned. + vowels_in_name = self.find_vowels(username) + + # Default if the checks above return None + unmatched_name = self.append_name(username) + + if spaces_in_name is not None: + replacements = ["Cotton", "Fluff", "Floof" "Bounce", "Snuffle", "Nibble", "Cuddle", "Velvetpaw", "Carrot"] + word_to_replace = random.choice(spaces_in_name) + substitute = random.choice(replacements) + bunnified_name = username.replace(word_to_replace, substitute) + elif vowels_in_name is not None: + bunnified_name = vowels_in_name + elif unmatched_name: + bunnified_name = unmatched_name + + await ctx.send(bunnified_name) + + +def setup(bot: Bot) -> None: + """Load the Bunny Name Generator Cog.""" + bot.add_cog(BunnyNameGenerator()) diff --git a/bot/exts/holidays/easter/earth_photos.py b/bot/exts/holidays/easter/earth_photos.py new file mode 100644 index 00000000..f65790af --- /dev/null +++ b/bot/exts/holidays/easter/earth_photos.py @@ -0,0 +1,66 @@ +import logging + +import discord +from discord.ext import commands + +from bot.bot import Bot +from bot.constants import Colours +from bot.constants import Tokens + +log = logging.getLogger(__name__) + +API_URL = "https://api.unsplash.com/photos/random" + + +class EarthPhotos(commands.Cog): + """This cog contains the command for earth photos.""" + + def __init__(self, bot: Bot): + self.bot = bot + + @commands.command(aliases=("earth",)) + async def earth_photos(self, ctx: commands.Context) -> None: + """Returns a random photo of earth, sourced from Unsplash.""" + async with ctx.typing(): + async with self.bot.http_session.get( + API_URL, + params={"query": "planet_earth", "client_id": Tokens.unsplash_access_key} + ) as r: + jsondata = await r.json() + linksdata = jsondata.get("urls") + embedlink = linksdata.get("regular") + downloadlinksdata = jsondata.get("links") + userdata = jsondata.get("user") + username = userdata.get("name") + userlinks = userdata.get("links") + profile = userlinks.get("html") + # Referral flags + rf = "?utm_source=Sir%20Lancebot&utm_medium=referral" + async with self.bot.http_session.get( + downloadlinksdata.get("download_location"), + params={"client_id": Tokens.unsplash_access_key} + ) as _: + pass + + embed = discord.Embed( + title="Earth Photo", + description="A photo of Earth 🌎 from Unsplash.", + color=Colours.grass_green + ) + embed.set_image(url=embedlink) + embed.add_field( + name="Author", + value=( + f"Photo by [{username}]({profile}{rf}) " + f"on [Unsplash](https://unsplash.com{rf})." + ) + ) + await ctx.send(embed=embed) + + +def setup(bot: Bot) -> None: + """Load the Earth Photos cog.""" + if not Tokens.unsplash_access_key: + log.warning("No Unsplash access key found. Cog not loading.") + return + bot.add_cog(EarthPhotos(bot)) diff --git a/bot/exts/holidays/easter/easter_riddle.py b/bot/exts/holidays/easter/easter_riddle.py new file mode 100644 index 00000000..c9b7fc53 --- /dev/null +++ b/bot/exts/holidays/easter/easter_riddle.py @@ -0,0 +1,112 @@ +import asyncio +import logging +import random +from json import loads +from pathlib import Path + +import discord +from discord.ext import commands + +from bot.bot import Bot +from bot.constants import Colours, NEGATIVE_REPLIES + +log = logging.getLogger(__name__) + +RIDDLE_QUESTIONS = loads(Path("bot/resources/holidays/easter/easter_riddle.json").read_text("utf8")) + +TIMELIMIT = 10 + + +class EasterRiddle(commands.Cog): + """This cog contains the command for the Easter quiz!""" + + def __init__(self, bot: Bot): + self.bot = bot + self.winners = set() + self.correct = "" + self.current_channel = None + + @commands.command(aliases=("riddlemethis", "riddleme")) + async def riddle(self, ctx: commands.Context) -> None: + """ + Gives a random riddle, then provides 2 hints at certain intervals before revealing the answer. + + The duration of the hint interval can be configured by changing the TIMELIMIT constant in this file. + """ + if self.current_channel: + await ctx.send(f"A riddle is already being solved in {self.current_channel.mention}!") + return + + # Don't let users start in a DM + if not ctx.guild: + await ctx.send( + embed=discord.Embed( + title=random.choice(NEGATIVE_REPLIES), + description="You can't start riddles in DMs", + colour=discord.Colour.red() + ) + ) + return + + self.current_channel = ctx.channel + + random_question = random.choice(RIDDLE_QUESTIONS) + question = random_question["question"] + hints = random_question["riddles"] + self.correct = random_question["correct_answer"] + + description = f"You have {TIMELIMIT} seconds before the first hint." + + riddle_embed = discord.Embed(title=question, description=description, colour=Colours.pink) + + await ctx.send(embed=riddle_embed) + await asyncio.sleep(TIMELIMIT) + + hint_embed = discord.Embed( + title=f"Here's a hint: {hints[0]}!", + colour=Colours.pink + ) + + await ctx.send(embed=hint_embed) + await asyncio.sleep(TIMELIMIT) + + hint_embed = discord.Embed( + title=f"Here's a hint: {hints[1]}!", + colour=Colours.pink + ) + + await ctx.send(embed=hint_embed) + await asyncio.sleep(TIMELIMIT) + + if self.winners: + win_list = " ".join(self.winners) + content = f"Well done {win_list} for getting it right!" + else: + content = "Nobody got it right..." + + answer_embed = discord.Embed( + title=f"The answer is: {self.correct}!", + colour=Colours.pink + ) + + await ctx.send(content, embed=answer_embed) + + self.winners.clear() + self.current_channel = None + + @commands.Cog.listener() + async def on_message(self, message: discord.Message) -> None: + """If a non-bot user enters a correct answer, their username gets added to self.winners.""" + if self.current_channel != message.channel: + return + + if self.bot.user == message.author: + return + + if message.content.lower() == self.correct.lower(): + self.winners.add(message.author.mention) + + +def setup(bot: Bot) -> None: + """Easter Riddle Cog load.""" + bot.add_cog(EasterRiddle(bot)) diff --git a/bot/exts/holidays/easter/egg_decorating.py b/bot/exts/holidays/easter/egg_decorating.py new file mode 100644 index 00000000..1db9b347 --- /dev/null +++ b/bot/exts/holidays/easter/egg_decorating.py @@ -0,0 +1,119 @@ +import json +import logging +import random +from contextlib import suppress +from io import BytesIO +from pathlib import Path +from typing import Optional, Union + +import discord +from PIL import Image +from discord.ext import commands + +from bot.bot import Bot +from bot.utils import helpers + +log = logging.getLogger(__name__) + +HTML_COLOURS = json.loads(Path("bot/resources/fun/html_colours.json").read_text("utf8")) + +XKCD_COLOURS = json.loads(Path("bot/resources/fun/xkcd_colours.json").read_text("utf8")) + +COLOURS = [ + (255, 0, 0, 255), (255, 128, 0, 255), (255, 255, 0, 255), (0, 255, 0, 255), + (0, 255, 255, 255), (0, 0, 255, 255), (255, 0, 255, 255), (128, 0, 128, 255) +] # Colours to be replaced - Red, Orange, Yellow, Green, Light Blue, Dark Blue, Pink, Purple + +IRREPLACEABLE = [ + (0, 0, 0, 0), (0, 0, 0, 255) +] # Colours that are meant to stay the same - Transparent and Black + + +class EggDecorating(commands.Cog): + """Decorate some easter eggs!""" + + @staticmethod + def replace_invalid(colour: str) -> Optional[int]: + """Attempts to match with HTML or XKCD colour names, returning the int value.""" + with suppress(KeyError): + return int(HTML_COLOURS[colour], 16) + with suppress(KeyError): + return int(XKCD_COLOURS[colour], 16) + return None + + @commands.command(aliases=("decorateegg",)) + async def eggdecorate( + self, ctx: commands.Context, *colours: Union[discord.Colour, str] + ) -> Optional[Image.Image]: + """ + Picks a random egg design and decorates it using the given colours. + + Colours are split by spaces, unless you wrap the colour name in double quotes. + Discord colour names, HTML colour names, XKCD colour names and hex values are accepted. + """ + if len(colours) < 2: + await ctx.send("You must include at least 2 colours!") + return + + invalid = [] + colours = list(colours) + for idx, colour in enumerate(colours): + if isinstance(colour, discord.Colour): + continue + value = self.replace_invalid(colour) + if value: + colours[idx] = discord.Colour(value) + else: + invalid.append(helpers.suppress_links(colour)) + + if len(invalid) > 1: + await ctx.send(f"Sorry, I don't know these colours: {' '.join(invalid)}") + return + elif len(invalid) == 1: + await ctx.send(f"Sorry, I don't know the colour {invalid[0]}!") + return + + async with ctx.typing(): + # Expand list to 8 colours + colours_n = len(colours) + if colours_n < 8: + q, r = divmod(8, colours_n) + colours = colours * q + colours[:r] + num = random.randint(1, 6) + im = Image.open(Path(f"bot/resources/holidays/easter/easter_eggs/design{num}.png")) + data = list(im.getdata()) + + replaceable = {x for x in data if x not in IRREPLACEABLE} + replaceable = sorted(replaceable, key=COLOURS.index) + + replacing_colours = {colour: colours[i] for i, colour in enumerate(replaceable)} + new_data = [] + for x in data: + if x in replacing_colours: + new_data.append((*replacing_colours[x].to_rgb(), 255)) + # Also ensures that the alpha channel has a value + else: + new_data.append(x) + new_im = Image.new(im.mode, im.size) + new_im.putdata(new_data) + + bufferedio = BytesIO() + new_im.save(bufferedio, format="PNG") + + bufferedio.seek(0) + + file = discord.File(bufferedio, filename="egg.png") # Creates file to be used in embed + embed = discord.Embed( + title="Your Colourful Easter Egg", + description="Here is your pretty little egg. Hope you like it!" + ) + embed.set_image(url="attachment://egg.png") + embed.set_footer(text=f"Made by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url) + + await ctx.send(file=file, embed=embed) + return new_im + + +def setup(bot: Bot) -> None: + """Load the Egg decorating Cog.""" + bot.add_cog(EggDecorating()) diff --git a/bot/exts/holidays/easter/egg_facts.py b/bot/exts/holidays/easter/egg_facts.py new file mode 100644 index 00000000..5f216e0d --- /dev/null +++ b/bot/exts/holidays/easter/egg_facts.py @@ -0,0 +1,55 @@ +import logging +import random +from json import loads +from pathlib import Path + +import discord +from discord.ext import commands + +from bot.bot import Bot +from bot.constants import Channels, Colours, Month +from bot.utils.decorators import seasonal_task + +log = logging.getLogger(__name__) + +EGG_FACTS = loads(Path("bot/resources/holidays/easter/easter_egg_facts.json").read_text("utf8")) + + +class EasterFacts(commands.Cog): + """ + A cog contains a command that will return an easter egg fact when called. + + It also contains a background task which sends an easter egg fact in the event channel everyday. + """ + + def __init__(self, bot: Bot): + self.bot = bot + self.daily_fact_task = self.bot.loop.create_task(self.send_egg_fact_daily()) + + @seasonal_task(Month.APRIL) + async def send_egg_fact_daily(self) -> None: + """A background task that sends an easter egg fact in the event channel everyday.""" + await self.bot.wait_until_guild_available() + + channel = self.bot.get_channel(Channels.community_bot_commands) + await channel.send(embed=self.make_embed()) + + @commands.command(name="eggfact", aliases=("fact",)) + async def easter_facts(self, ctx: commands.Context) -> None: + """Get easter egg facts.""" + embed = self.make_embed() + await ctx.send(embed=embed) + + @staticmethod + def make_embed() -> discord.Embed: + """Makes a nice embed for the message to be sent.""" + return discord.Embed( + colour=Colours.soft_red, + title="Easter Egg Fact", + description=random.choice(EGG_FACTS) + ) + + +def setup(bot: Bot) -> None: + """Load the Easter Egg facts Cog.""" + bot.add_cog(EasterFacts(bot)) diff --git a/bot/exts/holidays/easter/egghead_quiz.py b/bot/exts/holidays/easter/egghead_quiz.py new file mode 100644 index 00000000..06229537 --- /dev/null +++ b/bot/exts/holidays/easter/egghead_quiz.py @@ -0,0 +1,118 @@ +import asyncio +import logging +import random +from json import loads +from pathlib import Path +from typing import Union + +import discord +from discord.ext import commands + +from bot.bot import Bot +from bot.constants import Colours + +log = logging.getLogger(__name__) + +EGGHEAD_QUESTIONS = loads(Path("bot/resources/holidays/easter/egghead_questions.json").read_text("utf8")) + + +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): + self.quiz_messages = {} + + @commands.command(aliases=("eggheadquiz", "easterquiz")) + async def eggquiz(self, ctx: commands.Context) -> None: + """ + 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.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: discord.Message, user: Union[discord.Member, discord.User]) -> bool: + """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: discord.Reaction, user: Union[discord.Member, discord.User]) -> None: + """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: Bot) -> None: + """Load the Egghead Quiz Cog.""" + bot.add_cog(EggheadQuiz()) diff --git a/bot/exts/holidays/easter/traditions.py b/bot/exts/holidays/easter/traditions.py new file mode 100644 index 00000000..f54ab5c4 --- /dev/null +++ b/bot/exts/holidays/easter/traditions.py @@ -0,0 +1,28 @@ +import json +import logging +import random +from pathlib import Path + +from discord.ext import commands + +from bot.bot import Bot + +log = logging.getLogger(__name__) + +traditions = json.loads(Path("bot/resources/holidays/easter/traditions.json").read_text("utf8")) + + +class Traditions(commands.Cog): + """A cog which allows users to get a random easter tradition or custom from a random country.""" + + @commands.command(aliases=("eastercustoms",)) + async def easter_tradition(self, ctx: commands.Context) -> None: + """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: Bot) -> None: + """Load the Traditions Cog.""" + bot.add_cog(Traditions()) diff --git a/bot/exts/pride/__init__.py b/bot/exts/pride/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bot/resources/easter/april_fools_vids.json b/bot/resources/easter/april_fools_vids.json deleted file mode 100644 index e1e8c70a..00000000 --- a/bot/resources/easter/april_fools_vids.json +++ /dev/null @@ -1,130 +0,0 @@ -[ - { - "url": "https://youtu.be/OYcv406J_J4", - "channel": "google" - }, - { - "url": "https://youtu.be/0_5X6N6DHyk", - "channel": "google" - }, - { - "url": "https://youtu.be/UmJ2NBHXTqo", - "channel": "google" - }, - { - "url": "https://youtu.be/3MA6_21nka8", - "channel": "google" - }, - { - "url": "https://youtu.be/QAwL0O5nXe0", - "channel": "google" - }, - { - "url": "https://youtu.be/DPEJB-FCItk", - "channel": "google" - }, - { - "url": "https://youtu.be/LSZPNwZex9s", - "channel": "google" - }, - { - "url": "https://youtu.be/dFrgNiweQDk", - "channel": "google" - }, - { - "url": "https://youtu.be/F0F6SnbqUcE", - "channel": "google" - }, - { - "url": "https://youtu.be/VkOuShXpoKc", - "channel": "google" - }, - { - "url": "https://youtu.be/HQtGFBbwKEk", - "channel": "google" - }, - { - "url": "https://youtu.be/Cp10_PygJ4o", - "channel": "google" - }, - { - "url": "https://youtu.be/XTTtkisylQw", - "channel": "google" - }, - { - "url": "https://youtu.be/hydLZJXG3Tk", - "channel": "google" - }, - { - "url": "https://youtu.be/U2JBFlW--UU", - "channel": "google" - }, - { - "url": "https://youtu.be/G3NXNnoGr3Y", - "channel": "google" - }, - { - "url": "https://youtu.be/4YMD6xELI_k", - "channel": "google" - }, - { - "url": "https://youtu.be/qcgWRpQP6ds", - "channel": "google" - }, - { - "url": "https://youtu.be/Zr4JwPb99qU", - "channel": "google" - }, - { - "url": "https://youtu.be/VFbYadm_mrw", - "channel": "google" - }, - { - "url": "https://youtu.be/_qFFHC0eIUc", - "channel": "google" - }, - { - "url": "https://youtu.be/H542nLTTbu0", - "channel": "google" - }, - { - "url": "https://youtu.be/Je7Xq9tdCJc", - "channel": "google" - }, - { - "url": "https://youtu.be/re0VRK6ouwI", - "channel": "google" - }, - { - "url": "https://youtu.be/1KhZKNZO8mQ", - "channel": "google" - }, - { - "url": "https://youtu.be/UiLSiqyDf4Y", - "channel": "google" - }, - { - "url": "https://youtu.be/rznYifPHxDg", - "channel": "google" - }, - { - "url": "https://youtu.be/blB_X38YSxQ", - "channel": "google" - }, - { - "url": "https://youtu.be/Bu927_ul_X0", - "channel": "google" - }, - { - "url": "https://youtu.be/smM-Wdk2RLQ", - "channel": "nvidia" - }, - { - "url": "https://youtu.be/IlCx5gjAmqI", - "channel": "razer" - }, - { - "url": "https://youtu.be/j8UJE7DoyJ8", - "channel": "razer" - } -] diff --git a/bot/resources/easter/bunny_names.json b/bot/resources/easter/bunny_names.json deleted file mode 100644 index 8c97169c..00000000 --- a/bot/resources/easter/bunny_names.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "names": [ - "Flopsy", - "Hopsalot", - "Thumper", - "Nibbles", - "Daisy", - "Fuzzy", - "Cottontail", - "Carrot Top", - "Marshmallow", - "Lucky", - "Clover", - "Daffodil", - "Buttercup", - "Goldie", - "Dizzy", - "Trixie", - "Snuffles", - "Hopscotch", - "Skipper", - "Thunderfoot", - "Bigwig", - "Dandelion", - "Pipkin", - "Buckthorn", - "Skipper" - ] -} diff --git a/bot/resources/easter/chocolate_bunny.png b/bot/resources/easter/chocolate_bunny.png deleted file mode 100644 index 6b25aa5a..00000000 Binary files a/bot/resources/easter/chocolate_bunny.png and /dev/null differ diff --git a/bot/resources/easter/easter_egg_facts.json b/bot/resources/easter/easter_egg_facts.json deleted file mode 100644 index b0650b84..00000000 --- a/bot/resources/easter/easter_egg_facts.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - "The first story of a rabbit (later named the \"Easter Bunny\") hiding eggs in a garden was published in 1680.", - "Rabbits are known to be prolific pro creators and are an ancient symbol of fertility and new life. The German immigrants brought the tale of Easter Bunny in the 1700s with the tradition of an egg-laying hare called \"Osterhase\". The kids then would make nests in which the creature would lay coloured eggs. The tradition has been revolutionized in the form of candies and gifts instead of eggs.", - "In earlier days, a festival of egg throwing was held in church, when the priest would throw a hard-boiled egg to one of the choirboys. It was then tossed from one choirboy to the next and whoever held the egg when the clock struck 12 on Easter, was the winner and could keep it.", - "In medieval times, Easter eggs were boiled with onions to give them a golden sheen. Edward I went beyond this tradition in 1290 and ordered 450 eggs to be covered in gold leaf and given as Easter gifts.", - "Decorating Easter eggs is an ancient tradition that dates back to 13th century. One of the explanations for this custom is that eggs were considered as a forbidden food during the Lenten season (40 days before Easter). Therefore, people would paint and decorate them to mark an end of the period of penance and fasting and later eat them on Easter. The tradition of decorating eggs is called Pysanka which is creating a traditional Ukrainian folk design using wax-resist method.", - "Members of the Greek Orthodox faith often paint their Easter eggs red, which symbolizes Jesus' blood and his victory over death. The color red, symbolizes renewal of life, such as, Jesus' resurrection.", - "Eggs rolling take place in many parts of the world which symbolizes stone which was rolled away from the tomb where Jesus' body was laid after his death.", - "Easter eggs have been considered as a symbol of fertility, rebirth and new life. The custom of giving eggs has been derived from Egyptians, Persians, Gauls, Greeks, and Romans.", - "The first chocolate Easter egg was made by Fry's in 1873. Before this, people would give hollow cardboard eggs, filled with gifts.", - "The tallest chocolate Easter egg was made in Italy in 2011. Standing 10.39 metres tall and weighing 7,200 kg, it was taller than a giraffe and heavier than an elephant.", - "The largest ever Easter egg hunt was in Florida, where 9,753 children searched for 501,000 eggs.", - "In 2007, an Easter egg covered in diamonds sold for almost £9 million. Every hour, a cockerel made of jewels pops up from the top of the Faberge egg, flaps its wings four times, nods its head three times and makes a crowing noise. The gold-and-pink enamel egg was made by the Russian royal family as an engagement gift for French aristocrat Baron Edouard de Rothschild.", - "The White House held their first official egg roll in 1878 when Rutherford B. Hayes was the President. It is a race in which children push decorated, hard-boiled eggs across the White House lawn as an annual event held the Monday after Easter. In 2009, the Obamas hosted their first Easter egg roll with the theme, \"Let's go play\" which was meant to encourage young people to lead healthy and active lives.", - "80 million chocolate Easter eggs are sold each year. This accounts for 10% of Britain's annual spending on chocolate!", - "John Cadbury soon followed suit and made his first Cadbury Easter egg in 1875. By 1892 the company was producing 19 different lines, all made from dark chocolate." -] diff --git a/bot/resources/easter/easter_eggs/design1.png b/bot/resources/easter/easter_eggs/design1.png deleted file mode 100644 index d887c590..00000000 Binary files a/bot/resources/easter/easter_eggs/design1.png and /dev/null differ diff --git a/bot/resources/easter/easter_eggs/design2.png b/bot/resources/easter/easter_eggs/design2.png deleted file mode 100644 index c4fff644..00000000 Binary files a/bot/resources/easter/easter_eggs/design2.png and /dev/null differ diff --git a/bot/resources/easter/easter_eggs/design3.png b/bot/resources/easter/easter_eggs/design3.png deleted file mode 100644 index 803bc1e3..00000000 Binary files a/bot/resources/easter/easter_eggs/design3.png and /dev/null differ diff --git a/bot/resources/easter/easter_eggs/design4.png b/bot/resources/easter/easter_eggs/design4.png deleted file mode 100644 index 38e6a83f..00000000 Binary files a/bot/resources/easter/easter_eggs/design4.png and /dev/null differ diff --git a/bot/resources/easter/easter_eggs/design5.png b/bot/resources/easter/easter_eggs/design5.png deleted file mode 100644 index 56662c26..00000000 Binary files a/bot/resources/easter/easter_eggs/design5.png and /dev/null differ diff --git a/bot/resources/easter/easter_eggs/design6.png b/bot/resources/easter/easter_eggs/design6.png deleted file mode 100644 index 5372439a..00000000 Binary files a/bot/resources/easter/easter_eggs/design6.png and /dev/null differ diff --git a/bot/resources/easter/easter_riddle.json b/bot/resources/easter/easter_riddle.json deleted file mode 100644 index f7eb63d8..00000000 --- a/bot/resources/easter/easter_riddle.json +++ /dev/null @@ -1,74 +0,0 @@ -[ - { - "question": "What kind of music do bunnies like?", - "riddles": [ - "Two words", - "Jump to the beat" - ], - "correct_answer": "Hip hop" - }, - { - "question": "What kind of jewelry do rabbits wear?", - "riddles": [ - "They can eat it too", - "14 ___ gold" - ], - "correct_answer": "14 carrot gold" - }, - { - "question": "What does the easter bunny get for making a basket?", - "riddles": [ - "KOBE!", - "1+1 = ?" - ], - "correct_answer": "2 points" - }, - { - "question": "Where does the easter bunny eat breakfast?", - "riddles": [ - "No waffles here", - "An international home" - ], - "correct_answer": "IHOP" - }, - { - "question": "What do you call a rabbit with fleas?", - "riddles": [ - "A bit of a looney tune", - "What's up Doc?" - ], - "correct_answer": "Bugs Bunny" - }, - { - "question": "Why was the little girl sad after the race?", - "riddles": [ - "2nd place?", - "Who beat her?" - ], - "correct_answer": "Because an egg beater" - }, - { - "question": "What happened to the Easter Bunny when he misbehaved at school?", - "riddles": [ - "Won't be back anymore", - "Worse than suspension" - ], - "correct_answer": "He was eggspelled" - }, - { - "question": "What kind of bunny can't hop?", - "riddles": [ - "Might melt in the sun", - "Fragile and yummy" - ], - "correct_answer": "A chocolate one" - }, - { - "question": "Why did the Easter Bunny have to fire the duck?", - "riddles": [ - "Quack", - "MY EGGS!!" - ], - "correct_answer": "He kept quacking the eggs" - } -] diff --git a/bot/resources/easter/egghead_questions.json b/bot/resources/easter/egghead_questions.json deleted file mode 100644 index 5535f8e0..00000000 --- a/bot/resources/easter/egghead_questions.json +++ /dev/null @@ -1,181 +0,0 @@ -[ - { - "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": 3 - }, - { - "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 - } -] diff --git a/bot/resources/easter/save_the_planet.json b/bot/resources/easter/save_the_planet.json deleted file mode 100644 index f22261b7..00000000 --- a/bot/resources/easter/save_the_planet.json +++ /dev/null @@ -1,77 +0,0 @@ -[ - { - "title": "Choose renewable energy", - "image": {"url": "https://cdn.dnaindia.com/sites/default/files/styles/full/public/2019/07/23/851602-renewable-energy-istock-072419.jpg"}, - "footer": {"text": "Help out by sharing this information!"}, - "fields": [ - { - "name": "The problem", - "value": "Getting energy from oil or fossil fuels isn't a good idea, because there is only so much of it.", - "inline": false - }, - - { - "name": "What you can do", - "value": "Use renewable energy, such as wind, solar, and hydro, because it is healthier and is not a finite resource!", - "inline": false - } - ] - }, - - { - "title": "Save the trees!", - "image": {"url": "https://www.thecollegesolution.com/wp-content/uploads/2014/07/crumpled-paper-1.jpg"}, - "footer": {"text": "Help out by sharing this information!"}, - "fields": [ - { - "name": "The problem", - "value": "We often waste trees on making paper, and just getting rid of them for no good reason.", - "inline": false - }, - - { - "name": "What you can do", - "value": "Make sure you only use paper when absolutely necessary. When you do, make sure to use recycled paper because making new paper causes pollution. Find ways to plant trees (Hacktober Fest!) to combat losing them.", - "inline": false - } - ] - }, - - { - "title": "Less time in the car!", - "image": {"url": "https://www.careeraddict.com/uploads/article/55294/businessman-riding-bike.jpg"}, - "footer": {"text": "Help out by sharing this information!"}, - "fields": [ - { - "name": "The problem", - "value": "Every mile you drive to work produces about a pound of C0₂. That's crazy! What's crazier is how clean the planet could be if we spent less time in the car!", - "inline": false - }, - - { - "name": "What you can do", - "value": "Instead of using your car, ride your bike if possible! Not only does it save that pound of C0₂, it is also great exercise and is cheaper!", - "inline": false - } - ] - }, - - { - "title":"Paint your roof white!", - "image": {"url": "https://modernize.com/wp-content/uploads/2016/10/Cool-roof.jpg"}, - "footer": {"text":"Help out by sharing this information!"}, - "fields": [ - { - "name": "The problem", - "value": "People with dark roofs often spend 20 to 40% more on their electricity bills because of the extra heat, which means more electricity needs to be made, and a lot of it isn't renewable.", - "inline": false - }, - - { - "name":"What you can do", - "value": "Having a light colored roof will save you money, and also researchers at the Lawrence Berkeley National Laboratory estimated that if 80 percent of roofs in tropical and temperate climate areas were painted white, it could offset the greenhouse gas emissions of 300 million automobiles around the world.", - "inline": false - } - ] - } -] diff --git a/bot/resources/easter/traditions.json b/bot/resources/easter/traditions.json deleted file mode 100644 index f9dd6d81..00000000 --- a/bot/resources/easter/traditions.json +++ /dev/null @@ -1,13 +0,0 @@ -{"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/holidays/earth_day/save_the_planet.json b/bot/resources/holidays/earth_day/save_the_planet.json new file mode 100644 index 00000000..f22261b7 --- /dev/null +++ b/bot/resources/holidays/earth_day/save_the_planet.json @@ -0,0 +1,77 @@ +[ + { + "title": "Choose renewable energy", + "image": {"url": "https://cdn.dnaindia.com/sites/default/files/styles/full/public/2019/07/23/851602-renewable-energy-istock-072419.jpg"}, + "footer": {"text": "Help out by sharing this information!"}, + "fields": [ + { + "name": "The problem", + "value": "Getting energy from oil or fossil fuels isn't a good idea, because there is only so much of it.", + "inline": false + }, + + { + "name": "What you can do", + "value": "Use renewable energy, such as wind, solar, and hydro, because it is healthier and is not a finite resource!", + "inline": false + } + ] + }, + + { + "title": "Save the trees!", + "image": {"url": "https://www.thecollegesolution.com/wp-content/uploads/2014/07/crumpled-paper-1.jpg"}, + "footer": {"text": "Help out by sharing this information!"}, + "fields": [ + { + "name": "The problem", + "value": "We often waste trees on making paper, and just getting rid of them for no good reason.", + "inline": false + }, + + { + "name": "What you can do", + "value": "Make sure you only use paper when absolutely necessary. When you do, make sure to use recycled paper because making new paper causes pollution. Find ways to plant trees (Hacktober Fest!) to combat losing them.", + "inline": false + } + ] + }, + + { + "title": "Less time in the car!", + "image": {"url": "https://www.careeraddict.com/uploads/article/55294/businessman-riding-bike.jpg"}, + "footer": {"text": "Help out by sharing this information!"}, + "fields": [ + { + "name": "The problem", + "value": "Every mile you drive to work produces about a pound of C0₂. That's crazy! What's crazier is how clean the planet could be if we spent less time in the car!", + "inline": false + }, + + { + "name": "What you can do", + "value": "Instead of using your car, ride your bike if possible! Not only does it save that pound of C0₂, it is also great exercise and is cheaper!", + "inline": false + } + ] + }, + + { + "title":"Paint your roof white!", + "image": {"url": "https://modernize.com/wp-content/uploads/2016/10/Cool-roof.jpg"}, + "footer": {"text":"Help out by sharing this information!"}, + "fields": [ + { + "name": "The problem", + "value": "People with dark roofs often spend 20 to 40% more on their electricity bills because of the extra heat, which means more electricity needs to be made, and a lot of it isn't renewable.", + "inline": false + }, + + { + "name":"What you can do", + "value": "Having a light colored roof will save you money, and also researchers at the Lawrence Berkeley National Laboratory estimated that if 80 percent of roofs in tropical and temperate climate areas were painted white, it could offset the greenhouse gas emissions of 300 million automobiles around the world.", + "inline": false + } + ] + } +] diff --git a/bot/resources/holidays/easter/april_fools_vids.json b/bot/resources/holidays/easter/april_fools_vids.json new file mode 100644 index 00000000..e1e8c70a --- /dev/null +++ b/bot/resources/holidays/easter/april_fools_vids.json @@ -0,0 +1,130 @@ +[ + { + "url": "https://youtu.be/OYcv406J_J4", + "channel": "google" + }, + { + "url": "https://youtu.be/0_5X6N6DHyk", + "channel": "google" + }, + { + "url": "https://youtu.be/UmJ2NBHXTqo", + "channel": "google" + }, + { + "url": "https://youtu.be/3MA6_21nka8", + "channel": "google" + }, + { + "url": "https://youtu.be/QAwL0O5nXe0", + "channel": "google" + }, + { + "url": "https://youtu.be/DPEJB-FCItk", + "channel": "google" + }, + { + "url": "https://youtu.be/LSZPNwZex9s", + "channel": "google" + }, + { + "url": "https://youtu.be/dFrgNiweQDk", + "channel": "google" + }, + { + "url": "https://youtu.be/F0F6SnbqUcE", + "channel": "google" + }, + { + "url": "https://youtu.be/VkOuShXpoKc", + "channel": "google" + }, + { + "url": "https://youtu.be/HQtGFBbwKEk", + "channel": "google" + }, + { + "url": "https://youtu.be/Cp10_PygJ4o", + "channel": "google" + }, + { + "url": "https://youtu.be/XTTtkisylQw", + "channel": "google" + }, + { + "url": "https://youtu.be/hydLZJXG3Tk", + "channel": "google" + }, + { + "url": "https://youtu.be/U2JBFlW--UU", + "channel": "google" + }, + { + "url": "https://youtu.be/G3NXNnoGr3Y", + "channel": "google" + }, + { + "url": "https://youtu.be/4YMD6xELI_k", + "channel": "google" + }, + { + "url": "https://youtu.be/qcgWRpQP6ds", + "channel": "google" + }, + { + "url": "https://youtu.be/Zr4JwPb99qU", + "channel": "google" + }, + { + "url": "https://youtu.be/VFbYadm_mrw", + "channel": "google" + }, + { + "url": "https://youtu.be/_qFFHC0eIUc", + "channel": "google" + }, + { + "url": "https://youtu.be/H542nLTTbu0", + "channel": "google" + }, + { + "url": "https://youtu.be/Je7Xq9tdCJc", + "channel": "google" + }, + { + "url": "https://youtu.be/re0VRK6ouwI", + "channel": "google" + }, + { + "url": "https://youtu.be/1KhZKNZO8mQ", + "channel": "google" + }, + { + "url": "https://youtu.be/UiLSiqyDf4Y", + "channel": "google" + }, + { + "url": "https://youtu.be/rznYifPHxDg", + "channel": "google" + }, + { + "url": "https://youtu.be/blB_X38YSxQ", + "channel": "google" + }, + { + "url": "https://youtu.be/Bu927_ul_X0", + "channel": "google" + }, + { + "url": "https://youtu.be/smM-Wdk2RLQ", + "channel": "nvidia" + }, + { + "url": "https://youtu.be/IlCx5gjAmqI", + "channel": "razer" + }, + { + "url": "https://youtu.be/j8UJE7DoyJ8", + "channel": "razer" + } +] diff --git a/bot/resources/holidays/easter/bunny_names.json b/bot/resources/holidays/easter/bunny_names.json new file mode 100644 index 00000000..8c97169c --- /dev/null +++ b/bot/resources/holidays/easter/bunny_names.json @@ -0,0 +1,29 @@ +{ + "names": [ + "Flopsy", + "Hopsalot", + "Thumper", + "Nibbles", + "Daisy", + "Fuzzy", + "Cottontail", + "Carrot Top", + "Marshmallow", + "Lucky", + "Clover", + "Daffodil", + "Buttercup", + "Goldie", + "Dizzy", + "Trixie", + "Snuffles", + "Hopscotch", + "Skipper", + "Thunderfoot", + "Bigwig", + "Dandelion", + "Pipkin", + "Buckthorn", + "Skipper" + ] +} diff --git a/bot/resources/holidays/easter/chocolate_bunny.png b/bot/resources/holidays/easter/chocolate_bunny.png new file mode 100644 index 00000000..6b25aa5a Binary files /dev/null and b/bot/resources/holidays/easter/chocolate_bunny.png differ diff --git a/bot/resources/holidays/easter/easter_egg_facts.json b/bot/resources/holidays/easter/easter_egg_facts.json new file mode 100644 index 00000000..b0650b84 --- /dev/null +++ b/bot/resources/holidays/easter/easter_egg_facts.json @@ -0,0 +1,17 @@ +[ + "The first story of a rabbit (later named the \"Easter Bunny\") hiding eggs in a garden was published in 1680.", + "Rabbits are known to be prolific pro creators and are an ancient symbol of fertility and new life. The German immigrants brought the tale of Easter Bunny in the 1700s with the tradition of an egg-laying hare called \"Osterhase\". The kids then would make nests in which the creature would lay coloured eggs. The tradition has been revolutionized in the form of candies and gifts instead of eggs.", + "In earlier days, a festival of egg throwing was held in church, when the priest would throw a hard-boiled egg to one of the choirboys. It was then tossed from one choirboy to the next and whoever held the egg when the clock struck 12 on Easter, was the winner and could keep it.", + "In medieval times, Easter eggs were boiled with onions to give them a golden sheen. Edward I went beyond this tradition in 1290 and ordered 450 eggs to be covered in gold leaf and given as Easter gifts.", + "Decorating Easter eggs is an ancient tradition that dates back to 13th century. One of the explanations for this custom is that eggs were considered as a forbidden food during the Lenten season (40 days before Easter). Therefore, people would paint and decorate them to mark an end of the period of penance and fasting and later eat them on Easter. The tradition of decorating eggs is called Pysanka which is creating a traditional Ukrainian folk design using wax-resist method.", + "Members of the Greek Orthodox faith often paint their Easter eggs red, which symbolizes Jesus' blood and his victory over death. The color red, symbolizes renewal of life, such as, Jesus' resurrection.", + "Eggs rolling take place in many parts of the world which symbolizes stone which was rolled away from the tomb where Jesus' body was laid after his death.", + "Easter eggs have been considered as a symbol of fertility, rebirth and new life. The custom of giving eggs has been derived from Egyptians, Persians, Gauls, Greeks, and Romans.", + "The first chocolate Easter egg was made by Fry's in 1873. Before this, people would give hollow cardboard eggs, filled with gifts.", + "The tallest chocolate Easter egg was made in Italy in 2011. Standing 10.39 metres tall and weighing 7,200 kg, it was taller than a giraffe and heavier than an elephant.", + "The largest ever Easter egg hunt was in Florida, where 9,753 children searched for 501,000 eggs.", + "In 2007, an Easter egg covered in diamonds sold for almost £9 million. Every hour, a cockerel made of jewels pops up from the top of the Faberge egg, flaps its wings four times, nods its head three times and makes a crowing noise. The gold-and-pink enamel egg was made by the Russian royal family as an engagement gift for French aristocrat Baron Edouard de Rothschild.", + "The White House held their first official egg roll in 1878 when Rutherford B. Hayes was the President. It is a race in which children push decorated, hard-boiled eggs across the White House lawn as an annual event held the Monday after Easter. In 2009, the Obamas hosted their first Easter egg roll with the theme, \"Let's go play\" which was meant to encourage young people to lead healthy and active lives.", + "80 million chocolate Easter eggs are sold each year. This accounts for 10% of Britain's annual spending on chocolate!", + "John Cadbury soon followed suit and made his first Cadbury Easter egg in 1875. By 1892 the company was producing 19 different lines, all made from dark chocolate." +] diff --git a/bot/resources/holidays/easter/easter_eggs/design1.png b/bot/resources/holidays/easter/easter_eggs/design1.png new file mode 100644 index 00000000..d887c590 Binary files /dev/null and b/bot/resources/holidays/easter/easter_eggs/design1.png differ diff --git a/bot/resources/holidays/easter/easter_eggs/design2.png b/bot/resources/holidays/easter/easter_eggs/design2.png new file mode 100644 index 00000000..c4fff644 Binary files /dev/null and b/bot/resources/holidays/easter/easter_eggs/design2.png differ diff --git a/bot/resources/holidays/easter/easter_eggs/design3.png b/bot/resources/holidays/easter/easter_eggs/design3.png new file mode 100644 index 00000000..803bc1e3 Binary files /dev/null and b/bot/resources/holidays/easter/easter_eggs/design3.png differ diff --git a/bot/resources/holidays/easter/easter_eggs/design4.png b/bot/resources/holidays/easter/easter_eggs/design4.png new file mode 100644 index 00000000..38e6a83f Binary files /dev/null and b/bot/resources/holidays/easter/easter_eggs/design4.png differ diff --git a/bot/resources/holidays/easter/easter_eggs/design5.png b/bot/resources/holidays/easter/easter_eggs/design5.png new file mode 100644 index 00000000..56662c26 Binary files /dev/null and b/bot/resources/holidays/easter/easter_eggs/design5.png differ diff --git a/bot/resources/holidays/easter/easter_eggs/design6.png b/bot/resources/holidays/easter/easter_eggs/design6.png new file mode 100644 index 00000000..5372439a Binary files /dev/null and b/bot/resources/holidays/easter/easter_eggs/design6.png differ diff --git a/bot/resources/holidays/easter/easter_riddle.json b/bot/resources/holidays/easter/easter_riddle.json new file mode 100644 index 00000000..f7eb63d8 --- /dev/null +++ b/bot/resources/holidays/easter/easter_riddle.json @@ -0,0 +1,74 @@ +[ + { + "question": "What kind of music do bunnies like?", + "riddles": [ + "Two words", + "Jump to the beat" + ], + "correct_answer": "Hip hop" + }, + { + "question": "What kind of jewelry do rabbits wear?", + "riddles": [ + "They can eat it too", + "14 ___ gold" + ], + "correct_answer": "14 carrot gold" + }, + { + "question": "What does the easter bunny get for making a basket?", + "riddles": [ + "KOBE!", + "1+1 = ?" + ], + "correct_answer": "2 points" + }, + { + "question": "Where does the easter bunny eat breakfast?", + "riddles": [ + "No waffles here", + "An international home" + ], + "correct_answer": "IHOP" + }, + { + "question": "What do you call a rabbit with fleas?", + "riddles": [ + "A bit of a looney tune", + "What's up Doc?" + ], + "correct_answer": "Bugs Bunny" + }, + { + "question": "Why was the little girl sad after the race?", + "riddles": [ + "2nd place?", + "Who beat her?" + ], + "correct_answer": "Because an egg beater" + }, + { + "question": "What happened to the Easter Bunny when he misbehaved at school?", + "riddles": [ + "Won't be back anymore", + "Worse than suspension" + ], + "correct_answer": "He was eggspelled" + }, + { + "question": "What kind of bunny can't hop?", + "riddles": [ + "Might melt in the sun", + "Fragile and yummy" + ], + "correct_answer": "A chocolate one" + }, + { + "question": "Why did the Easter Bunny have to fire the duck?", + "riddles": [ + "Quack", + "MY EGGS!!" + ], + "correct_answer": "He kept quacking the eggs" + } +] diff --git a/bot/resources/holidays/easter/egghead_questions.json b/bot/resources/holidays/easter/egghead_questions.json new file mode 100644 index 00000000..5535f8e0 --- /dev/null +++ b/bot/resources/holidays/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": 3 + }, + { + "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 + } +] diff --git a/bot/resources/holidays/easter/traditions.json b/bot/resources/holidays/easter/traditions.json new file mode 100644 index 00000000..f9dd6d81 --- /dev/null +++ b/bot/resources/holidays/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."} -- cgit v1.2.3