diff options
Diffstat (limited to 'bot')
-rw-r--r-- | bot/constants.py | 12 | ||||
-rw-r--r-- | bot/resources/halloween/responses.json | 14 | ||||
-rw-r--r-- | bot/seasons/christmas/adventofcode.py | 6 | ||||
-rw-r--r-- | bot/seasons/christmas/hanukkah_embed.py | 112 | ||||
-rw-r--r-- | bot/seasons/easter/avatar_easterifier.py | 3 | ||||
-rw-r--r-- | bot/seasons/evergreen/showprojects.py | 35 | ||||
-rw-r--r-- | bot/seasons/evergreen/snakes/snakes_cog.py | 8 | ||||
-rw-r--r-- | bot/seasons/evergreen/snakes/utils.py | 11 | ||||
-rw-r--r-- | bot/seasons/halloween/8ball.py | 35 | ||||
-rw-r--r-- | bot/seasons/halloween/candy_collection.py | 10 | ||||
-rw-r--r-- | bot/seasons/halloween/halloween_facts.py | 4 | ||||
-rw-r--r-- | bot/seasons/halloween/spookyavatar.py | 5 | ||||
-rw-r--r-- | bot/seasons/season.py | 2 | ||||
-rw-r--r-- | bot/seasons/valentines/be_my_valentine.py | 7 |
14 files changed, 226 insertions, 38 deletions
diff --git a/bot/constants.py b/bot/constants.py index d362c90e..67dd9328 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -18,7 +18,6 @@ class AdventOfCode: leaderboard_join_code = str(environ.get("AOC_JOIN_CODE", None)) leaderboard_max_displayed_members = 10 year = 2018 - channel_id = int(environ.get("AOC_CHANNEL_ID", 517745814039166986)) role_id = int(environ.get("AOC_ROLE_ID", 518565788744024082)) @@ -50,6 +49,8 @@ class Channels(NamedTuple): staff_lounge = 464905259261755392 verification = 352442727016693763 python_discussion = 267624335836053506 + show_your_projects = 303934982764625920 + show_your_projects_discussion = 360148304664723466 class Client(NamedTuple): @@ -61,13 +62,14 @@ class Client(NamedTuple): class Colours: - yellow = 0xf9f586 - soft_red = 0xcd6d6d - soft_green = 0x68c290 + blue = 0x0279fd bright_green = 0x01d277 dark_green = 0x1f8b4c orange = 0xe67e22 pink = 0xcf84e0 + soft_green = 0x68c290 + soft_red = 0xcd6d6d + yellow = 0xf9f586 class Emojis: @@ -84,12 +86,10 @@ class Emojis: class Lovefest: - channel_id = int(environ.get("LOVEFEST_CHANNEL_ID", 542272993192050698)) role_id = int(environ.get("LOVEFEST_ROLE_ID", 542431903886606399)) class Hacktoberfest(NamedTuple): - channel_id = 498804484324196362 voice_id = 514420006474219521 diff --git a/bot/resources/halloween/responses.json b/bot/resources/halloween/responses.json new file mode 100644 index 00000000..c0f24c1a --- /dev/null +++ b/bot/resources/halloween/responses.json @@ -0,0 +1,14 @@ +{ + "responses": [ + ["No."], + ["Yes."], + ["I will seek and answer from the devil...", "...after requesting the devils knowledge the answer is far more complicated than a simple yes or no."], + ["This knowledge is not available to me, I will seek the answers from someone far more powerful...", "...there is no answer to this question, not even the Grim Reaper could find an answer."], + ["The ghosts I summoned have confirmed that is is certain."], + ["Double, double, toil and trouble,\nFire burn and cauldron bubble.\nCool it with a baboon's blood,\nand tell me the answer to his question...", "...the great cauldron can only confirm your beliefs."], + ["Double, double, toil and trouble,\nFire burn and cauldron bubble.\nCool it with a baboon's blood,\nand tell me the answer to his question...", "...the great cauldron can only confirm that the answer to your question is no."], + ["If I tell you I will have to kill you..."], + ["I swear on my spider that you are correct."], + ["With great certainty, under the watch of the Pumpkin King, I can confirm your suspicions."], + ["The undead have sworn me to secrecy. I can not answer your question."] +]} diff --git a/bot/seasons/christmas/adventofcode.py b/bot/seasons/christmas/adventofcode.py index c30de7b5..08b07e83 100644 --- a/bot/seasons/christmas/adventofcode.py +++ b/bot/seasons/christmas/adventofcode.py @@ -13,7 +13,7 @@ from bs4 import BeautifulSoup from discord.ext import commands from pytz import timezone -from bot.constants import AdventOfCode as AocConfig, Colours, Emojis, Tokens +from bot.constants import AdventOfCode as AocConfig, Channels, Colours, Emojis, Tokens log = logging.getLogger(__name__) @@ -84,7 +84,7 @@ async def day_countdown(bot: commands.Bot): await asyncio.sleep(time_left.seconds) - channel = bot.get_channel(AocConfig.channel_id) + channel = bot.get_channel(Channels.seasonalbot_chat) if not channel: log.error("Could not find the AoC channel to send notification in") @@ -127,7 +127,7 @@ class AdventOfCode(commands.Cog): @commands.group(name="adventofcode", aliases=("aoc",), invoke_without_command=True) async def adventofcode_group(self, ctx: commands.Context): """All of the Advent of Code commands.""" - await ctx.invoke(self.bot.get_command("help"), "adventofcode") + await ctx.send_help(ctx.command) @adventofcode_group.command( name="subscribe", diff --git a/bot/seasons/christmas/hanukkah_embed.py b/bot/seasons/christmas/hanukkah_embed.py new file mode 100644 index 00000000..652a1f35 --- /dev/null +++ b/bot/seasons/christmas/hanukkah_embed.py @@ -0,0 +1,112 @@ +import datetime +import logging + +from discord import Embed +from discord.ext import commands + +from bot.constants import Colours + + +log = logging.getLogger(__name__) + + +class HanukkahEmbed(commands.Cog): + """A cog that returns information about Hanukkah festival.""" + + def __init__(self, bot): + self.bot = bot + self.url = ("https://www.hebcal.com/hebcal/?v=1&cfg=json&maj=on&min=on&mod=on&nx=on&" + "year=now&month=x&ss=on&mf=on&c=on&geo=geoname&geonameid=3448439&m=50&s=on") + self.hanukkah_days = [] + self.hanukkah_months = [] + self.hanukkah_years = [] + + async def get_hanukkah_dates(self): + """Gets the dates for hanukkah festival.""" + hanukkah_dates = [] + async with self.bot.http_session.get(self.url) as response: + json_data = await response.json() + festivals = json_data['items'] + for festival in festivals: + if festival['title'].startswith('Chanukah'): + date = festival['date'] + hanukkah_dates.append(date) + return hanukkah_dates + + @commands.command(name='hanukkah', aliases=['chanukah']) + async def hanukkah_festival(self, ctx): + """Tells you about the Hanukkah Festivaltime of festival, festival day, etc).""" + hanukkah_dates = await self.get_hanukkah_dates() + self.hanukkah_dates_split(hanukkah_dates) + hanukkah_start_day = int(self.hanukkah_days[0]) + hanukkah_start_month = int(self.hanukkah_months[0]) + hanukkah_start_year = int(self.hanukkah_years[0]) + hanukkah_end_day = int(self.hanukkah_days[8]) + hanukkah_end_month = int(self.hanukkah_months[8]) + hanukkah_end_year = int(self.hanukkah_years[8]) + + hanukkah_start = datetime.date(hanukkah_start_year, hanukkah_start_month, hanukkah_start_day) + hanukkah_end = datetime.date(hanukkah_end_year, hanukkah_end_month, hanukkah_end_day) + today = datetime.date.today() + # today = datetime.date(2019, 12, 24) (for testing) + day = str(today.day) + month = str(today.month) + year = str(today.year) + embed = Embed() + embed.title = 'Hanukkah' + embed.colour = Colours.blue + if day in self.hanukkah_days and month in self.hanukkah_months and year in self.hanukkah_years: + if int(day) == hanukkah_start_day: + now = datetime.datetime.utcnow() + now = str(now) + hours = int(now[11:13]) + 4 # using only hours + hanukkah_start_hour = 18 + if hours < hanukkah_start_hour: + embed.description = (f"Hanukkah hasnt started yet, " + f"it will start in about {hanukkah_start_hour-hours} hour/s.") + return await ctx.send(embed=embed) + elif hours > hanukkah_start_hour: + embed.description = (f'It is the starting day of Hanukkah ! ' + f'Its been {hours-hanukkah_start_hour} hours hanukkah started !') + return await ctx.send(embed=embed) + festival_day = self.hanukkah_days.index(day) + number_suffixes = ['st', 'nd', 'rd', 'th'] + suffix = '' + if int(festival_day) == 1: + suffix = number_suffixes[0] + if int(festival_day) == 2: + suffix = number_suffixes[1] + if int(festival_day) == 3: + suffix = number_suffixes[2] + if int(festival_day) > 3: + suffix = number_suffixes[3] + message = '' + for _ in range(1, festival_day + 1): + message += ':menorah:' + embed.description = f'It is the {festival_day}{suffix} day of Hanukkah ! \n {message}' + await ctx.send(embed=embed) + else: + if today < hanukkah_start: + festival_starting_month = hanukkah_start.strftime('%B') + embed.description = (f"Hanukkah has not started yet. " + f"Hanukkah will start at sundown on {hanukkah_start_day}th " + f"of {festival_starting_month}.") + else: + festival_end_month = hanukkah_end.strftime('%B') + embed.description = (f"Looks like you missed Hanukkah !" + f"Hanukkah ended on {hanukkah_end_day}th of {festival_end_month}.") + + await ctx.send(embed=embed) + + def hanukkah_dates_split(self, hanukkah_dates): + """We are splitting the dates for hanukkah into days, months and years.""" + for date in hanukkah_dates: + self.hanukkah_days.append(date[8:10]) + self.hanukkah_months.append(date[5:7]) + self.hanukkah_years.append(date[0:4]) + + +def setup(bot): + """Cog load.""" + bot.add_cog(HanukkahEmbed(bot)) + log.info("Hanukkah embed cog loaded") diff --git a/bot/seasons/easter/avatar_easterifier.py b/bot/seasons/easter/avatar_easterifier.py index 445c5039..0e0b5934 100644 --- a/bot/seasons/easter/avatar_easterifier.py +++ b/bot/seasons/easter/avatar_easterifier.py @@ -69,8 +69,7 @@ class AvatarEasterifier(commands.Cog): async with ctx.typing(): # Grabs image of avatar - async with self.bot.http_session.get(ctx.author.avatar_url_as(size=256)) as resp: - image_bytes = await resp.read() + image_bytes = await ctx.author.avatar_url_as(size=256).read() old = Image.open(BytesIO(image_bytes)) old = old.convert("RGBA") diff --git a/bot/seasons/evergreen/showprojects.py b/bot/seasons/evergreen/showprojects.py new file mode 100644 index 00000000..d6223690 --- /dev/null +++ b/bot/seasons/evergreen/showprojects.py @@ -0,0 +1,35 @@ +import logging + +from discord.ext import commands + +from bot.constants import Channels + +log = logging.getLogger(__name__) + + +class ShowProjects(commands.Cog): + """Cog that reacts to posts in the #show-your-projects""" + + def __init__(self, bot): + self.bot = bot + self.lastPoster = 0 # Given 0 as the default last poster ID as no user can actually have 0 assigned to them + + @commands.Cog.listener() + async def on_message(self, message): + """Adds reactions to posts in #show-your-projects""" + + reactions = ["\U0001f44d", "\U00002764", "\U0001f440", "\U0001f389", "\U0001f680", "\U00002b50", "\U0001f6a9"] + if (message.channel.id == Channels.show_your_projects + and message.author.bot is False + and message.author.id != self.lastPoster): + for reaction in reactions: + await message.add_reaction(reaction) + + self.lastPoster = message.author.id + + +def setup(bot): + """Show Projects Reaction Cog""" + + bot.add_cog(ShowProjects(bot)) + log.info("ShowProjects cog loaded") diff --git a/bot/seasons/evergreen/snakes/snakes_cog.py b/bot/seasons/evergreen/snakes/snakes_cog.py index 6698183f..3927fab5 100644 --- a/bot/seasons/evergreen/snakes/snakes_cog.py +++ b/bot/seasons/evergreen/snakes/snakes_cog.py @@ -445,7 +445,7 @@ class Snakes(Cog): @group(name='snakes', aliases=('snake',), invoke_without_command=True) async def snakes_group(self, ctx: Context): """Commands from our first code jam.""" - await ctx.invoke(self.bot.get_command("help"), "snake") + await ctx.send_help(ctx.command) @bot_has_permissions(manage_messages=True) @snakes_group.command(name='antidote') @@ -1029,12 +1029,6 @@ class Snakes(Cog): ) await ctx.channel.send(embed=embed) - @snakes_group.command(name='help') - async def help_command(self, ctx: Context): - """Invokes the help command for the Snakes Cog.""" - log.debug(f"{ctx.author} requested info about the snakes cog") - return await ctx.invoke(self.bot.get_command("help"), "Snakes") - @snakes_group.command(name='snakify') async def snakify_command(self, ctx: Context, *, message: str = None): """ diff --git a/bot/seasons/evergreen/snakes/utils.py b/bot/seasons/evergreen/snakes/utils.py index 0d1505f7..4899c2a2 100644 --- a/bot/seasons/evergreen/snakes/utils.py +++ b/bot/seasons/evergreen/snakes/utils.py @@ -8,7 +8,6 @@ from itertools import product from pathlib import Path from typing import List, Tuple -import aiohttp from PIL import Image from PIL.ImageDraw import ImageDraw from discord import File, Member, Reaction @@ -469,12 +468,10 @@ class SnakeAndLaddersGame: async def _add_player(self, user: Member): self.players.append(user) self.player_tiles[user.id] = 1 - avatar_url = user.avatar_url_as(format='jpeg', size=PLAYER_ICON_IMAGE_SIZE) - async with aiohttp.ClientSession() as session: - async with session.get(avatar_url) as res: - avatar_bytes = await res.read() - im = Image.open(io.BytesIO(avatar_bytes)).resize((BOARD_PLAYER_SIZE, BOARD_PLAYER_SIZE)) - self.avatar_images[user.id] = im + + avatar_bytes = await user.avatar_url_as(format='jpeg', size=PLAYER_ICON_IMAGE_SIZE).read() + im = Image.open(io.BytesIO(avatar_bytes)).resize((BOARD_PLAYER_SIZE, BOARD_PLAYER_SIZE)) + self.avatar_images[user.id] = im async def player_join(self, user: Member): """ diff --git a/bot/seasons/halloween/8ball.py b/bot/seasons/halloween/8ball.py new file mode 100644 index 00000000..af037e53 --- /dev/null +++ b/bot/seasons/halloween/8ball.py @@ -0,0 +1,35 @@ +import asyncio +import json +import logging +import random +from pathlib import Path + +from discord.ext import commands + +log = logging.getLogger(__name__) + +with open(Path('bot', 'resources', 'halloween', 'responses.json'), 'r', encoding="utf8") as f: + responses = json.load(f) + + +class SpookyEightBall(commands.Cog): + """Spooky Eightball answers.""" + + def __init__(self, bot): + self.bot = bot + + @commands.command(aliases=('spooky8ball',)) + async def spookyeightball(self, ctx, *, question: str): + """Responds with a random response to a question.""" + choice = random.choice(responses['responses']) + msg = await ctx.send(choice[0]) + if len(choice) > 1: + await asyncio.sleep(random.randint(2, 5)) + await msg.edit(content=f"{choice[0]} \n{choice[1]}") + + +def setup(bot): + """Spooky Eight Ball Cog Load.""" + + bot.add_cog(SpookyEightBall(bot)) + log.info("SpookyEightBall cog loaded") diff --git a/bot/seasons/halloween/candy_collection.py b/bot/seasons/halloween/candy_collection.py index 1f219425..d35cbee5 100644 --- a/bot/seasons/halloween/candy_collection.py +++ b/bot/seasons/halloween/candy_collection.py @@ -7,7 +7,7 @@ import random import discord from discord.ext import commands -from bot.constants import Hacktoberfest +from bot.constants import Channels log = logging.getLogger(__name__) @@ -40,7 +40,7 @@ class CandyCollection(commands.Cog): if message.author.bot: return # ensure it's hacktober channel - if message.channel.id != Hacktoberfest.channel_id: + if message.channel.id != Channels.seasonalbot_chat: return # do random check for skull first as it has the lower chance @@ -63,7 +63,7 @@ class CandyCollection(commands.Cog): return # check to ensure it is in correct channel - if message.channel.id != Hacktoberfest.channel_id: + if message.channel.id != Channels.seasonalbot_chat: return # if its not a candy or skull, and it is one of 10 most recent messages, @@ -123,7 +123,7 @@ class CandyCollection(commands.Cog): ten_recent = [] recent_msg = max(message.id for message in self.bot._connection._messages - if message.channel.id == Hacktoberfest.channel_id) + if message.channel.id == Channels.seasonalbot_chat) channel = await self.hacktober_channel() ten_recent.append(recent_msg.id) @@ -153,7 +153,7 @@ class CandyCollection(commands.Cog): async def hacktober_channel(self): """Get #hacktoberbot channel from its ID.""" - return self.bot.get_channel(id=Hacktoberfest.channel_id) + return self.bot.get_channel(id=Channels.seasonalbot_chat) async def remove_reactions(self, reaction): """Remove all candy/skull reactions.""" diff --git a/bot/seasons/halloween/halloween_facts.py b/bot/seasons/halloween/halloween_facts.py index e8392b28..00d91bc5 100644 --- a/bot/seasons/halloween/halloween_facts.py +++ b/bot/seasons/halloween/halloween_facts.py @@ -7,7 +7,7 @@ from pathlib import Path import discord from discord.ext import commands -from bot.constants import Hacktoberfest +from bot.constants import Channels log = logging.getLogger(__name__) @@ -39,7 +39,7 @@ class HalloweenFacts(commands.Cog): @commands.Cog.listener() async def on_ready(self): """Get event Channel object and initialize fact task loop.""" - self.channel = self.bot.get_channel(Hacktoberfest.channel_id) + self.channel = self.bot.get_channel(Channels.seasonalbot_chat) self.bot.loop.create_task(self._fact_publisher_task()) def random_fact(self): diff --git a/bot/seasons/halloween/spookyavatar.py b/bot/seasons/halloween/spookyavatar.py index 4b0ba9f5..9bdef1a8 100644 --- a/bot/seasons/halloween/spookyavatar.py +++ b/bot/seasons/halloween/spookyavatar.py @@ -35,8 +35,9 @@ class SpookyAvatar(commands.Cog): embed = discord.Embed(colour=0xFF0000) embed.title = "Is this you or am I just really paranoid?" embed.set_author(name=str(user.name), icon_url=user.avatar_url) - resp = await self.get(user.avatar_url) - im = Image.open(BytesIO(resp)) + + image_bytes = await ctx.author.avatar_url.read() + im = Image.open(BytesIO(image_bytes)) modified_im = spookifications.get_random_effect(im) modified_im.save(str(ctx.message.id)+'.png') f = discord.File(str(ctx.message.id)+'.png') diff --git a/bot/seasons/season.py b/bot/seasons/season.py index 4809c2e8..e6a262c8 100644 --- a/bot/seasons/season.py +++ b/bot/seasons/season.py @@ -424,7 +424,7 @@ class SeasonManager(commands.Cog): async def refresh(self, ctx): """Refreshes certain seasonal elements without reloading seasons.""" if not ctx.invoked_subcommand: - await ctx.invoke(bot.get_command("help"), "refresh") + await ctx.send_help(ctx.command) @refresh.command(name="avatar") async def refresh_avatar(self, ctx): diff --git a/bot/seasons/valentines/be_my_valentine.py b/bot/seasons/valentines/be_my_valentine.py index 90e4d5db..fff3e367 100644 --- a/bot/seasons/valentines/be_my_valentine.py +++ b/bot/seasons/valentines/be_my_valentine.py @@ -8,7 +8,7 @@ import discord from discord.ext import commands from discord.ext.commands.cooldowns import BucketType -from bot.constants import Client, Colours, Lovefest +from bot.constants import Channels, Client, Colours, Lovefest log = logging.getLogger(__name__) @@ -40,7 +40,8 @@ class BeMyValentine(commands.Cog): 1) use the command \".lovefest sub\" to get the lovefest role. 2) use the command \".lovefest unsub\" to get rid of the lovefest role. """ - await ctx.invoke(self.bot.get_command("help"), "lovefest") + + await ctx.send_help(ctx.command) @lovefest_role.command(name="sub") async def add_role(self, ctx): @@ -94,7 +95,7 @@ class BeMyValentine(commands.Cog): emoji_1, emoji_2 = self.random_emoji() lovefest_role = discord.utils.get(ctx.guild.roles, id=Lovefest.role_id) - channel = self.bot.get_channel(Lovefest.channel_id) + channel = self.bot.get_channel(Channels.seasonalbot_chat) valentine, title = self.valentine_check(valentine_type) if user is None: |