From 2ee473894e83f3d1d4290163d4bd1e9a659abecf Mon Sep 17 00:00:00 2001 From: mathsman5133 <38833292+mathsman5133@users.noreply.github.com> Date: Tue, 9 Oct 2018 17:48:02 +1100 Subject: Add files via upload --- bot/cogs/candy_collection.json | 25 ++++++ bot/cogs/candy_collection.py | 186 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 bot/cogs/candy_collection.json create mode 100644 bot/cogs/candy_collection.py (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.json b/bot/cogs/candy_collection.json new file mode 100644 index 00000000..308de4f3 --- /dev/null +++ b/bot/cogs/candy_collection.json @@ -0,0 +1,25 @@ +{ + "msg_reacted": [ + { + "reaction": "\ud83c\udf6c", + "msg_id": 499064137188638730, + "won": true, + "user_reacted": 230214242618441728 + }, + { + "reaction": "\ud83c\udf6c", + "msg_id": 499064204570132500, + "won": false + } + ], + "records": [ + { + "userid": 1234567890, + "record": 4 + }, + { + "userid": 9876543210, + "record": 10 + } + ] +} \ No newline at end of file diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py new file mode 100644 index 00000000..5a51d05c --- /dev/null +++ b/bot/cogs/candy_collection.py @@ -0,0 +1,186 @@ +import discord +from discord.ext import commands +import random +import json +import functools +import os + +json_location = os.path.join(os.getcwd(),'resources', 'candy_collection.json') + + +class CandyCollection: + def __init__(self, bot): + self.bot = bot + with open(json_location) as candy: + self.candy_json = json.load(candy) + self.msg_reacted = self.candy_json['msg_reacted'] + self.get_candyinfo = dict() + for userinfo in self.candy_json['records']: + userid = userinfo['userid'] + self.get_candyinfo[userid] = userinfo + + HACKTOBER_CHANNEL_ID = 496432022961520650 + # chance is 1 in x range, so 1 in 20 range would give 5% chance (for add candy) + ADD_CANDY_REACTION_CHANCE = 20 # 5% + ADD_CANDY_EXISTING_REACTION_CHANCE = 10 # 10% + ADD_SKULL_REACTION_CHANCE = 50 # 2% + ADD_SKULL_EXISTING_REACTION_CHANCE = 20 # 5% + + async def on_message(self, message): + """Make sure the user is not a bot and + the channel is #event-hacktoberfest. + Because the skull has a lower chance of occurring + we'll check for that first, and then add respective reactions""" + if message.author.bot: + return + if message.channel.id != self.HACKTOBER_CHANNEL_ID: + return + if random.randint(1, self.ADD_SKULL_REACTION_CHANCE) == 1: + d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{SKULL}') + if random.randint(1, self.ADD_CANDY_REACTION_CHANCE) == 1: + d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{CANDY}') + + async def on_reaction_add(self, reaction, user): + """Make sure the reaction is in #event-hacktoberfest + and the user reacting is not a bot (ie. ourselves) + Check if the reaction is a skull/candy first. """ + message = reaction.message + if message.channel.id != self.HACKTOBER_CHANNEL_ID: + return + if user.bot: + return + if str(reaction.emoji) not in ('\N{SKULL}', '\N{CANDY}'): + if message.id in await self.ten_recent_msg(): + await self.reacted_msg_chance(message) + return + for react in self.msg_reacted: + # check to see if the message id of a message we added a + # reaction to is in json file, and if nobody has won/claimed it yet + if react['msg_id'] == message.id and react['won'] is False: + react['user_reacted'] = user.id + react['won'] = True + try: + # if they have record/candies in json already it will do this + user_records = self.get_candyinfo[user.id] + if str(reaction.emoji) == '\N{CANDY}': + user_records['record'] += 1 + if str(reaction.emoji) == '\N{SKULL}': + if user_records['record'] <= 3: + user_records['record'] = 0 + lost = 'all of your' + else: + lost = random.randint(1, 3) + user_records['record'] -= lost + await self.send_spook_msg(message.channel, lost) + + except KeyError: + # otherwise it will raise KeyError so we need to add them + if str(reaction.emoji) == '\N{CANDY}': + print('ok') + d = {"userid": user.id, "record": 1} + self.candy_json['records'].append(d) + await self.remove_reactions(reaction) + + async def reacted_msg_chance(self, message): + """(Randomly) add a skull or candy to a message if there is a reaction there already + (higher probability)""" + if random.randint(1, self.ADD_SKULL_EXISTING_REACTION_CHANCE) == 1: + d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{SKULL}') + + if random.randint(1, self.ADD_CANDY_EXISTING_REACTION_CHANCE) == 1: + d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{CANDY}') + + async def ten_recent_msg(self): + """Get the last 10 messages sent in the channel""" + ten_recent = [] + recent_msg = max((x for x in self.bot._connection._messages + if x.channel.id == self.HACKTOBER_CHANNEL_ID), key=lambda x: x.id) + channel = await self.hacktober_channel() + ten_recent.append(recent_msg.id) + for i in range(9): + o = discord.Object(id=recent_msg.id + i) + msg = await channel.history(limit=1, before=o).next() + ten_recent.append(msg.id) + return ten_recent + + async def get_message(self, msg_id): + """Get the message from it's ID. Use history rather than get_message due to + poor ratelimit (50/1s vs 1/1s)""" + try: + o = discord.Object(id=msg_id + 1) + msg = await self.hacktober_channel.history(limit=1, before=o).next() + if msg.id != msg_id: + return None + return msg + except Exception: + return None + + async def hacktober_channel(self): + """Get #events-hacktober channel from it's id""" + return self.bot.get_channel(id=self.HACKTOBER_CHANNEL_ID) + + async def remove_reactions(self, reaction): + """Remove all candy/skull reactions""" + try: + async for user in reaction.users(): + await reaction.message.remove_reaction(reaction.emoji, user) + except discord.HTTPException: + pass + + async def send_spook_msg(self, channel, candies): + """Send a (lame) spooky message""" + e = discord.Embed(colour=discord.Member.colour) + e.set_author(name="You went to bed last night and the witch visited your grave." + " She left a message that you will be cursed for as long as you live." + f" You woke up this morning and found that {candies} candies had disappeared") + await channel.send(embed=e) + + def save_to_json(self): + """Save json to the file. We will do this with bad practice + async (run_in_executor) to prevent blocking""" + with open(json_location, 'w') as outfile: + json.dump(self.candy_json, outfile) + + @commands.command() + async def candy(self, ctx): + """Get the candy leaderboard and save to json when this is called""" + thing = functools.partial(self.save_to_json) + save = await self.bot.loop.run_in_executor(None, thing) + emoji = ( + '\N{FIRST PLACE MEDAL}', + '\N{SECOND PLACE MEDAL}', + '\N{THIRD PLACE MEDAL}', + '\N{SPORTS MEDAL}', + '\N{SPORTS MEDAL}' + ) + top_sorted = sorted(self.candy_json['records'], key=lambda k: k.get('record', 0), reverse=True) + top_five = top_sorted[:5] + usersid = [] + records = [] + for record in top_five: + usersid.append(record['userid']) + records.append(record['record']) + + value = '\n'.join(f'{emoji[index]} <@{usersid[index]}>: {records[index]}' + for index in range(0, len(usersid))) or 'No Candies' + e = discord.Embed(colour=discord.Colour.blurple()) + e.add_field(name="Top Candy Records", value=value, inline=False) + e.add_field(name='\u200b', + value=f"Candies will randomly appear on messages sent. " + f"\nHit the candy when it appears as fast as possible to get the candy! " + f"\nBut beware the witch...", + inline=False) + await ctx.send(embed=e) + + +def setup(bot): + bot.add_cog(CandyCollection(bot)) + -- cgit v1.2.3 From 7f79647c5ed7b0b95c149bfbe7de04b9db0e30f8 Mon Sep 17 00:00:00 2001 From: mathsman5133 <38833292+mathsman5133@users.noreply.github.com> Date: Tue, 9 Oct 2018 17:49:24 +1100 Subject: Delete candy_collection.json --- bot/cogs/candy_collection.json | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 bot/cogs/candy_collection.json (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.json b/bot/cogs/candy_collection.json deleted file mode 100644 index 308de4f3..00000000 --- a/bot/cogs/candy_collection.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "msg_reacted": [ - { - "reaction": "\ud83c\udf6c", - "msg_id": 499064137188638730, - "won": true, - "user_reacted": 230214242618441728 - }, - { - "reaction": "\ud83c\udf6c", - "msg_id": 499064204570132500, - "won": false - } - ], - "records": [ - { - "userid": 1234567890, - "record": 4 - }, - { - "userid": 9876543210, - "record": 10 - } - ] -} \ No newline at end of file -- cgit v1.2.3 From 9314d2377d5d686fac729a3f05ea8dde3b8242aa Mon Sep 17 00:00:00 2001 From: mathsman5133 <38833292+mathsman5133@users.noreply.github.com> Date: Tue, 9 Oct 2018 17:49:32 +1100 Subject: Delete candy_collection.py --- bot/cogs/candy_collection.py | 186 ------------------------------------------- 1 file changed, 186 deletions(-) delete mode 100644 bot/cogs/candy_collection.py (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py deleted file mode 100644 index 5a51d05c..00000000 --- a/bot/cogs/candy_collection.py +++ /dev/null @@ -1,186 +0,0 @@ -import discord -from discord.ext import commands -import random -import json -import functools -import os - -json_location = os.path.join(os.getcwd(),'resources', 'candy_collection.json') - - -class CandyCollection: - def __init__(self, bot): - self.bot = bot - with open(json_location) as candy: - self.candy_json = json.load(candy) - self.msg_reacted = self.candy_json['msg_reacted'] - self.get_candyinfo = dict() - for userinfo in self.candy_json['records']: - userid = userinfo['userid'] - self.get_candyinfo[userid] = userinfo - - HACKTOBER_CHANNEL_ID = 496432022961520650 - # chance is 1 in x range, so 1 in 20 range would give 5% chance (for add candy) - ADD_CANDY_REACTION_CHANCE = 20 # 5% - ADD_CANDY_EXISTING_REACTION_CHANCE = 10 # 10% - ADD_SKULL_REACTION_CHANCE = 50 # 2% - ADD_SKULL_EXISTING_REACTION_CHANCE = 20 # 5% - - async def on_message(self, message): - """Make sure the user is not a bot and - the channel is #event-hacktoberfest. - Because the skull has a lower chance of occurring - we'll check for that first, and then add respective reactions""" - if message.author.bot: - return - if message.channel.id != self.HACKTOBER_CHANNEL_ID: - return - if random.randint(1, self.ADD_SKULL_REACTION_CHANCE) == 1: - d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} - self.msg_reacted.append(d) - return await message.add_reaction('\N{SKULL}') - if random.randint(1, self.ADD_CANDY_REACTION_CHANCE) == 1: - d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} - self.msg_reacted.append(d) - return await message.add_reaction('\N{CANDY}') - - async def on_reaction_add(self, reaction, user): - """Make sure the reaction is in #event-hacktoberfest - and the user reacting is not a bot (ie. ourselves) - Check if the reaction is a skull/candy first. """ - message = reaction.message - if message.channel.id != self.HACKTOBER_CHANNEL_ID: - return - if user.bot: - return - if str(reaction.emoji) not in ('\N{SKULL}', '\N{CANDY}'): - if message.id in await self.ten_recent_msg(): - await self.reacted_msg_chance(message) - return - for react in self.msg_reacted: - # check to see if the message id of a message we added a - # reaction to is in json file, and if nobody has won/claimed it yet - if react['msg_id'] == message.id and react['won'] is False: - react['user_reacted'] = user.id - react['won'] = True - try: - # if they have record/candies in json already it will do this - user_records = self.get_candyinfo[user.id] - if str(reaction.emoji) == '\N{CANDY}': - user_records['record'] += 1 - if str(reaction.emoji) == '\N{SKULL}': - if user_records['record'] <= 3: - user_records['record'] = 0 - lost = 'all of your' - else: - lost = random.randint(1, 3) - user_records['record'] -= lost - await self.send_spook_msg(message.channel, lost) - - except KeyError: - # otherwise it will raise KeyError so we need to add them - if str(reaction.emoji) == '\N{CANDY}': - print('ok') - d = {"userid": user.id, "record": 1} - self.candy_json['records'].append(d) - await self.remove_reactions(reaction) - - async def reacted_msg_chance(self, message): - """(Randomly) add a skull or candy to a message if there is a reaction there already - (higher probability)""" - if random.randint(1, self.ADD_SKULL_EXISTING_REACTION_CHANCE) == 1: - d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} - self.msg_reacted.append(d) - return await message.add_reaction('\N{SKULL}') - - if random.randint(1, self.ADD_CANDY_EXISTING_REACTION_CHANCE) == 1: - d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} - self.msg_reacted.append(d) - return await message.add_reaction('\N{CANDY}') - - async def ten_recent_msg(self): - """Get the last 10 messages sent in the channel""" - ten_recent = [] - recent_msg = max((x for x in self.bot._connection._messages - if x.channel.id == self.HACKTOBER_CHANNEL_ID), key=lambda x: x.id) - channel = await self.hacktober_channel() - ten_recent.append(recent_msg.id) - for i in range(9): - o = discord.Object(id=recent_msg.id + i) - msg = await channel.history(limit=1, before=o).next() - ten_recent.append(msg.id) - return ten_recent - - async def get_message(self, msg_id): - """Get the message from it's ID. Use history rather than get_message due to - poor ratelimit (50/1s vs 1/1s)""" - try: - o = discord.Object(id=msg_id + 1) - msg = await self.hacktober_channel.history(limit=1, before=o).next() - if msg.id != msg_id: - return None - return msg - except Exception: - return None - - async def hacktober_channel(self): - """Get #events-hacktober channel from it's id""" - return self.bot.get_channel(id=self.HACKTOBER_CHANNEL_ID) - - async def remove_reactions(self, reaction): - """Remove all candy/skull reactions""" - try: - async for user in reaction.users(): - await reaction.message.remove_reaction(reaction.emoji, user) - except discord.HTTPException: - pass - - async def send_spook_msg(self, channel, candies): - """Send a (lame) spooky message""" - e = discord.Embed(colour=discord.Member.colour) - e.set_author(name="You went to bed last night and the witch visited your grave." - " She left a message that you will be cursed for as long as you live." - f" You woke up this morning and found that {candies} candies had disappeared") - await channel.send(embed=e) - - def save_to_json(self): - """Save json to the file. We will do this with bad practice - async (run_in_executor) to prevent blocking""" - with open(json_location, 'w') as outfile: - json.dump(self.candy_json, outfile) - - @commands.command() - async def candy(self, ctx): - """Get the candy leaderboard and save to json when this is called""" - thing = functools.partial(self.save_to_json) - save = await self.bot.loop.run_in_executor(None, thing) - emoji = ( - '\N{FIRST PLACE MEDAL}', - '\N{SECOND PLACE MEDAL}', - '\N{THIRD PLACE MEDAL}', - '\N{SPORTS MEDAL}', - '\N{SPORTS MEDAL}' - ) - top_sorted = sorted(self.candy_json['records'], key=lambda k: k.get('record', 0), reverse=True) - top_five = top_sorted[:5] - usersid = [] - records = [] - for record in top_five: - usersid.append(record['userid']) - records.append(record['record']) - - value = '\n'.join(f'{emoji[index]} <@{usersid[index]}>: {records[index]}' - for index in range(0, len(usersid))) or 'No Candies' - e = discord.Embed(colour=discord.Colour.blurple()) - e.add_field(name="Top Candy Records", value=value, inline=False) - e.add_field(name='\u200b', - value=f"Candies will randomly appear on messages sent. " - f"\nHit the candy when it appears as fast as possible to get the candy! " - f"\nBut beware the witch...", - inline=False) - await ctx.send(embed=e) - - -def setup(bot): - bot.add_cog(CandyCollection(bot)) - -- cgit v1.2.3 From 3e547aa2ff677bfe2b32af6ec41c9cefc7b6d3ca Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Tue, 9 Oct 2018 17:59:20 +1100 Subject: candy-collection --- bot/cogs/candy_collection.py | 186 +++++++++++++++++++++++++++++++ bot/cogs/resources/candy_collection.json | 25 +++++ 2 files changed, 211 insertions(+) create mode 100644 bot/cogs/candy_collection.py create mode 100644 bot/cogs/resources/candy_collection.json (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py new file mode 100644 index 00000000..41e9472f --- /dev/null +++ b/bot/cogs/candy_collection.py @@ -0,0 +1,186 @@ +import discord +from discord.ext import commands +import random +import json +import functools +import os + +json_location = os.path.join(os.getcwd(),'resources', 'candy_collection.json') + + +class CandyCollection: + def __init__(self, bot): + self.bot = bot + with open(json_location) as candy: + self.candy_json = json.load(candy) + self.msg_reacted = self.candy_json['msg_reacted'] + self.get_candyinfo = dict() + for userinfo in self.candy_json['records']: + userid = userinfo['userid'] + self.get_candyinfo[userid] = userinfo + + HACKTOBER_CHANNEL_ID = 496432022961520650 + # chance is 1 in x range, so 1 in 20 range would give 5% chance (for add candy) + ADD_CANDY_REACTION_CHANCE = 20 # 5% + ADD_CANDY_EXISTING_REACTION_CHANCE = 10 # 10% + ADD_SKULL_REACTION_CHANCE = 50 # 2% + ADD_SKULL_EXISTING_REACTION_CHANCE = 20 # 5% + + async def on_message(self, message): + """Make sure the user is not a bot and + the channel is #event-hacktoberfest. + Because the skull has a lower chance of occurring + we'll check for that first, and then add respective reactions""" + if message.author.bot: + return + if message.channel.id != self.HACKTOBER_CHANNEL_ID: + return + if random.randint(1, self.ADD_SKULL_REACTION_CHANCE) == 1: + d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{SKULL}') + if random.randint(1, self.ADD_CANDY_REACTION_CHANCE) == 1: + d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{CANDY}') + + async def on_reaction_add(self, reaction, user): + """Make sure the reaction is in #event-hacktoberfest + and the user reacting is not a bot (ie. ourselves) + Check if the reaction is a skull/candy first. """ + message = reaction.message + if message.channel.id != self.HACKTOBER_CHANNEL_ID: + return + if user.bot: + return + if str(reaction.emoji) not in ('\N{SKULL}', '\N{CANDY}'): + if message.id in await self.ten_recent_msg(): + await self.reacted_msg_chance(message) + return + for react in self.msg_reacted: + # check to see if the message id of a message we added a + # reaction to is in json file, and if nobody has won/claimed it yet + if react['msg_id'] == message.id and react['won'] is False: + react['user_reacted'] = user.id + react['won'] = True + try: + # if they have record/candies in json already it will do this + user_records = self.get_candyinfo[user.id] + if str(reaction.emoji) == '\N{CANDY}': + user_records['record'] += 1 + if str(reaction.emoji) == '\N{SKULL}': + if user_records['record'] <= 3: + user_records['record'] = 0 + lost = 'all of your' + else: + lost = random.randint(1, 3) + user_records['record'] -= lost + await self.send_spook_msg(message.channel, lost) + + except KeyError: + # otherwise it will raise KeyError so we need to add them + if str(reaction.emoji) == '\N{CANDY}': + print('ok') + d = {"userid": user.id, "record": 1} + self.candy_json['records'].append(d) + await self.remove_reactions(reaction) + + async def reacted_msg_chance(self, message): + """(Randomly) add a skull or candy to a message if there is a reaction there already + (higher probability)""" + if random.randint(1, self.ADD_SKULL_EXISTING_REACTION_CHANCE) == 1: + d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{SKULL}') + + if random.randint(1, self.ADD_CANDY_EXISTING_REACTION_CHANCE) == 1: + d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} + self.msg_reacted.append(d) + return await message.add_reaction('\N{CANDY}') + + async def ten_recent_msg(self): + """Get the last 10 messages sent in the channel""" + ten_recent = [] + recent_msg = max((x for x in self.bot._connection._messages + if x.channel.id == self.HACKTOBER_CHANNEL_ID), key=lambda x: x.id) + channel = await self.hacktober_channel() + ten_recent.append(recent_msg.id) + for i in range(9): + o = discord.Object(id=recent_msg.id + i) + msg = await channel.history(limit=1, before=o).next() + ten_recent.append(msg.id) + return ten_recent + + async def get_message(self, msg_id): + """Get the message from it's ID. Use history rather than get_message due to + poor ratelimit (50/1s vs 1/1s)""" + try: + o = discord.Object(id=msg_id + 1) + msg = await self.hacktober_channel.history(limit=1, before=o).next() + if msg.id != msg_id: + return None + return msg + except Exception: + return None + + async def hacktober_channel(self): + """Get #events-hacktober channel from it's id""" + return self.bot.get_channel(id=self.HACKTOBER_CHANNEL_ID) + + async def remove_reactions(self, reaction): + """Remove all candy/skull reactions""" + try: + async for user in reaction.users(): + await reaction.message.remove_reaction(reaction.emoji, user) + except discord.HTTPException: + pass + + async def send_spook_msg(self, channel, candies): + """Send a (lame) spooky message""" + e = discord.Embed(colour=discord.Member.colour) + e.set_author(name="You went to bed last night and the witch visited your grave." + " She left a message that you will be cursed for as long as you live." + f" You woke up this morning and found that {candies} candies had disappeared") + await channel.send(embed=e) + + def save_to_json(self): + """Save json to the file. We will do this with bad practice + async (run_in_executor) to prevent blocking""" + with open(json_location, 'w') as outfile: + json.dump(self.candy_json, outfile) + + @commands.command() + async def candy(self, ctx): + """Get the candy leaderboard and save to json when this is called""" + thing = functools.partial(self.save_to_json) + save = await self.bot.loop.run_in_executor(None, thing) + emoji = ( + '\N{FIRST PLACE MEDAL}', + '\N{SECOND PLACE MEDAL}', + '\N{THIRD PLACE MEDAL}', + '\N{SPORTS MEDAL}', + '\N{SPORTS MEDAL}' + ) + top_sorted = sorted(self.candy_json['records'], key=lambda k: k.get('record', 0), reverse=True) + top_five = top_sorted[:5] + usersid = [] + records = [] + for record in top_five: + usersid.append(record['userid']) + records.append(record['record']) + + value = '\n'.join(f'{emoji[index]} <@{usersid[index]}>: {records[index]}' + for index in range(0, len(usersid))) or 'No Candies' + e = discord.Embed(colour=discord.Colour.blurple()) + e.add_field(name="Top Candy Records", value=value, inline=False) + e.add_field(name='\u200b', + value=f"Candies will randomly appear on messages sent. " + f"\nHit the candy when it appears as fast as possible to get the candy! " + f"\nBut beware the witch...", + inline=False) + await ctx.send(embed=e) + + +def setup(bot): + bot.add_cog(CandyCollection(bot)) + diff --git a/bot/cogs/resources/candy_collection.json b/bot/cogs/resources/candy_collection.json new file mode 100644 index 00000000..2b9a30a6 --- /dev/null +++ b/bot/cogs/resources/candy_collection.json @@ -0,0 +1,25 @@ +{ + "msg_reacted": [ + { + "reaction": "\ud83c\udf6c", + "msg_id": 499064137188638730, + "won": true, + "user_reacted": 230214242618441728 + }, + { + "reaction": "\ud83c\udf6c", + "msg_id": 499064204570132500, + "won": false + } + ], + "records": [ + { + "userid": 1234567890, + "record": 4 + }, + { + "userid": 9876543210, + "record": 10 + } + ] +} \ No newline at end of file -- cgit v1.2.3 From f1f35f0b520a9efe7c4b74e3683766b3e82ef783 Mon Sep 17 00:00:00 2001 From: mathsman5133 <38833292+mathsman5133@users.noreply.github.com> Date: Wed, 10 Oct 2018 11:04:18 +1100 Subject: Update candy_collection.py --- bot/cogs/candy_collection.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index 41e9472f..208f6686 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -138,9 +138,8 @@ class CandyCollection: async def send_spook_msg(self, channel, candies): """Send a (lame) spooky message""" e = discord.Embed(colour=discord.Member.colour) - e.set_author(name="You went to bed last night and the witch visited your grave." - " She left a message that you will be cursed for as long as you live." - f" You woke up this morning and found that {candies} candies had disappeared") + e.set_author(name="Ghosts and Ghouls and Jack o' lanterns at night; " + f"I took {candies} candies and quickly took flight.") await channel.send(embed=e) def save_to_json(self): @@ -176,7 +175,7 @@ class CandyCollection: e.add_field(name='\u200b', value=f"Candies will randomly appear on messages sent. " f"\nHit the candy when it appears as fast as possible to get the candy! " - f"\nBut beware the witch...", + f"\nBut beware the ghosts...", inline=False) await ctx.send(embed=e) -- cgit v1.2.3 From c9791bcf1b8ca8ba6ca8d53ce5612ea271073a78 Mon Sep 17 00:00:00 2001 From: mathsman5133 <38833292+mathsman5133@users.noreply.github.com> Date: Wed, 10 Oct 2018 11:05:14 +1100 Subject: Update candy_collection.json add new line --- bot/cogs/resources/candy_collection.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot/cogs') diff --git a/bot/cogs/resources/candy_collection.json b/bot/cogs/resources/candy_collection.json index 2b9a30a6..70dabd05 100644 --- a/bot/cogs/resources/candy_collection.json +++ b/bot/cogs/resources/candy_collection.json @@ -22,4 +22,4 @@ "record": 10 } ] -} \ No newline at end of file +} -- cgit v1.2.3 From 21de080a3717a5642f5f081079227e6e7f21e271 Mon Sep 17 00:00:00 2001 From: Derek Fitzpatrick Date: Thu, 11 Oct 2018 02:56:02 -0700 Subject: Initial commit. --- Pipfile | 3 +- bot/cogs/monstersurvey.py | 74 ++++++++++++++++++++++++++++++++++++++++ bot/resources/monstersurvey.json | 5 +++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 bot/cogs/monstersurvey.py create mode 100644 bot/resources/monstersurvey.json (limited to 'bot/cogs') diff --git a/Pipfile b/Pipfile index 90f6f45e..453df43a 100644 --- a/Pipfile +++ b/Pipfile @@ -5,6 +5,7 @@ name = "pypi" [packages] "discord.py" = {ref = "rewrite", git = "https://github.com/Rapptz/discord.py"} +requests = "*" [dev-packages] "flake8" = "*" @@ -18,4 +19,4 @@ name = "pypi" python_version = "3.7" [scripts] -start = "python -m bot" \ No newline at end of file +start = "python -m bot" diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py new file mode 100644 index 00000000..5e94b8a5 --- /dev/null +++ b/bot/cogs/monstersurvey.py @@ -0,0 +1,74 @@ +import logging +import json +from discord.ext import commands +from discord.ext.commands import Bot, Context +import discord +from typing import Optional +import aiohttp +from http import HTTPStatus + +log = logging.getLogger(__name__) + + +class MonsterSurvey: + + def __init__(self, bot: Bot): + self.bot = Bot + self._monsters = None + + async def monster_summary(self, monster): + monster = monster.replace(' ', '_') + wiki_url = "http://en.wikipedia.org/w/api.php" \ + "?format=json" \ + "&action=query" \ + "&prop=extracts" \ + "&prop=pageimages" \ + "&explaintext&exintro" \ + "&redirects=1" \ + f"&titles={monster}" + print(wiki_url) + async with aiohttp.ClientSession() as session: + response = await session.get(wiki_url) + if response.status == HTTPStatus.OK: + result = json.loads(await response.text()) + return next(iter(result['query']['pages'].values()))['extract'] + + @property + def survey_data(self) -> dict: + """Get an updated instance of the survey data at all times""" + with open('../bot/resources/monstersurvey.json', 'r') as f: + self.monsters = json.load(f) + return self.monsters + + @commands.group(name='monster', aliases=('ms',), invoke_without_command=True) + async def monster_group(self, ctx: Context): + await ctx.invoke(self.bot.get_command(name="help"), 'monstersurvey') + + @monster_group.command(name='vote') + async def monster_vote(self, ctx: Context, name: Optional[str] = None): + embed = discord.Embed(name='Vote for your favorite monster') + if not name: + for k,v in self.monsters.items(): + msg = f"`!monster show {k}` for more information\n" \ + f"`!monster vote {k}` to cast your vote for this monster." + embed.add_field(name=f"{k}", value=f"{msg}", inline=False) + + await ctx.send(embed=embed) + + @monster_group.command(name='show') + async def monster_show(self, ctx: Context, *monster: str): + monster = ' '.join(monster) + if self.monsters.get(monster, None): + summary = await self.monster_summary(monster) + embed = discord.Embed(name=monster) + embed.add_field(name=f"About {monster}", value=summary) + await ctx.send(embed=embed) + + +def setup(bot: Bot): + bot.add_cog(MonsterSurvey(bot)) + + + + + diff --git a/bot/resources/monstersurvey.json b/bot/resources/monstersurvey.json new file mode 100644 index 00000000..7a8c2043 --- /dev/null +++ b/bot/resources/monstersurvey.json @@ -0,0 +1,5 @@ +{ + "Frankenstein's Monster": { + "votes": [] + } +} -- cgit v1.2.3 From 4c29c2b470d6f27416a97c3be1e41f753e0a1ea6 Mon Sep 17 00:00:00 2001 From: mathsman5133 <38833292+mathsman5133@users.noreply.github.com> Date: Thu, 11 Oct 2018 21:58:13 +1100 Subject: fixed colour for spooky msg --- bot/cogs/candy_collection.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index 208f6686..1d470524 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -75,7 +75,7 @@ class CandyCollection: else: lost = random.randint(1, 3) user_records['record'] -= lost - await self.send_spook_msg(message.channel, lost) + await self.send_spook_msg(message.author, message.channel, lost) except KeyError: # otherwise it will raise KeyError so we need to add them @@ -135,9 +135,9 @@ class CandyCollection: except discord.HTTPException: pass - async def send_spook_msg(self, channel, candies): + async def send_spook_msg(self, author, channel, candies): """Send a (lame) spooky message""" - e = discord.Embed(colour=discord.Member.colour) + e = discord.Embed(colour=author.colour) e.set_author(name="Ghosts and Ghouls and Jack o' lanterns at night; " f"I took {candies} candies and quickly took flight.") await channel.send(embed=e) -- cgit v1.2.3 From bea7d364e957e2f3f1d71cbfb00c306588861ec6 Mon Sep 17 00:00:00 2001 From: Derek Fitzpatrick Date: Thu, 11 Oct 2018 14:22:30 -0700 Subject: Merge branch 'deploy' of https://github.com/dfitzpatrick/hacktoberbot into 31-vote-for-favorite-monster # Conflicts: # Pipfile --- bot/cogs/monstersurvey.py | 86 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 28 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py index 5e94b8a5..46ab2485 100644 --- a/bot/cogs/monstersurvey.py +++ b/bot/cogs/monstersurvey.py @@ -3,66 +3,96 @@ import json from discord.ext import commands from discord.ext.commands import Bot, Context import discord -from typing import Optional +from typing import Optional, Tuple import aiohttp from http import HTTPStatus log = logging.getLogger(__name__) +EMOJIS = { + 'SUCCESS': u"\u2705", + 'ERROR': u"\u274C", +} + class MonsterSurvey: def __init__(self, bot: Bot): self.bot = Bot self._monsters = None - async def monster_summary(self, monster): - monster = monster.replace(' ', '_') - wiki_url = "http://en.wikipedia.org/w/api.php" \ - "?format=json" \ - "&action=query" \ - "&prop=extracts" \ - "&prop=pageimages" \ - "&explaintext&exintro" \ - "&redirects=1" \ - f"&titles={monster}" - print(wiki_url) - async with aiohttp.ClientSession() as session: - response = await session.get(wiki_url) + @property + def monsters(self) -> dict: + """Always get the most up to date version""" + path = '../bot/resources/monstersurvey/monstersurvey.json' + with open(path, 'r') as f: + self._monsters = json.load(f) + return self._monsters + + async def monster_info(self, monster) -> Tuple[Optional[str], Optional[str]]: + """Gets information relating to each monster. This first checks if there + are 'summary' and 'image' keys in the json file. If this fails, it will + attempt to pull summary information from Wikipedia. + """ + async def fetch_url(session: aiohttp.ClientSession, url: str) -> dict: + """Use wikipedia api url calls""" + response = await session.get(url) if response.status == HTTPStatus.OK: result = json.loads(await response.text()) - return next(iter(result['query']['pages'].values()))['extract'] - - @property - def survey_data(self) -> dict: - """Get an updated instance of the survey data at all times""" - with open('../bot/resources/monstersurvey.json', 'r') as f: - self.monsters = json.load(f) - return self.monsters + return next(iter(result['query']['pages'].values())) + summary_url = "http://en.wikipedia.org/w/api.php" \ + "?format=json" \ + "&action=query" \ + "&prop=extracts" \ + "&explaintext&exintro" \ + "&redirects=1" \ + f"&titles={monster}" + image_url = "http://en.wikipedia.org/w/api.php" \ + "?action=query" \ + "&prop=pageimages" \ + "&format=json" \ + "&piprop=original" \ + f"&titles={monster}" + async with aiohttp.ClientSession() as s: + summary = self.monsters[monster].get('summary') \ + or (await fetch_url(s, summary_url)).get('extract') + + image = self.monsters[monster].get('image') \ + or (await fetch_url(s, image_url)).get('original', {}).get('source') + return summary, image @commands.group(name='monster', aliases=('ms',), invoke_without_command=True) async def monster_group(self, ctx: Context): - await ctx.invoke(self.bot.get_command(name="help"), 'monstersurvey') + pass @monster_group.command(name='vote') async def monster_vote(self, ctx: Context, name: Optional[str] = None): + """Casts a vote for a particular monster, or displays a list of all + monsters that are available for voting. + """ embed = discord.Embed(name='Vote for your favorite monster') if not name: for k,v in self.monsters.items(): - msg = f"`!monster show {k}` for more information\n" \ - f"`!monster vote {k}` to cast your vote for this monster." + msg = f"`.monster show {k}` for more information\n" \ + f"`.monster vote {k}` to cast your vote for this monster." embed.add_field(name=f"{k}", value=f"{msg}", inline=False) - + # TODO: Add logic for voting await ctx.send(embed=embed) @monster_group.command(name='show') async def monster_show(self, ctx: Context, *monster: str): + """Display a detailed description for the monster, and image.""" monster = ' '.join(monster) if self.monsters.get(monster, None): - summary = await self.monster_summary(monster) + summary, image = await self.monster_info(monster) embed = discord.Embed(name=monster) - embed.add_field(name=f"About {monster}", value=summary) + embed.add_field(name=f"About {monster}", value=summary or "No information") + if image: + embed.set_image(url=image) + embed.set_footer(text=f"To vote for {monster}, type `.monster vote {monster}`") await ctx.send(embed=embed) + else: + await ctx.message.add_reaction(EMOJIS['ERROR']) def setup(bot: Bot): -- cgit v1.2.3 From 7d80d96bca9a18d69f6c469a1531ddfe29417425 Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Fri, 12 Oct 2018 10:24:36 +1100 Subject: Fixed docstrings, add blank lines for readibility, method of finding last 10 messages --- bot/cogs/candy_collection.py | 78 +++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 27 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index 41e9472f..1e066cb0 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -5,7 +5,7 @@ import json import functools import os -json_location = os.path.join(os.getcwd(),'resources', 'candy_collection.json') +json_location = os.path.join(os.getcwd(), 'resources', 'candy_collection.json') class CandyCollection: @@ -19,7 +19,7 @@ class CandyCollection: userid = userinfo['userid'] self.get_candyinfo[userid] = userinfo - HACKTOBER_CHANNEL_ID = 496432022961520650 + HACKTOBER_CHANNEL_ID = 498804484324196362 # chance is 1 in x range, so 1 in 20 range would give 5% chance (for add candy) ADD_CANDY_REACTION_CHANCE = 20 # 5% ADD_CANDY_EXISTING_REACTION_CHANCE = 10 # 10% @@ -27,36 +27,44 @@ class CandyCollection: ADD_SKULL_EXISTING_REACTION_CHANCE = 20 # 5% async def on_message(self, message): - """Make sure the user is not a bot and - the channel is #event-hacktoberfest. - Because the skull has a lower chance of occurring - we'll check for that first, and then add respective reactions""" + """Randomly adds candy or skull to certain messages""" + + # make sure its a human message if message.author.bot: return + # ensure it's hacktober channel if message.channel.id != self.HACKTOBER_CHANNEL_ID: return + + # do random check for skull first as it has the lower chance if random.randint(1, self.ADD_SKULL_REACTION_CHANCE) == 1: d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} self.msg_reacted.append(d) return await message.add_reaction('\N{SKULL}') + # check for the candy chance next if random.randint(1, self.ADD_CANDY_REACTION_CHANCE) == 1: d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} self.msg_reacted.append(d) return await message.add_reaction('\N{CANDY}') async def on_reaction_add(self, reaction, user): - """Make sure the reaction is in #event-hacktoberfest - and the user reacting is not a bot (ie. ourselves) - Check if the reaction is a skull/candy first. """ + """Add/remove candies from a person if the reaction satisfies criteria""" + message = reaction.message - if message.channel.id != self.HACKTOBER_CHANNEL_ID: - return + # check to ensure the reactor is human if user.bot: return + # check to ensure it is in correct channel + if message.channel.id != self.HACKTOBER_CHANNEL_ID: + return + + # if its not a candy or skull, and it is one of 10 most recent messages, + # proceed to add a skull/candy with higher chance if str(reaction.emoji) not in ('\N{SKULL}', '\N{CANDY}'): if message.id in await self.ten_recent_msg(): await self.reacted_msg_chance(message) return + for react in self.msg_reacted: # check to see if the message id of a message we added a # reaction to is in json file, and if nobody has won/claimed it yet @@ -75,10 +83,10 @@ class CandyCollection: else: lost = random.randint(1, 3) user_records['record'] -= lost - await self.send_spook_msg(message.channel, lost) + await self.send_spook_msg(message.author, message.channel, lost) except KeyError: - # otherwise it will raise KeyError so we need to add them + # otherwise it will raise KeyError so we need to add them to file if str(reaction.emoji) == '\N{CANDY}': print('ok') d = {"userid": user.id, "record": 1} @@ -86,8 +94,9 @@ class CandyCollection: await self.remove_reactions(reaction) async def reacted_msg_chance(self, message): - """(Randomly) add a skull or candy to a message if there is a reaction there already + """Randomly add a skull or candy to a message if there is a reaction there already (higher probability)""" + if random.randint(1, self.ADD_SKULL_EXISTING_REACTION_CHANCE) == 1: d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} self.msg_reacted.append(d) @@ -101,59 +110,71 @@ class CandyCollection: async def ten_recent_msg(self): """Get the last 10 messages sent in the channel""" ten_recent = [] - recent_msg = max((x for x in self.bot._connection._messages - if x.channel.id == self.HACKTOBER_CHANNEL_ID), key=lambda x: x.id) + recent_msg = max(message.id for message + in self.bot._connection._messages + if message.channel.id == self.HACKTOBER_CHANNEL_ID) + channel = await self.hacktober_channel() ten_recent.append(recent_msg.id) + for i in range(9): o = discord.Object(id=recent_msg.id + i) msg = await channel.history(limit=1, before=o).next() ten_recent.append(msg.id) + return ten_recent async def get_message(self, msg_id): - """Get the message from it's ID. Use history rather than get_message due to - poor ratelimit (50/1s vs 1/1s)""" + """Get the message from it's ID.""" + try: o = discord.Object(id=msg_id + 1) + # Use history rather than get_message due to + # poor ratelimit (50/1s vs 1/1s) msg = await self.hacktober_channel.history(limit=1, before=o).next() + if msg.id != msg_id: return None + return msg + except Exception: return None async def hacktober_channel(self): - """Get #events-hacktober channel from it's id""" + """Get #hacktoberbot channel from it's id""" return self.bot.get_channel(id=self.HACKTOBER_CHANNEL_ID) async def remove_reactions(self, reaction): """Remove all candy/skull reactions""" + try: async for user in reaction.users(): await reaction.message.remove_reaction(reaction.emoji, user) + except discord.HTTPException: pass - async def send_spook_msg(self, channel, candies): - """Send a (lame) spooky message""" - e = discord.Embed(colour=discord.Member.colour) - e.set_author(name="You went to bed last night and the witch visited your grave." - " She left a message that you will be cursed for as long as you live." - f" You woke up this morning and found that {candies} candies had disappeared") + async def send_spook_msg(self, author, channel, candies): + """Send a spooky message""" + e = discord.Embed(colour=author.colour) + e.set_author(name="Ghosts and Ghouls and Jack o' lanterns at night; " + f"I took {candies} candies and quickly took flight.") await channel.send(embed=e) def save_to_json(self): - """Save json to the file. We will do this with bad practice - async (run_in_executor) to prevent blocking""" + """Save json to the file.""" with open(json_location, 'w') as outfile: json.dump(self.candy_json, outfile) @commands.command() async def candy(self, ctx): """Get the candy leaderboard and save to json when this is called""" + + # use run_in_executor to prevent blocking thing = functools.partial(self.save_to_json) save = await self.bot.loop.run_in_executor(None, thing) + emoji = ( '\N{FIRST PLACE MEDAL}', '\N{SECOND PLACE MEDAL}', @@ -161,8 +182,10 @@ class CandyCollection: '\N{SPORTS MEDAL}', '\N{SPORTS MEDAL}' ) + top_sorted = sorted(self.candy_json['records'], key=lambda k: k.get('record', 0), reverse=True) top_five = top_sorted[:5] + usersid = [] records = [] for record in top_five: @@ -171,6 +194,7 @@ class CandyCollection: value = '\n'.join(f'{emoji[index]} <@{usersid[index]}>: {records[index]}' for index in range(0, len(usersid))) or 'No Candies' + e = discord.Embed(colour=discord.Colour.blurple()) e.add_field(name="Top Candy Records", value=value, inline=False) e.add_field(name='\u200b', -- cgit v1.2.3 From 7960ac4059bad5b464137cbf690c0f802ee66857 Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Fri, 12 Oct 2018 10:47:18 +1100 Subject: Fixed merged conflicts --- bot/cogs/candy_collection.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index 63ce9cb6..8eb6ddf9 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -156,11 +156,7 @@ class CandyCollection: pass async def send_spook_msg(self, author, channel, candies): -<<<<<<< HEAD """Send a spooky message""" -======= - """Send a (lame) spooky message""" ->>>>>>> 4c29c2b470d6f27416a97c3be1e41f753e0a1ea6 e = discord.Embed(colour=author.colour) e.set_author(name="Ghosts and Ghouls and Jack o' lanterns at night; " f"I took {candies} candies and quickly took flight.") -- cgit v1.2.3 From 886e43a3e78cf34c83db73d8c96c52dbbcc16779 Mon Sep 17 00:00:00 2001 From: Derek Fitzpatrick Date: Fri, 12 Oct 2018 00:20:05 -0700 Subject: Refactor monstersurvey. Added leaderboard and show. --- bot/cogs/monstersurvey.py | 177 +++++++++++++------------ bot/resources/monstersurvey/monstersurvey.json | 32 ++++- 2 files changed, 118 insertions(+), 91 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py index 46ab2485..67bc9051 100644 --- a/bot/cogs/monstersurvey.py +++ b/bot/cogs/monstersurvey.py @@ -1,104 +1,107 @@ -import logging -import json -from discord.ext import commands from discord.ext.commands import Bot, Context -import discord from typing import Optional, Tuple -import aiohttp -from http import HTTPStatus +from discord.ext import commands +from discord import Embed +import discord, logging, json, os log = logging.getLogger(__name__) - EMOJIS = { - 'SUCCESS': u"\u2705", - 'ERROR': u"\u274C", + 'SUCCESS': u'\u2705', + 'ERROR': u'\u274C' } -class MonsterSurvey: - - def __init__(self, bot: Bot): - self.bot = Bot - self._monsters = None - @property - def monsters(self) -> dict: - """Always get the most up to date version""" - path = '../bot/resources/monstersurvey/monstersurvey.json' - with open(path, 'r') as f: - self._monsters = json.load(f) - return self._monsters +class MonsterServey: - async def monster_info(self, monster) -> Tuple[Optional[str], Optional[str]]: - """Gets information relating to each monster. This first checks if there - are 'summary' and 'image' keys in the json file. If this fails, it will - attempt to pull summary information from Wikipedia. - """ - async def fetch_url(session: aiohttp.ClientSession, url: str) -> dict: - """Use wikipedia api url calls""" - response = await session.get(url) - if response.status == HTTPStatus.OK: - result = json.loads(await response.text()) - return next(iter(result['query']['pages'].values())) - summary_url = "http://en.wikipedia.org/w/api.php" \ - "?format=json" \ - "&action=query" \ - "&prop=extracts" \ - "&explaintext&exintro" \ - "&redirects=1" \ - f"&titles={monster}" - image_url = "http://en.wikipedia.org/w/api.php" \ - "?action=query" \ - "&prop=pageimages" \ - "&format=json" \ - "&piprop=original" \ - f"&titles={monster}" - async with aiohttp.ClientSession() as s: - summary = self.monsters[monster].get('summary') \ - or (await fetch_url(s, summary_url)).get('extract') - - image = self.monsters[monster].get('image') \ - or (await fetch_url(s, image_url)).get('original', {}).get('source') - return summary, image - - @commands.group(name='monster', aliases=('ms',), invoke_without_command=True) + def __init__(self, bot: Bot): + self.bot = bot + self.registry_location = os.path.join(os.getcwd(), 'resources', 'monstersurvey', 'monstersurvey.json') + with open(self.registry_location, 'r') as jason: + self.voter_registry = json.load(jason) + + @commands.group( + name='monster', + aliases=['ms'] + ) async def monster_group(self, ctx: Context): - pass - - @monster_group.command(name='vote') + if ctx.invoked_subcommand is None: + default_embed = Embed( + title='Monster Voting', + color=0xFF6800, + description='Vote for your favorite monster!' + ) + default_embed.add_field( + name='.monster show monster_name(optional)', + value='Show a specific monster. If none is listed, show a brief of all.', + inline=False) + default_embed.add_field( + name='.monster vote monster_name', + value='Vote for a specific monster. You can vote more than once, but you can only vote for one monster' + 'at a time.', + inline=False + ) + default_embed.add_field( + name='.monster leaderboard', + value='Which monster has the most votes? This command will tell you.', + inline=False + ) + await ctx.send(embed=default_embed) + + @monster_group.command( + name='vote' + ) async def monster_vote(self, ctx: Context, name: Optional[str] = None): - """Casts a vote for a particular monster, or displays a list of all - monsters that are available for voting. - """ - embed = discord.Embed(name='Vote for your favorite monster') - if not name: - for k,v in self.monsters.items(): - msg = f"`.monster show {k}` for more information\n" \ - f"`.monster vote {k}` to cast your vote for this monster." - embed.add_field(name=f"{k}", value=f"{msg}", inline=False) - # TODO: Add logic for voting - await ctx.send(embed=embed) - - @monster_group.command(name='show') - async def monster_show(self, ctx: Context, *monster: str): - """Display a detailed description for the monster, and image.""" - monster = ' '.join(monster) - if self.monsters.get(monster, None): - summary, image = await self.monster_info(monster) - embed = discord.Embed(name=monster) - embed.add_field(name=f"About {monster}", value=summary or "No information") - if image: - embed.set_image(url=image) - embed.set_footer(text=f"To vote for {monster}, type `.monster vote {monster}`") - await ctx.send(embed=embed) - else: - await ctx.message.add_reaction(EMOJIS['ERROR']) - - -def setup(bot: Bot): - bot.add_cog(MonsterSurvey(bot)) + """Casts a vote for a particular monster, or displays a list of monsters that can be voted for + if one is not given.""" + vote_embed = Embed( + name='Monster Voting', + color=0xFF6800 + ) + if name not in self.voter_registry.keys() and name is not None: + vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' + vote_embed.add_field( + name='Use `.monster show {monster_name} for more information on a specific monster', + value='or use `.monster vote {monster}` to cast your vote for said monster.', + inline=False + ) + vote_embed.add_field( + name='You may vote for the following monsters:', + value=f"{', '.join(self.voter_registry.keys())}" + ) + return await ctx.send(embed=vote_embed) + if name is None: + pass + @monster_group.command(name='show') + async def monster_show(self, ctx: Context, name: str): + m = self.voter_registry.get(name) + if not m: + # TODO: invoke .monster vote command to display list + raise commands.BadArgument("Monster does not exist.") + + embed = Embed(title=m['full_name'], color=0xFF6800) + embed.add_field(name='Summary', value=m['summary']) + embed.set_image(url=m['image']) + embed.set_footer(text=f'To vote for this monster, type .monster vote {name}') + await ctx.send(embed=embed) + @monster_group.command(name='leaderboard') + async def monster_leaderboard(self, ctx: Context): + vr = self.voter_registry + top = sorted(vr.values(), key=lambda k: len(k['votes']), reverse=True) + + embed = Embed(title="Leader board", color=0xFF6800) + total_votes = sum(len(m['votes']) for m in self.voter_registry.values()) + for rank, m in enumerate(top): + votes = len(m['votes']) + percentage = ((votes / total_votes) * 100) if total_votes > 0 else 0 + embed.add_field(name=f"{rank+1}. {m['full_name']}", + value=f"{votes} votes. {percentage:.1f}%" + f" of total votes.", inline=False) + await ctx.send(embed=embed) +def setup(bot): + bot.add_cog(MonsterServey(bot)) diff --git a/bot/resources/monstersurvey/monstersurvey.json b/bot/resources/monstersurvey/monstersurvey.json index 7e923dcc..a98870c3 100644 --- a/bot/resources/monstersurvey/monstersurvey.json +++ b/bot/resources/monstersurvey/monstersurvey.json @@ -1,8 +1,32 @@ { - "Frankenstein's Monster": { - "votes": [] - }, - "Count Dracula": { + "frankenstein": { + "full_name": "Frankenstein's Monster", + "summary": "His limbs were in proportion, and I had selected his features as beautiful. Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which they were set, his shrivelled complexion and straight black lips.", + "image": "https://upload.wikimedia.org/wikipedia/commons/a/a7/Frankenstein%27s_monster_%28Boris_Karloff%29.jpg", + "votes": [] + }, + "dracula": { + "full_name": "Count Dracula", + "summary": "Count Dracula is an undead, centuries-old vampire, and a Transylvanian nobleman who claims to be a Székely descended from Attila the Hun. He inhabits a decaying castle in the Carpathian Mountains near the Borgo Pass. Unlike the vampires of Eastern European folklore, which are portrayed as repulsive, corpse-like creatures, Dracula wears a veneer of aristocratic charm. In his conversations with Jonathan Harker, he reveals himself as deeply proud of his boyar heritage and nostalgic for the past, which he admits have become only a memory of heroism, honour and valour in modern times.", + "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg/250px-Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg", + "votes": [] + }, + "blob": { + "full_name": "The Blob", + "summary": "", + "image": "", + "votes": [] + }, + "goofy": { + "full_name": "Goofy in the Monster's INC World", + "summary": "Pure nightmare fuel.\nThis monster is nothing like its original counterpart. With two different eyes, a pointed nose, fins growing out of its blue skin, and dark spots covering his body, he's a true nightmare come to life.", + "image": "https://www.dailydot.com/wp-content/uploads/3a2/a8/bf38aedbef9f795f.png", + "votes": [] + }, + "refisio": { + "full_name": "Refisio", + "summary": "Who let this guy write this? That's who the real monster is.", + "image": "https://avatars0.githubusercontent.com/u/24819750?s=460&v=4", "votes": [] } } -- cgit v1.2.3 From abc481b13a419537b5ee462d1ceb718d1df87503 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Oct 2018 16:45:33 -0400 Subject: Finished MonsterSurvey cog. Added docstrings to all commands, refactored a tiny bit of code within the two commands that you wrote. --- bot/cogs/monstersurvey.py | 92 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 20 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py index 67bc9051..289e56cd 100644 --- a/bot/cogs/monstersurvey.py +++ b/bot/cogs/monstersurvey.py @@ -1,8 +1,9 @@ from discord.ext.commands import Bot, Context -from typing import Optional, Tuple +from asyncio import sleep as asleep +from typing import Optional from discord.ext import commands from discord import Embed -import discord, logging, json, os +import logging, json, os log = logging.getLogger(__name__) @@ -12,19 +13,33 @@ EMOJIS = { } -class MonsterServey: +class MonsterSurvey: + """ + Vote for your favorite monster! + This command allows users to vote for their favorite listed monster. + Users may change their vote, but only their current vote will be counted. + """ def __init__(self, bot: Bot): + """Initializes values for the bot to use within the voting commands.""" self.bot = bot self.registry_location = os.path.join(os.getcwd(), 'resources', 'monstersurvey', 'monstersurvey.json') with open(self.registry_location, 'r') as jason: self.voter_registry = json.load(jason) + def json_write(self): + with open(self.registry_location, 'w') as jason: + json.dump(self.voter_registry, jason, indent=2) + @commands.group( name='monster', aliases=['ms'] ) async def monster_group(self, ctx: Context): + """ + The base voting command. If nothing is called, then it will return an embed. + """ + if ctx.invoked_subcommand is None: default_embed = Embed( title='Monster Voting', @@ -46,7 +61,7 @@ class MonsterServey: value='Which monster has the most votes? This command will tell you.', inline=False ) - await ctx.send(embed=default_embed) + return await ctx.send(embed=default_embed) @monster_group.command( name='vote' @@ -58,42 +73,78 @@ class MonsterServey: name='Monster Voting', color=0xFF6800 ) - if name not in self.voter_registry.keys() and name is not None: - vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' + if name is None or name.lower() not in self.voter_registry.keys(): + if name is not None: + vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' vote_embed.add_field( - name='Use `.monster show {monster_name} for more information on a specific monster', + name='Use `.monster show {monster_name}` for more information on a specific monster', value='or use `.monster vote {monster}` to cast your vote for said monster.', inline=False ) vote_embed.add_field( - name='You may vote for the following monsters:', + name='You may vote for or show the following monsters:', value=f"{', '.join(self.voter_registry.keys())}" ) return await ctx.send(embed=vote_embed) - if name is None: - pass - - + for monster in self.voter_registry.keys(): + if ctx.author.id in self.voter_registry[monster]['votes']: + if name != monster: + self.voter_registry[monster]['votes'].remove(ctx.author.id) + break + else: + vote_embed.add_field( + name='Vote unsuccessful.', + value='You already voted for this monster. ' + 'If you want to change your vote, use another monster.', + inline=False + ) + await ctx.send(embed=vote_embed) + await asleep(.5) + return await ctx.invoke(self.monster_vote) + self.voter_registry[name]['votes'].append(ctx.author.id) + vote_embed.add_field( + name='Vote successful!', + value=f'You have successfully voted for {self.voter_registry[name]["full_name"]}!', + inline=False + ) + vote_embed.set_thumbnail(url=self.voter_registry[name]['image']) + self.json_write() + return await ctx.send(embed=vote_embed) - @monster_group.command(name='show') + @monster_group.command( + name='show' + ) async def monster_show(self, ctx: Context, name: str): + """ + Shows the named monster. If one is not named, it sends the default voting embed instead. + :param ctx: + :param name: + :return: + """ m = self.voter_registry.get(name) if not m: - # TODO: invoke .monster vote command to display list - raise commands.BadArgument("Monster does not exist.") - + await ctx.send('That monster does not exist.') + return await ctx.invoke(self.monster_vote) embed = Embed(title=m['full_name'], color=0xFF6800) embed.add_field(name='Summary', value=m['summary']) embed.set_image(url=m['image']) embed.set_footer(text=f'To vote for this monster, type .monster vote {name}') - await ctx.send(embed=embed) + return await ctx.send(embed=embed) - @monster_group.command(name='leaderboard') + @monster_group.command( + name='leaderboard', + aliases=['lb'] + ) async def monster_leaderboard(self, ctx: Context): + """ + Shows the current standings. + :param ctx: + :return: + """ vr = self.voter_registry top = sorted(vr.values(), key=lambda k: len(k['votes']), reverse=True) - embed = Embed(title="Leader board", color=0xFF6800) + embed = Embed(title="Monster Survey Leader Board", color=0xFF6800) total_votes = sum(len(m['votes']) for m in self.voter_registry.values()) for rank, m in enumerate(top): votes = len(m['votes']) @@ -103,5 +154,6 @@ class MonsterServey: f" of total votes.", inline=False) await ctx.send(embed=embed) + def setup(bot): - bot.add_cog(MonsterServey(bot)) + bot.add_cog(MonsterSurvey(bot)) -- cgit v1.2.3 From 2e71ff8fe3f7482de50b01c917640f21f62a40fe Mon Sep 17 00:00:00 2001 From: Derek Fitzpatrick Date: Fri, 12 Oct 2018 15:38:48 -0700 Subject: Fixed linting: Multiple imports on single line. --- Pipfile | 1 + bot/cogs/monstersurvey.py | 4 +++- bot/resources/monstersurvey/monstersurvey.json | 8 +++++--- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'bot/cogs') diff --git a/Pipfile b/Pipfile index a702616f..158d2787 100644 --- a/Pipfile +++ b/Pipfile @@ -5,6 +5,7 @@ name = "pypi" [packages] "discord.py" = {ref = "rewrite", git = "https://github.com/Rapptz/discord.py"} +"flake8" = "*" [dev-packages] "flake8" = "*" diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py index 289e56cd..dd19d401 100644 --- a/bot/cogs/monstersurvey.py +++ b/bot/cogs/monstersurvey.py @@ -3,7 +3,9 @@ from asyncio import sleep as asleep from typing import Optional from discord.ext import commands from discord import Embed -import logging, json, os +import logging +import json +import os log = logging.getLogger(__name__) diff --git a/bot/resources/monstersurvey/monstersurvey.json b/bot/resources/monstersurvey/monstersurvey.json index a98870c3..016bda3e 100644 --- a/bot/resources/monstersurvey/monstersurvey.json +++ b/bot/resources/monstersurvey/monstersurvey.json @@ -7,9 +7,11 @@ }, "dracula": { "full_name": "Count Dracula", - "summary": "Count Dracula is an undead, centuries-old vampire, and a Transylvanian nobleman who claims to be a Székely descended from Attila the Hun. He inhabits a decaying castle in the Carpathian Mountains near the Borgo Pass. Unlike the vampires of Eastern European folklore, which are portrayed as repulsive, corpse-like creatures, Dracula wears a veneer of aristocratic charm. In his conversations with Jonathan Harker, he reveals himself as deeply proud of his boyar heritage and nostalgic for the past, which he admits have become only a memory of heroism, honour and valour in modern times.", + "summary": "Count Dracula is an undead, centuries-old vampire, and a Transylvanian nobleman who claims to be a Sz\u00c3\u00a9kely descended from Attila the Hun. He inhabits a decaying castle in the Carpathian Mountains near the Borgo Pass. Unlike the vampires of Eastern European folklore, which are portrayed as repulsive, corpse-like creatures, Dracula wears a veneer of aristocratic charm. In his conversations with Jonathan Harker, he reveals himself as deeply proud of his boyar heritage and nostalgic for the past, which he admits have become only a memory of heroism, honour and valour in modern times.", "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg/250px-Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg", - "votes": [] + "votes": [ + 224734305581137921 + ] }, "blob": { "full_name": "The Blob", @@ -29,4 +31,4 @@ "image": "https://avatars0.githubusercontent.com/u/24819750?s=460&v=4", "votes": [] } -} +} \ No newline at end of file -- cgit v1.2.3 From e75a59172674243986bdf73aecb1d61f2e1b3cee Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Sat, 13 Oct 2018 11:31:08 +1100 Subject: Add new line and remove save variable (not used) --- bot/cogs/candy_collection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index 8eb6ddf9..713e1f2f 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -173,7 +173,7 @@ class CandyCollection: # use run_in_executor to prevent blocking thing = functools.partial(self.save_to_json) - save = await self.bot.loop.run_in_executor(None, thing) + await self.bot.loop.run_in_executor(None, thing) emoji = ( '\N{FIRST PLACE MEDAL}', -- cgit v1.2.3 From 6b5ad9c4fc9f431336569ffe7359bc60becb66a1 Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Sat, 13 Oct 2018 11:33:51 +1100 Subject: Remove new line at end of file --- bot/cogs/candy_collection.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index 713e1f2f..b1d47cdb 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -206,5 +206,4 @@ class CandyCollection: def setup(bot): - bot.add_cog(CandyCollection(bot)) - + bot.add_cog(CandyCollection(bot)) \ No newline at end of file -- cgit v1.2.3 From f03debf36a3b0c1155474b6f7b7d5d95478d4170 Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Sat, 13 Oct 2018 11:37:11 +1100 Subject: Add that line back lol --- bot/cogs/candy_collection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index b1d47cdb..b8a36115 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -206,4 +206,4 @@ class CandyCollection: def setup(bot): - bot.add_cog(CandyCollection(bot)) \ No newline at end of file + bot.add_cog(CandyCollection(bot)) -- cgit v1.2.3 From 6efbded6e068dff478ee121ede2ebe74a16292f5 Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Sun, 14 Oct 2018 20:06:36 +1100 Subject: fixed docstring and position of constants --- bot/cogs/candy_collection.py | 67 ++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 24 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/candy_collection.py b/bot/cogs/candy_collection.py index b8a36115..59eadd93 100644 --- a/bot/cogs/candy_collection.py +++ b/bot/cogs/candy_collection.py @@ -7,6 +7,14 @@ import os json_location = os.path.join(os.getcwd(), 'resources', 'candy_collection.json') +HACKTOBER_CHANNEL_ID = 498804484324196362 + +# chance is 1 in x range, so 1 in 20 range would give 5% chance (for add candy) +ADD_CANDY_REACTION_CHANCE = 20 # 5% +ADD_CANDY_EXISTING_REACTION_CHANCE = 10 # 10% +ADD_SKULL_REACTION_CHANCE = 50 # 2% +ADD_SKULL_EXISTING_REACTION_CHANCE = 20 # 5% + class CandyCollection: def __init__(self, bot): @@ -19,43 +27,40 @@ class CandyCollection: userid = userinfo['userid'] self.get_candyinfo[userid] = userinfo - HACKTOBER_CHANNEL_ID = 498804484324196362 - # chance is 1 in x range, so 1 in 20 range would give 5% chance (for add candy) - ADD_CANDY_REACTION_CHANCE = 20 # 5% - ADD_CANDY_EXISTING_REACTION_CHANCE = 10 # 10% - ADD_SKULL_REACTION_CHANCE = 50 # 2% - ADD_SKULL_EXISTING_REACTION_CHANCE = 20 # 5% - async def on_message(self, message): - """Randomly adds candy or skull to certain messages""" + """ + Randomly adds candy or skull to certain messages + """ # make sure its a human message if message.author.bot: return # ensure it's hacktober channel - if message.channel.id != self.HACKTOBER_CHANNEL_ID: + if message.channel.id != HACKTOBER_CHANNEL_ID: return # do random check for skull first as it has the lower chance - if random.randint(1, self.ADD_SKULL_REACTION_CHANCE) == 1: + if random.randint(1, ADD_SKULL_REACTION_CHANCE) == 1: d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} self.msg_reacted.append(d) return await message.add_reaction('\N{SKULL}') # check for the candy chance next - if random.randint(1, self.ADD_CANDY_REACTION_CHANCE) == 1: + if random.randint(1, ADD_CANDY_REACTION_CHANCE) == 1: d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} self.msg_reacted.append(d) return await message.add_reaction('\N{CANDY}') async def on_reaction_add(self, reaction, user): - """Add/remove candies from a person if the reaction satisfies criteria""" + """ + Add/remove candies from a person if the reaction satisfies criteria + """ message = reaction.message # check to ensure the reactor is human if user.bot: return # check to ensure it is in correct channel - if message.channel.id != self.HACKTOBER_CHANNEL_ID: + if message.channel.id != HACKTOBER_CHANNEL_ID: return # if its not a candy or skull, and it is one of 10 most recent messages, @@ -94,15 +99,17 @@ class CandyCollection: await self.remove_reactions(reaction) async def reacted_msg_chance(self, message): - """Randomly add a skull or candy to a message if there is a reaction there already - (higher probability)""" + """ + Randomly add a skull or candy to a message if there is a reaction there already + (higher probability) + """ - if random.randint(1, self.ADD_SKULL_EXISTING_REACTION_CHANCE) == 1: + if random.randint(1, ADD_SKULL_EXISTING_REACTION_CHANCE) == 1: d = {"reaction": '\N{SKULL}', "msg_id": message.id, "won": False} self.msg_reacted.append(d) return await message.add_reaction('\N{SKULL}') - if random.randint(1, self.ADD_CANDY_EXISTING_REACTION_CHANCE) == 1: + if random.randint(1, ADD_CANDY_EXISTING_REACTION_CHANCE) == 1: d = {"reaction": '\N{CANDY}', "msg_id": message.id, "won": False} self.msg_reacted.append(d) return await message.add_reaction('\N{CANDY}') @@ -125,7 +132,9 @@ class CandyCollection: return ten_recent async def get_message(self, msg_id): - """Get the message from it's ID.""" + """ + Get the message from it's ID. + """ try: o = discord.Object(id=msg_id + 1) @@ -142,11 +151,15 @@ class CandyCollection: return None async def hacktober_channel(self): - """Get #hacktoberbot channel from it's id""" - return self.bot.get_channel(id=self.HACKTOBER_CHANNEL_ID) + """ + Get #hacktoberbot channel from it's id + """ + return self.bot.get_channel(id=HACKTOBER_CHANNEL_ID) async def remove_reactions(self, reaction): - """Remove all candy/skull reactions""" + """ + Remove all candy/skull reactions + """ try: async for user in reaction.users(): @@ -156,20 +169,26 @@ class CandyCollection: pass async def send_spook_msg(self, author, channel, candies): - """Send a spooky message""" + """ + Send a spooky message + """ e = discord.Embed(colour=author.colour) e.set_author(name="Ghosts and Ghouls and Jack o' lanterns at night; " f"I took {candies} candies and quickly took flight.") await channel.send(embed=e) def save_to_json(self): - """Save json to the file.""" + """ + Save json to the file. + """ with open(json_location, 'w') as outfile: json.dump(self.candy_json, outfile) @commands.command() async def candy(self, ctx): - """Get the candy leaderboard and save to json when this is called""" + """ + Get the candy leaderboard and save to json when this is called + """ # use run_in_executor to prevent blocking thing = functools.partial(self.save_to_json) -- cgit v1.2.3 From 7d624d9852cb38a50c15c41c074e2ea7301cabca Mon Sep 17 00:00:00 2001 From: mathsman5133 Date: Sun, 14 Oct 2018 20:10:40 +1100 Subject: clean json file --- bot/cogs/resources/candy_collection.json | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/resources/candy_collection.json b/bot/cogs/resources/candy_collection.json index 70dabd05..6313dd10 100644 --- a/bot/cogs/resources/candy_collection.json +++ b/bot/cogs/resources/candy_collection.json @@ -1,25 +1,8 @@ { "msg_reacted": [ - { - "reaction": "\ud83c\udf6c", - "msg_id": 499064137188638730, - "won": true, - "user_reacted": 230214242618441728 - }, - { - "reaction": "\ud83c\udf6c", - "msg_id": 499064204570132500, - "won": false - } + ], "records": [ - { - "userid": 1234567890, - "record": 4 - }, - { - "userid": 9876543210, - "record": 10 - } + ] } -- cgit v1.2.3 From f2a5a5f727b5fd2dfe8e34aa5d5cc9dd06511105 Mon Sep 17 00:00:00 2001 From: Derek Fitzpatrick Date: Wed, 31 Oct 2018 02:37:39 -0700 Subject: Resolved feedback from PR. Resolved lint extra spacing. --- bot/cogs/monstersurvey.py | 45 ++++++++++++++++++-------- bot/resources/monstersurvey/monstersurvey.json | 8 +---- 2 files changed, 32 insertions(+), 21 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py index dd19d401..e59caeee 100644 --- a/bot/cogs/monstersurvey.py +++ b/bot/cogs/monstersurvey.py @@ -1,11 +1,12 @@ -from discord.ext.commands import Bot, Context -from asyncio import sleep as asleep -from typing import Optional -from discord.ext import commands -from discord import Embed -import logging import json +import logging import os +from asyncio import sleep as asleep +from typing import Optional, Union + +from discord import Embed +from discord.ext import commands +from discord.ext.commands import Bot, Context log = logging.getLogger(__name__) @@ -25,11 +26,12 @@ class MonsterSurvey: def __init__(self, bot: Bot): """Initializes values for the bot to use within the voting commands.""" self.bot = bot - self.registry_location = os.path.join(os.getcwd(), 'resources', 'monstersurvey', 'monstersurvey.json') + self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'monstersurvey', 'monstersurvey.json') with open(self.registry_location, 'r') as jason: self.voter_registry = json.load(jason) def json_write(self): + log.info("Saved Monster Survey Results") with open(self.registry_location, 'w') as jason: json.dump(self.voter_registry, jason, indent=2) @@ -50,12 +52,11 @@ class MonsterSurvey: ) default_embed.add_field( name='.monster show monster_name(optional)', - value='Show a specific monster. If none is listed, show a brief of all.', + value='Show a specific monster. If none is listed, it will give you an error with valid choices.', inline=False) default_embed.add_field( name='.monster vote monster_name', - value='Vote for a specific monster. You can vote more than once, but you can only vote for one monster' - 'at a time.', + value='Vote for a specific monster. You get one vote, but can change it at any time.', inline=False ) default_embed.add_field( @@ -68,13 +69,16 @@ class MonsterSurvey: @monster_group.command( name='vote' ) - async def monster_vote(self, ctx: Context, name: Optional[str] = None): + async def monster_vote(self, ctx: Context, name: Optional[Union[int, str]] = None): """Casts a vote for a particular monster, or displays a list of monsters that can be voted for if one is not given.""" vote_embed = Embed( name='Monster Voting', color=0xFF6800 ) + if isinstance(name, int): + name = list(self.voter_registry.keys())[name] + if name is None or name.lower() not in self.voter_registry.keys(): if name is not None: vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' @@ -90,7 +94,7 @@ class MonsterSurvey: return await ctx.send(embed=vote_embed) for monster in self.voter_registry.keys(): if ctx.author.id in self.voter_registry[monster]['votes']: - if name != monster: + if name.lower() != monster: self.voter_registry[monster]['votes'].remove(ctx.author.id) break else: @@ -100,6 +104,7 @@ class MonsterSurvey: 'If you want to change your vote, use another monster.', inline=False ) + log.info(f"{ctx.author.name} Tried to vote for the same monster.") await ctx.send(embed=vote_embed) await asleep(.5) return await ctx.invoke(self.monster_vote) @@ -116,14 +121,25 @@ class MonsterSurvey: @monster_group.command( name='show' ) - async def monster_show(self, ctx: Context, name: str): + async def monster_show(self, ctx: Context, name: Optional[Union[int, str]] = None): """ Shows the named monster. If one is not named, it sends the default voting embed instead. :param ctx: :param name: :return: """ - m = self.voter_registry.get(name) + if name is None: + monster_choices = map(lambda m: f"'{m}'", self.voter_registry.keys()) + monster_choices = ', '.join(monster_choices) + embed = Embed(title="Uh Oh!", + description="I need you to provide a name for your" + f" monster. Choose from {monster_choices}") + await ctx.send(embed=embed) + return + if isinstance(name, int): + m = list(self.voter_registry.values())[name] + else: + m = self.voter_registry.get(name.lower()) if not m: await ctx.send('That monster does not exist.') return await ctx.invoke(self.monster_vote) @@ -159,3 +175,4 @@ class MonsterSurvey: def setup(bot): bot.add_cog(MonsterSurvey(bot)) + log.debug("MonsterSurvey COG Loaded") diff --git a/bot/resources/monstersurvey/monstersurvey.json b/bot/resources/monstersurvey/monstersurvey.json index 016bda3e..6c62e2c1 100644 --- a/bot/resources/monstersurvey/monstersurvey.json +++ b/bot/resources/monstersurvey/monstersurvey.json @@ -13,12 +13,6 @@ 224734305581137921 ] }, - "blob": { - "full_name": "The Blob", - "summary": "", - "image": "", - "votes": [] - }, "goofy": { "full_name": "Goofy in the Monster's INC World", "summary": "Pure nightmare fuel.\nThis monster is nothing like its original counterpart. With two different eyes, a pointed nose, fins growing out of its blue skin, and dark spots covering his body, he's a true nightmare come to life.", @@ -31,4 +25,4 @@ "image": "https://avatars0.githubusercontent.com/u/24819750?s=460&v=4", "votes": [] } -} \ No newline at end of file +} -- cgit v1.2.3 From 755372c2f9981f9c84e534b018193fa6c5632fcb Mon Sep 17 00:00:00 2001 From: Derek Fitzpatrick Date: Wed, 31 Oct 2018 02:54:28 -0700 Subject: Fixed linting issue in hacktoberstats --- bot/cogs/hacktoberstats.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/hacktoberstats.py b/bot/cogs/hacktoberstats.py index adbc5c82..536307cc 100644 --- a/bot/cogs/hacktoberstats.py +++ b/bot/cogs/hacktoberstats.py @@ -22,7 +22,7 @@ class Stats: aliases=('hacktoberstats', 'getstats', 'userstats'), invoke_without_command=True ) - async def hacktoberstats_group(self, ctx: commands.Context, github_username: str=None): + async def hacktoberstats_group(self, ctx: commands.Context, github_username: str = None): """ If invoked without a subcommand or github_username, get the invoking user's stats if they've linked their Discord name to GitHub using .stats link @@ -47,7 +47,7 @@ class Stats: await self.get_stats(ctx, github_username) @hacktoberstats_group.command(name="link") - async def link_user(self, ctx: commands.Context, github_username: str=None): + async def link_user(self, ctx: commands.Context, github_username: str = None): """ Link the invoking user's Github github_username to their Discord ID -- cgit v1.2.3 From b25491bb4f45628460964a43b02b39714e995168 Mon Sep 17 00:00:00 2001 From: Derek Fitzpatrick Date: Wed, 31 Oct 2018 22:29:08 -0700 Subject: Resolved PR comments. --- bot/cogs/monstersurvey.py | 88 +++++++++++++++----------- bot/resources/monstersurvey/monstersurvey.json | 2 +- 2 files changed, 52 insertions(+), 38 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py index e59caeee..9eafcadc 100644 --- a/bot/cogs/monstersurvey.py +++ b/bot/cogs/monstersurvey.py @@ -1,7 +1,6 @@ import json import logging import os -from asyncio import sleep as asleep from typing import Optional, Union from discord import Embed @@ -35,6 +34,28 @@ class MonsterSurvey: with open(self.registry_location, 'w') as jason: json.dump(self.voter_registry, jason, indent=2) + def cast_vote(self, id: int, monster: str): + """ + + :param id: The id of the person voting + :param monster: the string key of the json that represents a monster + :return: None + """ + vr = self.voter_registry + for m in vr.keys(): + if id not in vr[m]['votes'] and m == monster: + vr[m]['votes'].append(id) + else: + if id in vr[m]['votes'] and m != monster: + vr[m]['votes'].remove(id) + + def get_name_by_leaderboard_index(self, n): + n = n - 1 + vr = self.voter_registry + top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True) + name = top[n] if n >= 0 else None + return name + @commands.group( name='monster', aliases=['ms'] @@ -64,6 +85,7 @@ class MonsterSurvey: value='Which monster has the most votes? This command will tell you.', inline=False ) + default_embed.set_footer(text=f"Monsters choices are: {', '.join(self.voter_registry.keys())}") return await ctx.send(embed=default_embed) @monster_group.command( @@ -72,16 +94,21 @@ class MonsterSurvey: async def monster_vote(self, ctx: Context, name: Optional[Union[int, str]] = None): """Casts a vote for a particular monster, or displays a list of monsters that can be voted for if one is not given.""" + if name is None: + await ctx.invoke(self.monster_leaderboard) + return vote_embed = Embed( name='Monster Voting', color=0xFF6800 ) if isinstance(name, int): - name = list(self.voter_registry.keys())[name] + name = self.get_name_by_leaderboard_index(name) + else: + name = name.lower() + m = self.voter_registry.get(name) + if m is None: - if name is None or name.lower() not in self.voter_registry.keys(): - if name is not None: - vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' + vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' vote_embed.add_field( name='Use `.monster show {monster_name}` for more information on a specific monster', value='or use `.monster vote {monster}` to cast your vote for said monster.', @@ -92,29 +119,14 @@ class MonsterSurvey: value=f"{', '.join(self.voter_registry.keys())}" ) return await ctx.send(embed=vote_embed) - for monster in self.voter_registry.keys(): - if ctx.author.id in self.voter_registry[monster]['votes']: - if name.lower() != monster: - self.voter_registry[monster]['votes'].remove(ctx.author.id) - break - else: - vote_embed.add_field( - name='Vote unsuccessful.', - value='You already voted for this monster. ' - 'If you want to change your vote, use another monster.', - inline=False - ) - log.info(f"{ctx.author.name} Tried to vote for the same monster.") - await ctx.send(embed=vote_embed) - await asleep(.5) - return await ctx.invoke(self.monster_vote) - self.voter_registry[name]['votes'].append(ctx.author.id) + self.cast_vote(ctx.author.id, name) vote_embed.add_field( name='Vote successful!', - value=f'You have successfully voted for {self.voter_registry[name]["full_name"]}!', + value=f'You have successfully voted for {m["full_name"]}!', inline=False ) - vote_embed.set_thumbnail(url=self.voter_registry[name]['image']) + vote_embed.set_thumbnail(url=m['image']) + vote_embed.set_footer(text="Please note that any previous votes have been removed.") self.json_write() return await ctx.send(embed=vote_embed) @@ -129,17 +141,13 @@ class MonsterSurvey: :return: """ if name is None: - monster_choices = map(lambda m: f"'{m}'", self.voter_registry.keys()) - monster_choices = ', '.join(monster_choices) - embed = Embed(title="Uh Oh!", - description="I need you to provide a name for your" - f" monster. Choose from {monster_choices}") - await ctx.send(embed=embed) + await ctx.invoke(self.monster_leaderboard) return if isinstance(name, int): - m = list(self.voter_registry.values())[name] + m = self.voter_registry.get(self.get_name_by_leaderboard_index(name)) else: - m = self.voter_registry.get(name.lower()) + name = name.lower() + m = self.voter_registry.get(name) if not m: await ctx.send('That monster does not exist.') return await ctx.invoke(self.monster_vote) @@ -160,16 +168,22 @@ class MonsterSurvey: :return: """ vr = self.voter_registry - top = sorted(vr.values(), key=lambda k: len(k['votes']), reverse=True) + top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True) embed = Embed(title="Monster Survey Leader Board", color=0xFF6800) total_votes = sum(len(m['votes']) for m in self.voter_registry.values()) for rank, m in enumerate(top): - votes = len(m['votes']) + votes = len(vr[m]['votes']) percentage = ((votes / total_votes) * 100) if total_votes > 0 else 0 - embed.add_field(name=f"{rank+1}. {m['full_name']}", - value=f"{votes} votes. {percentage:.1f}%" - f" of total votes.", inline=False) + embed.add_field(name=f"{rank+1}. {vr[m]['full_name']}", + value=f"{votes} votes. {percentage:.1f}% of total votes.\n" + f"Vote for this monster by typing " + f"'.monster vote {m}'\n" + f"Get more information on this monster by typing " + f"'.monster show {m}'", + inline=False) + + embed.set_footer(text="You can also vote by their rank number. '.monster vote {number}' ") await ctx.send(embed=embed) diff --git a/bot/resources/monstersurvey/monstersurvey.json b/bot/resources/monstersurvey/monstersurvey.json index 6c62e2c1..209f1cbb 100644 --- a/bot/resources/monstersurvey/monstersurvey.json +++ b/bot/resources/monstersurvey/monstersurvey.json @@ -25,4 +25,4 @@ "image": "https://avatars0.githubusercontent.com/u/24819750?s=460&v=4", "votes": [] } -} +} \ No newline at end of file -- cgit v1.2.3 From 1025b0bca5846a4fb34ffb30333ffa9df7978ae0 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 20 Nov 2018 02:03:07 +0100 Subject: Reverting changes on the conflicting file. --- bot/cogs/hacktober/hacktoberstats.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot/cogs') diff --git a/bot/cogs/hacktober/hacktoberstats.py b/bot/cogs/hacktober/hacktoberstats.py index 0755503c..092e5ca8 100644 --- a/bot/cogs/hacktober/hacktoberstats.py +++ b/bot/cogs/hacktober/hacktoberstats.py @@ -22,7 +22,7 @@ class Stats: aliases=('hacktoberstats', 'getstats', 'userstats'), invoke_without_command=True ) - async def hacktoberstats_group(self, ctx: commands.Context, github_username: str = None): + async def hacktoberstats_group(self, ctx: commands.Context, github_username: str=None): """ If invoked without a subcommand or github_username, get the invoking user's stats if they've linked their Discord name to GitHub using .stats link @@ -47,7 +47,7 @@ class Stats: await self.get_stats(ctx, github_username) @hacktoberstats_group.command(name="link") - async def link_user(self, ctx: commands.Context, github_username: str = None): + async def link_user(self, ctx: commands.Context, github_username: str=None): """ Link the invoking user's Github github_username to their Discord ID -- cgit v1.2.3 From abd44273967ba2eb8432337069e4dec345ef0982 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 20 Nov 2018 02:06:18 +0100 Subject: Adding the files this PR was supposed to have --- bot/cogs/hacktober/monstersurvey.py | 192 +++++++++++++++++++++++++++ bot/resources/halloween/halloween_facts.json | 14 ++ bot/resources/halloween/halloweenify.json | 82 ++++++++++++ bot/resources/halloween/monstersurvey.json | 28 ++++ bot/resources/halloween_facts.json | 14 -- bot/resources/halloweenify.json | 82 ------------ 6 files changed, 316 insertions(+), 96 deletions(-) create mode 100644 bot/cogs/hacktober/monstersurvey.py create mode 100644 bot/resources/halloween/halloween_facts.json create mode 100644 bot/resources/halloween/halloweenify.json create mode 100644 bot/resources/halloween/monstersurvey.json delete mode 100644 bot/resources/halloween_facts.json delete mode 100644 bot/resources/halloweenify.json (limited to 'bot/cogs') diff --git a/bot/cogs/hacktober/monstersurvey.py b/bot/cogs/hacktober/monstersurvey.py new file mode 100644 index 00000000..376ac1fa --- /dev/null +++ b/bot/cogs/hacktober/monstersurvey.py @@ -0,0 +1,192 @@ +import json +import logging +import os +from typing import Optional, Union + +from discord import Embed +from discord.ext import commands +from discord.ext.commands import Bot, Context + +log = logging.getLogger(__name__) + +EMOJIS = { + 'SUCCESS': u'\u2705', + 'ERROR': u'\u274C' +} + + +class MonsterSurvey: + """ + Vote for your favorite monster! + This command allows users to vote for their favorite listed monster. + Users may change their vote, but only their current vote will be counted. + """ + + def __init__(self, bot: Bot): + """Initializes values for the bot to use within the voting commands.""" + self.bot = bot + self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'halloween', 'monstersurvey.json') + with open(self.registry_location, 'r') as jason: + self.voter_registry = json.load(jason) + + def json_write(self): + log.info("Saved Monster Survey Results") + with open(self.registry_location, 'w') as jason: + json.dump(self.voter_registry, jason, indent=2) + + def cast_vote(self, id: int, monster: str): + """ + + :param id: The id of the person voting + :param monster: the string key of the json that represents a monster + :return: None + """ + vr = self.voter_registry + for m in vr.keys(): + if id not in vr[m]['votes'] and m == monster: + vr[m]['votes'].append(id) + else: + if id in vr[m]['votes'] and m != monster: + vr[m]['votes'].remove(id) + + def get_name_by_leaderboard_index(self, n): + n = n - 1 + vr = self.voter_registry + top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True) + name = top[n] if n >= 0 else None + return name + + @commands.group( + name='monster', + aliases=['ms'] + ) + async def monster_group(self, ctx: Context): + """ + The base voting command. If nothing is called, then it will return an embed. + """ + + if ctx.invoked_subcommand is None: + default_embed = Embed( + title='Monster Voting', + color=0xFF6800, + description='Vote for your favorite monster!' + ) + default_embed.add_field( + name='.monster show monster_name(optional)', + value='Show a specific monster. If none is listed, it will give you an error with valid choices.', + inline=False) + default_embed.add_field( + name='.monster vote monster_name', + value='Vote for a specific monster. You get one vote, but can change it at any time.', + inline=False + ) + default_embed.add_field( + name='.monster leaderboard', + value='Which monster has the most votes? This command will tell you.', + inline=False + ) + default_embed.set_footer(text=f"Monsters choices are: {', '.join(self.voter_registry.keys())}") + return await ctx.send(embed=default_embed) + + @monster_group.command( + name='vote' + ) + async def monster_vote(self, ctx: Context, name: Optional[Union[int, str]] = None): + """Casts a vote for a particular monster, or displays a list of monsters that can be voted for + if one is not given.""" + if name is None: + await ctx.invoke(self.monster_leaderboard) + return + vote_embed = Embed( + name='Monster Voting', + color=0xFF6800 + ) + if isinstance(name, int): + name = self.get_name_by_leaderboard_index(name) + else: + name = name.lower() + m = self.voter_registry.get(name) + if m is None: + + vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' + vote_embed.add_field( + name='Use `.monster show {monster_name}` for more information on a specific monster', + value='or use `.monster vote {monster}` to cast your vote for said monster.', + inline=False + ) + vote_embed.add_field( + name='You may vote for or show the following monsters:', + value=f"{', '.join(self.voter_registry.keys())}" + ) + return await ctx.send(embed=vote_embed) + self.cast_vote(ctx.author.id, name) + vote_embed.add_field( + name='Vote successful!', + value=f'You have successfully voted for {m["full_name"]}!', + inline=False + ) + vote_embed.set_thumbnail(url=m['image']) + vote_embed.set_footer(text="Please note that any previous votes have been removed.") + self.json_write() + return await ctx.send(embed=vote_embed) + + @monster_group.command( + name='show' + ) + async def monster_show(self, ctx: Context, name: Optional[Union[int, str]] = None): + """ + Shows the named monster. If one is not named, it sends the default voting embed instead. + :param ctx: + :param name: + :return: + """ + if name is None: + await ctx.invoke(self.monster_leaderboard) + return + if isinstance(name, int): + m = self.voter_registry.get(self.get_name_by_leaderboard_index(name)) + else: + name = name.lower() + m = self.voter_registry.get(name) + if not m: + await ctx.send('That monster does not exist.') + return await ctx.invoke(self.monster_vote) + embed = Embed(title=m['full_name'], color=0xFF6800) + embed.add_field(name='Summary', value=m['summary']) + embed.set_image(url=m['image']) + embed.set_footer(text=f'To vote for this monster, type .monster vote {name}') + return await ctx.send(embed=embed) + + @monster_group.command( + name='leaderboard', + aliases=['lb'] + ) + async def monster_leaderboard(self, ctx: Context): + """ + Shows the current standings. + :param ctx: + :return: + """ + vr = self.voter_registry + top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True) + + embed = Embed(title="Monster Survey Leader Board", color=0xFF6800) + total_votes = sum(len(m['votes']) for m in self.voter_registry.values()) + for rank, m in enumerate(top): + votes = len(vr[m]['votes']) + percentage = ((votes / total_votes) * 100) if total_votes > 0 else 0 + embed.add_field(name=f"{rank+1}. {vr[m]['full_name']}", + value=f"{votes} votes. {percentage:.1f}% of total votes.\n" + f"Vote for this monster by typing " + f"'.monster vote {m}'\n" + f"Get more information on this monster by typing " + f"'.monster show {m}'", + inline=False) + + embed.set_footer(text="You can also vote by their rank number. '.monster vote {number}' ") + await ctx.send(embed=embed) + + +def setup(bot): + bot.add_cog(MonsterSurvey(bot)) + log.debug("MonsterSurvey COG Loaded") diff --git a/bot/resources/halloween/halloween_facts.json b/bot/resources/halloween/halloween_facts.json new file mode 100644 index 00000000..fc6fa85f --- /dev/null +++ b/bot/resources/halloween/halloween_facts.json @@ -0,0 +1,14 @@ +[ + "Halloween or Hallowe'en is also known as Allhalloween, All Hallows' Eve and All Saints' Eve.", + "It is widely believed that many Halloween traditions originated from ancient Celtic harvest festivals, particularly the Gaelic festival Samhain, which means \"summer's end\".", + "It is believed that the custom of making jack-o'-lanterns at Halloween began in Ireland. In the 19th century, turnips or mangel wurzels, hollowed out to act as lanterns and often carved with grotesque faces, were used at Halloween in parts of Ireland and the Scottish Highlands.", + "Halloween is the second highest grossing commercial holiday after Christmas.", + "The word \"witch\" comes from the Old English *wicce*, meaning \"wise woman\". In fact, *wiccan* were highly respected people at one time. According to popular belief, witches held one of their two main meetings, or *sabbats*, on Halloween night.", + "Samhainophobia is the fear of Halloween.", + "The owl is a popular Halloween image. In Medieval Europe, owls were thought to be witches, and to hear an owl's call meant someone was about to die.", + "An Irish legend about jack-o'-lanterns goes as follows:\n*On route home after a night's drinking, Jack encounters the Devil and tricks him into climbing a tree. A quick-thinking Jack etches the sign of the cross into the bark, thus trapping the Devil. Jack strikes a bargain that Satan can never claim his soul. After a life of sin, drink, and mendacity, Jack is refused entry to heaven when he dies. Keeping his promise, the Devil refuses to let Jack into hell and throws a live coal straight from the fires of hell at him. It was a cold night, so Jack places the coal in a hollowed out turnip to stop it from going out, since which time Jack and his lantern have been roaming looking for a place to rest.*", + "Trick-or-treating evolved from the ancient Celtic tradition of putting out treats and food to placate spirits who roamed the streets at Samhain, a sacred festival that marked the end of the Celtic calendar year.", + "Comedian John Evans once quipped: \"What do you get if you divide the circumference of a jack-o’-lantern by its diameter? Pumpkin π.\"", + "Dressing up as ghouls and other spooks originated from the ancient Celtic tradition of townspeople disguising themselves as demons and spirits. The Celts believed that disguising themselves this way would allow them to escape the notice of the real spirits wandering the streets during Samhain.", + "In Western history, black cats have typically been looked upon as a symbol of evil omens, specifically being suspected of being the familiars of witches, or actually shape-shifting witches themselves. They are, however, too cute to be evil." +] diff --git a/bot/resources/halloween/halloweenify.json b/bot/resources/halloween/halloweenify.json new file mode 100644 index 00000000..88c46bfc --- /dev/null +++ b/bot/resources/halloween/halloweenify.json @@ -0,0 +1,82 @@ +{ + "characters": [ + { + "Michael Myers": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f57x2f9353301x2fwzqoqvitx2fuqkpimt-ugmza-x78pwbw-c95x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Jason Voorhees": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f42x2f9050161x2fwzqoqvitx2friawv-dwwzpmma-nqtu-kpizikbmza-x78pwbw-c1x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Freddy Krueger": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f30x2f9800154x2fwzqoqvitx2fnzmllg-szcmomz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Pennywise the Dancing Clown": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f436x2f91927608x2fwzqoqvitx2fx78mvvgeqam-bpm-livkqvo-ktwev-nqtu-kpizikbmza-x78pwbw-c0x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Charles Lee Ray": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f14x2f581261x2fwzqoqvitx2fkpiztma-tmm-zig-c90x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Leatherface": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f50x2f9204163x2fwzqoqvitx2ftmibpmznikm-c08x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Jack Torrance": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f41x2f9032825x2fwzqoqvitx2friks-bwzzivkm-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Ghostface": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f32x2f9845748x2fwzqoqvitx2fopwabnikm-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Regan MacNeil": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f73x2f9665843x2fwzqoqvitx2fzmoiv-uikvmqt-zmkwzlqvo-izbqaba-ivl-ozwcx78a-x78pwbw-c1x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Hannibal Lecter": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f35x2f9903368x2fwzqoqvitx2fpivvqjit-tmkbmz-nqtu-kpizikbmza-x78pwbw-c99x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Samara Morgan": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f77x2f9744082x2fwzqoqvitx2faiuizi-uwzoiv-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Pinhead": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f79x2f9683232x2fwzqoqvitx2fx78qvpmil-nqtu-kpizikbmza-x78pwbw-c4x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Bruce": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f2047x2f63159728x2fwzqoqvitx2friea-c3x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Xenomorph": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f909x2f0297919x2fwzqoqvitx2ffmvwuwzx78p-x78pwbw-c91x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "The Thing": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f1947x2f41148806x2fwzqoqvitx2fbpm-bpqvo-x78pwbw-c6x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Sadako Yamamura": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f76x2f9735755x2fwzqoqvitx2failisw-giuiuczi-c4x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Jigsaw Killer": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f43x2f9065767x2fwzqoqvitx2frqoaie-sqttmz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Norman Bates": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f63x2f9467317x2fwzqoqvitx2fvwzuiv-jibma-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Candyman": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f255x2f7305168x2fwzqoqvitx2fkivlguiv-c5x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "The Creeper": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f998x2f0963452x2fwzqoqvitx2fbpm-kzmmx78mz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Damien Thorn": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f29x2f685981x2fwzqoqvitx2fliuqmv-bpwzv-x78pwbw-c1x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Joker": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f903x2f0276049x2fwzqoqvitx2frwsmz-c71x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Cujo": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f1581x2f52837948x2fwzqoqvitx2fkcrw-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Gage Creed": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f1968x2f41364699x2fwzqoqvitx2foiom-kzmml-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Chatterer": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f14x2f586061x2fwzqoqvitx2fkpibbmzmz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" + }, + { + "Pale Man": "https://i2.wp.com/macguff.in/wp-content/uploads/2016/10/Pans-Labyrinth-Movie-Header-Image.jpg?fit=630%2C400&ssl=1" + } + ] +} \ No newline at end of file diff --git a/bot/resources/halloween/monstersurvey.json b/bot/resources/halloween/monstersurvey.json new file mode 100644 index 00000000..6c62e2c1 --- /dev/null +++ b/bot/resources/halloween/monstersurvey.json @@ -0,0 +1,28 @@ +{ + "frankenstein": { + "full_name": "Frankenstein's Monster", + "summary": "His limbs were in proportion, and I had selected his features as beautiful. Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which they were set, his shrivelled complexion and straight black lips.", + "image": "https://upload.wikimedia.org/wikipedia/commons/a/a7/Frankenstein%27s_monster_%28Boris_Karloff%29.jpg", + "votes": [] + }, + "dracula": { + "full_name": "Count Dracula", + "summary": "Count Dracula is an undead, centuries-old vampire, and a Transylvanian nobleman who claims to be a Sz\u00c3\u00a9kely descended from Attila the Hun. He inhabits a decaying castle in the Carpathian Mountains near the Borgo Pass. Unlike the vampires of Eastern European folklore, which are portrayed as repulsive, corpse-like creatures, Dracula wears a veneer of aristocratic charm. In his conversations with Jonathan Harker, he reveals himself as deeply proud of his boyar heritage and nostalgic for the past, which he admits have become only a memory of heroism, honour and valour in modern times.", + "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg/250px-Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg", + "votes": [ + 224734305581137921 + ] + }, + "goofy": { + "full_name": "Goofy in the Monster's INC World", + "summary": "Pure nightmare fuel.\nThis monster is nothing like its original counterpart. With two different eyes, a pointed nose, fins growing out of its blue skin, and dark spots covering his body, he's a true nightmare come to life.", + "image": "https://www.dailydot.com/wp-content/uploads/3a2/a8/bf38aedbef9f795f.png", + "votes": [] + }, + "refisio": { + "full_name": "Refisio", + "summary": "Who let this guy write this? That's who the real monster is.", + "image": "https://avatars0.githubusercontent.com/u/24819750?s=460&v=4", + "votes": [] + } +} diff --git a/bot/resources/halloween_facts.json b/bot/resources/halloween_facts.json deleted file mode 100644 index fc6fa85f..00000000 --- a/bot/resources/halloween_facts.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - "Halloween or Hallowe'en is also known as Allhalloween, All Hallows' Eve and All Saints' Eve.", - "It is widely believed that many Halloween traditions originated from ancient Celtic harvest festivals, particularly the Gaelic festival Samhain, which means \"summer's end\".", - "It is believed that the custom of making jack-o'-lanterns at Halloween began in Ireland. In the 19th century, turnips or mangel wurzels, hollowed out to act as lanterns and often carved with grotesque faces, were used at Halloween in parts of Ireland and the Scottish Highlands.", - "Halloween is the second highest grossing commercial holiday after Christmas.", - "The word \"witch\" comes from the Old English *wicce*, meaning \"wise woman\". In fact, *wiccan* were highly respected people at one time. According to popular belief, witches held one of their two main meetings, or *sabbats*, on Halloween night.", - "Samhainophobia is the fear of Halloween.", - "The owl is a popular Halloween image. In Medieval Europe, owls were thought to be witches, and to hear an owl's call meant someone was about to die.", - "An Irish legend about jack-o'-lanterns goes as follows:\n*On route home after a night's drinking, Jack encounters the Devil and tricks him into climbing a tree. A quick-thinking Jack etches the sign of the cross into the bark, thus trapping the Devil. Jack strikes a bargain that Satan can never claim his soul. After a life of sin, drink, and mendacity, Jack is refused entry to heaven when he dies. Keeping his promise, the Devil refuses to let Jack into hell and throws a live coal straight from the fires of hell at him. It was a cold night, so Jack places the coal in a hollowed out turnip to stop it from going out, since which time Jack and his lantern have been roaming looking for a place to rest.*", - "Trick-or-treating evolved from the ancient Celtic tradition of putting out treats and food to placate spirits who roamed the streets at Samhain, a sacred festival that marked the end of the Celtic calendar year.", - "Comedian John Evans once quipped: \"What do you get if you divide the circumference of a jack-o’-lantern by its diameter? Pumpkin π.\"", - "Dressing up as ghouls and other spooks originated from the ancient Celtic tradition of townspeople disguising themselves as demons and spirits. The Celts believed that disguising themselves this way would allow them to escape the notice of the real spirits wandering the streets during Samhain.", - "In Western history, black cats have typically been looked upon as a symbol of evil omens, specifically being suspected of being the familiars of witches, or actually shape-shifting witches themselves. They are, however, too cute to be evil." -] diff --git a/bot/resources/halloweenify.json b/bot/resources/halloweenify.json deleted file mode 100644 index 88c46bfc..00000000 --- a/bot/resources/halloweenify.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "characters": [ - { - "Michael Myers": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f57x2f9353301x2fwzqoqvitx2fuqkpimt-ugmza-x78pwbw-c95x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Jason Voorhees": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f42x2f9050161x2fwzqoqvitx2friawv-dwwzpmma-nqtu-kpizikbmza-x78pwbw-c1x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Freddy Krueger": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f30x2f9800154x2fwzqoqvitx2fnzmllg-szcmomz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Pennywise the Dancing Clown": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f436x2f91927608x2fwzqoqvitx2fx78mvvgeqam-bpm-livkqvo-ktwev-nqtu-kpizikbmza-x78pwbw-c0x3fex3d438x26yx3d38x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Charles Lee Ray": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f14x2f581261x2fwzqoqvitx2fkpiztma-tmm-zig-c90x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Leatherface": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f50x2f9204163x2fwzqoqvitx2ftmibpmznikm-c08x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Jack Torrance": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f41x2f9032825x2fwzqoqvitx2friks-bwzzivkm-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Ghostface": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f32x2f9845748x2fwzqoqvitx2fopwabnikm-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Regan MacNeil": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f73x2f9665843x2fwzqoqvitx2fzmoiv-uikvmqt-zmkwzlqvo-izbqaba-ivl-ozwcx78a-x78pwbw-c1x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Hannibal Lecter": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f35x2f9903368x2fwzqoqvitx2fpivvqjit-tmkbmz-nqtu-kpizikbmza-x78pwbw-c99x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Samara Morgan": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f77x2f9744082x2fwzqoqvitx2faiuizi-uwzoiv-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Pinhead": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f79x2f9683232x2fwzqoqvitx2fx78qvpmil-nqtu-kpizikbmza-x78pwbw-c4x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Bruce": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f2047x2f63159728x2fwzqoqvitx2friea-c3x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Xenomorph": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f909x2f0297919x2fwzqoqvitx2ffmvwuwzx78p-x78pwbw-c91x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "The Thing": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f1947x2f41148806x2fwzqoqvitx2fbpm-bpqvo-x78pwbw-c6x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Sadako Yamamura": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f76x2f9735755x2fwzqoqvitx2failisw-giuiuczi-c4x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Jigsaw Killer": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f43x2f9065767x2fwzqoqvitx2frqoaie-sqttmz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Norman Bates": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f63x2f9467317x2fwzqoqvitx2fvwzuiv-jibma-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Candyman": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f255x2f7305168x2fwzqoqvitx2fkivlguiv-c5x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "The Creeper": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f998x2f0963452x2fwzqoqvitx2fbpm-kzmmx78mz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Damien Thorn": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f29x2f685981x2fwzqoqvitx2fliuqmv-bpwzv-x78pwbw-c1x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Joker": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f903x2f0276049x2fwzqoqvitx2frwsmz-c71x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Cujo": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f1581x2f52837948x2fwzqoqvitx2fkcrw-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Gage Creed": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fcamz_vwlm_quox2f1968x2f41364699x2fwzqoqvitx2foiom-kzmml-nqtu-kpizikbmza-x78pwbw-c9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Chatterer": "https://c-5uwzmx78pmca09x24quoqfx2ezivsmzx2ekwu.g00.ranker.com/g00/3_c-5eee.zivsmz.kwu_/c-5UWZMXPMCA09x24pbbx78ax3ax2fx2fquoqf.zivsmz.kwux2fvwlm_quox2f14x2f586061x2fwzqoqvitx2fkpibbmzmz-nqtu-kpizikbmza-x78pwbw-9x3fex3d438x26yx3d48x26nux3drx78ox26nqbx3dkzwx78x26kzwx78x3dnikmax22x26q98k.uizsx3dquiom_$/$/$/$/$/$" - }, - { - "Pale Man": "https://i2.wp.com/macguff.in/wp-content/uploads/2016/10/Pans-Labyrinth-Movie-Header-Image.jpg?fit=630%2C400&ssl=1" - } - ] -} \ No newline at end of file -- cgit v1.2.3 From 2262f684e03d004ad65bf023eca7e649489b891f Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 20 Nov 2018 02:09:20 +0100 Subject: Minor changes --- bot/__main__.py | 4 +- bot/cogs/hacktober/monstersurvey.py | 2 +- bot/cogs/monstersurvey.py | 192 ------------------------- bot/resources/monstersurvey/monstersurvey.json | 28 ---- 4 files changed, 3 insertions(+), 223 deletions(-) delete mode 100644 bot/cogs/monstersurvey.py delete mode 100644 bot/resources/monstersurvey/monstersurvey.json (limited to 'bot/cogs') diff --git a/bot/__main__.py b/bot/__main__.py index a1484cbc..b2b2c5fd 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -22,10 +22,10 @@ log.info('Start loading extensions from ./bot/cogs/evergreen/') if __name__ == '__main__': # Scan for files in the /cogs/ directory and make a list of the file names. - cogs = [file.stem for file in Path('bot', 'cogs', 'evergreen').glob('*.py') if not file.stem.startswith("__")] + cogs = [file.stem for file in Path('bot', 'cogs', 'halloween').glob('*.py') if not file.stem.startswith("__")] for extension in cogs: try: - bot.load_extension(f'bot.cogs.evergreen.{extension}') + bot.load_extension(f'bot.cogs.halloween.{extension}') log.info(f'Successfully loaded extension: {extension}') except Exception as e: log.error(f'Failed to load extension {extension}: {repr(e)} {format_exc()}') diff --git a/bot/cogs/hacktober/monstersurvey.py b/bot/cogs/hacktober/monstersurvey.py index 376ac1fa..9eafcadc 100644 --- a/bot/cogs/hacktober/monstersurvey.py +++ b/bot/cogs/hacktober/monstersurvey.py @@ -25,7 +25,7 @@ class MonsterSurvey: def __init__(self, bot: Bot): """Initializes values for the bot to use within the voting commands.""" self.bot = bot - self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'halloween', 'monstersurvey.json') + self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'monstersurvey', 'monstersurvey.json') with open(self.registry_location, 'r') as jason: self.voter_registry = json.load(jason) diff --git a/bot/cogs/monstersurvey.py b/bot/cogs/monstersurvey.py deleted file mode 100644 index 9eafcadc..00000000 --- a/bot/cogs/monstersurvey.py +++ /dev/null @@ -1,192 +0,0 @@ -import json -import logging -import os -from typing import Optional, Union - -from discord import Embed -from discord.ext import commands -from discord.ext.commands import Bot, Context - -log = logging.getLogger(__name__) - -EMOJIS = { - 'SUCCESS': u'\u2705', - 'ERROR': u'\u274C' -} - - -class MonsterSurvey: - """ - Vote for your favorite monster! - This command allows users to vote for their favorite listed monster. - Users may change their vote, but only their current vote will be counted. - """ - - def __init__(self, bot: Bot): - """Initializes values for the bot to use within the voting commands.""" - self.bot = bot - self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'monstersurvey', 'monstersurvey.json') - with open(self.registry_location, 'r') as jason: - self.voter_registry = json.load(jason) - - def json_write(self): - log.info("Saved Monster Survey Results") - with open(self.registry_location, 'w') as jason: - json.dump(self.voter_registry, jason, indent=2) - - def cast_vote(self, id: int, monster: str): - """ - - :param id: The id of the person voting - :param monster: the string key of the json that represents a monster - :return: None - """ - vr = self.voter_registry - for m in vr.keys(): - if id not in vr[m]['votes'] and m == monster: - vr[m]['votes'].append(id) - else: - if id in vr[m]['votes'] and m != monster: - vr[m]['votes'].remove(id) - - def get_name_by_leaderboard_index(self, n): - n = n - 1 - vr = self.voter_registry - top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True) - name = top[n] if n >= 0 else None - return name - - @commands.group( - name='monster', - aliases=['ms'] - ) - async def monster_group(self, ctx: Context): - """ - The base voting command. If nothing is called, then it will return an embed. - """ - - if ctx.invoked_subcommand is None: - default_embed = Embed( - title='Monster Voting', - color=0xFF6800, - description='Vote for your favorite monster!' - ) - default_embed.add_field( - name='.monster show monster_name(optional)', - value='Show a specific monster. If none is listed, it will give you an error with valid choices.', - inline=False) - default_embed.add_field( - name='.monster vote monster_name', - value='Vote for a specific monster. You get one vote, but can change it at any time.', - inline=False - ) - default_embed.add_field( - name='.monster leaderboard', - value='Which monster has the most votes? This command will tell you.', - inline=False - ) - default_embed.set_footer(text=f"Monsters choices are: {', '.join(self.voter_registry.keys())}") - return await ctx.send(embed=default_embed) - - @monster_group.command( - name='vote' - ) - async def monster_vote(self, ctx: Context, name: Optional[Union[int, str]] = None): - """Casts a vote for a particular monster, or displays a list of monsters that can be voted for - if one is not given.""" - if name is None: - await ctx.invoke(self.monster_leaderboard) - return - vote_embed = Embed( - name='Monster Voting', - color=0xFF6800 - ) - if isinstance(name, int): - name = self.get_name_by_leaderboard_index(name) - else: - name = name.lower() - m = self.voter_registry.get(name) - if m is None: - - vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.' - vote_embed.add_field( - name='Use `.monster show {monster_name}` for more information on a specific monster', - value='or use `.monster vote {monster}` to cast your vote for said monster.', - inline=False - ) - vote_embed.add_field( - name='You may vote for or show the following monsters:', - value=f"{', '.join(self.voter_registry.keys())}" - ) - return await ctx.send(embed=vote_embed) - self.cast_vote(ctx.author.id, name) - vote_embed.add_field( - name='Vote successful!', - value=f'You have successfully voted for {m["full_name"]}!', - inline=False - ) - vote_embed.set_thumbnail(url=m['image']) - vote_embed.set_footer(text="Please note that any previous votes have been removed.") - self.json_write() - return await ctx.send(embed=vote_embed) - - @monster_group.command( - name='show' - ) - async def monster_show(self, ctx: Context, name: Optional[Union[int, str]] = None): - """ - Shows the named monster. If one is not named, it sends the default voting embed instead. - :param ctx: - :param name: - :return: - """ - if name is None: - await ctx.invoke(self.monster_leaderboard) - return - if isinstance(name, int): - m = self.voter_registry.get(self.get_name_by_leaderboard_index(name)) - else: - name = name.lower() - m = self.voter_registry.get(name) - if not m: - await ctx.send('That monster does not exist.') - return await ctx.invoke(self.monster_vote) - embed = Embed(title=m['full_name'], color=0xFF6800) - embed.add_field(name='Summary', value=m['summary']) - embed.set_image(url=m['image']) - embed.set_footer(text=f'To vote for this monster, type .monster vote {name}') - return await ctx.send(embed=embed) - - @monster_group.command( - name='leaderboard', - aliases=['lb'] - ) - async def monster_leaderboard(self, ctx: Context): - """ - Shows the current standings. - :param ctx: - :return: - """ - vr = self.voter_registry - top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True) - - embed = Embed(title="Monster Survey Leader Board", color=0xFF6800) - total_votes = sum(len(m['votes']) for m in self.voter_registry.values()) - for rank, m in enumerate(top): - votes = len(vr[m]['votes']) - percentage = ((votes / total_votes) * 100) if total_votes > 0 else 0 - embed.add_field(name=f"{rank+1}. {vr[m]['full_name']}", - value=f"{votes} votes. {percentage:.1f}% of total votes.\n" - f"Vote for this monster by typing " - f"'.monster vote {m}'\n" - f"Get more information on this monster by typing " - f"'.monster show {m}'", - inline=False) - - embed.set_footer(text="You can also vote by their rank number. '.monster vote {number}' ") - await ctx.send(embed=embed) - - -def setup(bot): - bot.add_cog(MonsterSurvey(bot)) - log.debug("MonsterSurvey COG Loaded") diff --git a/bot/resources/monstersurvey/monstersurvey.json b/bot/resources/monstersurvey/monstersurvey.json deleted file mode 100644 index 209f1cbb..00000000 --- a/bot/resources/monstersurvey/monstersurvey.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "frankenstein": { - "full_name": "Frankenstein's Monster", - "summary": "His limbs were in proportion, and I had selected his features as beautiful. Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which they were set, his shrivelled complexion and straight black lips.", - "image": "https://upload.wikimedia.org/wikipedia/commons/a/a7/Frankenstein%27s_monster_%28Boris_Karloff%29.jpg", - "votes": [] - }, - "dracula": { - "full_name": "Count Dracula", - "summary": "Count Dracula is an undead, centuries-old vampire, and a Transylvanian nobleman who claims to be a Sz\u00c3\u00a9kely descended from Attila the Hun. He inhabits a decaying castle in the Carpathian Mountains near the Borgo Pass. Unlike the vampires of Eastern European folklore, which are portrayed as repulsive, corpse-like creatures, Dracula wears a veneer of aristocratic charm. In his conversations with Jonathan Harker, he reveals himself as deeply proud of his boyar heritage and nostalgic for the past, which he admits have become only a memory of heroism, honour and valour in modern times.", - "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg/250px-Bela_Lugosi_as_Dracula%2C_anonymous_photograph_from_1931%2C_Universal_Studios.jpg", - "votes": [ - 224734305581137921 - ] - }, - "goofy": { - "full_name": "Goofy in the Monster's INC World", - "summary": "Pure nightmare fuel.\nThis monster is nothing like its original counterpart. With two different eyes, a pointed nose, fins growing out of its blue skin, and dark spots covering his body, he's a true nightmare come to life.", - "image": "https://www.dailydot.com/wp-content/uploads/3a2/a8/bf38aedbef9f795f.png", - "votes": [] - }, - "refisio": { - "full_name": "Refisio", - "summary": "Who let this guy write this? That's who the real monster is.", - "image": "https://avatars0.githubusercontent.com/u/24819750?s=460&v=4", - "votes": [] - } -} \ No newline at end of file -- cgit v1.2.3 From 42954e96c05ef4d81ac56e6fb59a30ccffa230e5 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 20 Nov 2018 02:19:36 +0100 Subject: It should work now. --- bot/__main__.py | 6 +++--- bot/cogs/hacktober/halloween_facts.py | 2 +- bot/cogs/hacktober/halloweenify.py | 2 +- bot/cogs/hacktober/monstersurvey.py | 6 +++--- bot/resources/halloween/monstersurvey.json | 6 ++++-- 5 files changed, 12 insertions(+), 10 deletions(-) (limited to 'bot/cogs') diff --git a/bot/__main__.py b/bot/__main__.py index b2b2c5fd..b74e4f54 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -17,15 +17,15 @@ else: ghost_unicode = "\N{GHOST}" bot = commands.Bot(command_prefix=commands.when_mentioned_or(".", f"{ghost_unicode} ", ghost_unicode)) -log.info('Start loading extensions from ./bot/cogs/evergreen/') +log.info('Start loading extensions from ./bot/cogs/halloween/') if __name__ == '__main__': # Scan for files in the /cogs/ directory and make a list of the file names. - cogs = [file.stem for file in Path('bot', 'cogs', 'halloween').glob('*.py') if not file.stem.startswith("__")] + cogs = [file.stem for file in Path('bot', 'cogs', 'hacktober').glob('*.py') if not file.stem.startswith("__")] for extension in cogs: try: - bot.load_extension(f'bot.cogs.halloween.{extension}') + bot.load_extension(f'bot.cogs.hacktober.{extension}') log.info(f'Successfully loaded extension: {extension}') except Exception as e: log.error(f'Failed to load extension {extension}: {repr(e)} {format_exc()}') diff --git a/bot/cogs/hacktober/halloween_facts.py b/bot/cogs/hacktober/halloween_facts.py index e97c80d2..304d5d94 100644 --- a/bot/cogs/hacktober/halloween_facts.py +++ b/bot/cogs/hacktober/halloween_facts.py @@ -26,7 +26,7 @@ class HalloweenFacts: def __init__(self, bot): self.bot = bot - with open(Path("./bot/resources", "halloween_facts.json"), "r") as file: + with open(Path("bot", "resources", "halloween", "halloween_facts.json"), "r") as file: self.halloween_facts = json.load(file) self.channel = None self.last_fact = None diff --git a/bot/cogs/hacktober/halloweenify.py b/bot/cogs/hacktober/halloweenify.py index a5fe45ef..9b93ac99 100644 --- a/bot/cogs/hacktober/halloweenify.py +++ b/bot/cogs/hacktober/halloweenify.py @@ -21,7 +21,7 @@ class Halloweenify: """ Change your nickname into a much spookier one! """ - with open(Path('./bot/resources', 'halloweenify.json'), 'r') as f: + with open(Path('bot', 'resources', 'halloween', 'halloweenify.json'), 'r') as f: data = load(f) # Choose a random character from our list we loaded above and set apart the nickname and image url. diff --git a/bot/cogs/hacktober/monstersurvey.py b/bot/cogs/hacktober/monstersurvey.py index 9eafcadc..9f33e31b 100644 --- a/bot/cogs/hacktober/monstersurvey.py +++ b/bot/cogs/hacktober/monstersurvey.py @@ -25,7 +25,7 @@ class MonsterSurvey: def __init__(self, bot: Bot): """Initializes values for the bot to use within the voting commands.""" self.bot = bot - self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'monstersurvey', 'monstersurvey.json') + self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'halloween', 'monstersurvey.json') with open(self.registry_location, 'r') as jason: self.voter_registry = json.load(jason) @@ -91,7 +91,7 @@ class MonsterSurvey: @monster_group.command( name='vote' ) - async def monster_vote(self, ctx: Context, name: Optional[Union[int, str]] = None): + async def monster_vote(self, ctx: Context, name = None): """Casts a vote for a particular monster, or displays a list of monsters that can be voted for if one is not given.""" if name is None: @@ -133,7 +133,7 @@ class MonsterSurvey: @monster_group.command( name='show' ) - async def monster_show(self, ctx: Context, name: Optional[Union[int, str]] = None): + async def monster_show(self, ctx: Context, name = None): """ Shows the named monster. If one is not named, it sends the default voting embed instead. :param ctx: diff --git a/bot/resources/halloween/monstersurvey.json b/bot/resources/halloween/monstersurvey.json index 6c62e2c1..99a3e96f 100644 --- a/bot/resources/halloween/monstersurvey.json +++ b/bot/resources/halloween/monstersurvey.json @@ -23,6 +23,8 @@ "full_name": "Refisio", "summary": "Who let this guy write this? That's who the real monster is.", "image": "https://avatars0.githubusercontent.com/u/24819750?s=460&v=4", - "votes": [] + "votes": [ + 95872159741644800 + ] } -} +} \ No newline at end of file -- cgit v1.2.3